use of org.apache.asterix.om.types.AUnionType in project asterixdb by apache.
the class FieldAccessNestedEvalFactory method createScalarEvaluator.
@Override
public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
return new IScalarEvaluator() {
private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
private final DataOutput out = resultStorage.getDataOutput();
private final ByteArrayAccessibleOutputStream subRecordTmpStream = new ByteArrayAccessibleOutputStream();
private final IPointable inputArg0 = new VoidPointable();
private final IScalarEvaluator eval0 = recordEvalFactory.createScalarEvaluator(ctx);
private final IPointable[] fieldPointables = new VoidPointable[fieldPath.size()];
private final RuntimeRecordTypeInfo[] recTypeInfos = new RuntimeRecordTypeInfo[fieldPath.size()];
@SuppressWarnings("unchecked")
private final ISerializerDeserializer<ANull> nullSerde = SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ANULL);
@SuppressWarnings("unchecked")
private final ISerializerDeserializer<AMissing> missingSerde = SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AMISSING);
{
generateFieldsPointables();
for (int index = 0; index < fieldPath.size(); ++index) {
recTypeInfos[index] = new RuntimeRecordTypeInfo();
}
}
@SuppressWarnings("unchecked")
private void generateFieldsPointables() throws HyracksDataException {
for (int i = 0; i < fieldPath.size(); i++) {
ArrayBackedValueStorage storage = new ArrayBackedValueStorage();
DataOutput out = storage.getDataOutput();
AString as = new AString(fieldPath.get(i));
SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(as.getType()).serialize(as, out);
fieldPointables[i] = new VoidPointable();
fieldPointables[i].set(storage);
}
}
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
try {
resultStorage.reset();
eval0.evaluate(tuple, inputArg0);
byte[] serRecord = inputArg0.getByteArray();
int offset = inputArg0.getStartOffset();
int start = offset;
int len = inputArg0.getLength();
if (serRecord[start] != ATypeTag.SERIALIZED_RECORD_TYPE_TAG) {
throw new TypeMismatchException(BuiltinFunctions.FIELD_ACCESS_NESTED, 0, serRecord[start], ATypeTag.SERIALIZED_RECORD_TYPE_TAG);
}
int subFieldIndex = -1;
int subFieldOffset = -1;
int subFieldLength = -1;
int nullBitmapSize = -1;
IAType subType = recordType;
recTypeInfos[0].reset(recordType);
ATypeTag subTypeTag = ATypeTag.MISSING;
boolean openField = false;
int pathIndex = 0;
// Moving through closed fields first.
for (; pathIndex < fieldPointables.length; pathIndex++) {
if (subType.getTypeTag().equals(ATypeTag.UNION)) {
//enforced SubType
subType = ((AUnionType) subType).getActualType();
byte serializedTypeTag = subType.getTypeTag().serialize();
if (serializedTypeTag != ATypeTag.SERIALIZED_RECORD_TYPE_TAG) {
throw new UnsupportedTypeException(BuiltinFunctions.FIELD_ACCESS_NESTED.getName(), serializedTypeTag);
}
if (subType.getTypeTag() == ATypeTag.OBJECT) {
recTypeInfos[pathIndex].reset((ARecordType) subType);
}
}
subFieldIndex = recTypeInfos[pathIndex].getFieldIndex(fieldPointables[pathIndex].getByteArray(), fieldPointables[pathIndex].getStartOffset() + 1, fieldPointables[pathIndex].getLength() - 1);
if (subFieldIndex == -1) {
break;
}
nullBitmapSize = RecordUtil.computeNullBitmapSize((ARecordType) subType);
subFieldOffset = ARecordSerializerDeserializer.getFieldOffsetById(serRecord, start, subFieldIndex, nullBitmapSize, ((ARecordType) subType).isOpen());
if (subFieldOffset == 0) {
// the field is null, we checked the null bit map
// any path after null will return null.
nullSerde.serialize(ANull.NULL, out);
result.set(resultStorage);
return;
}
if (subFieldOffset < 0) {
// the field is missing, we checked the missing bit map
// any path after missing will return null.
missingSerde.serialize(AMissing.MISSING, out);
result.set(resultStorage);
return;
}
subType = ((ARecordType) subType).getFieldTypes()[subFieldIndex];
if (subType.getTypeTag() == ATypeTag.OBJECT && pathIndex + 1 < fieldPointables.length) {
// Move to the next Depth
recTypeInfos[pathIndex + 1].reset((ARecordType) subType);
}
if (subType.getTypeTag().equals(ATypeTag.UNION)) {
subTypeTag = ((AUnionType) subType).getActualType().getTypeTag();
subFieldLength = NonTaggedFormatUtil.getFieldValueLength(serRecord, subFieldOffset, subTypeTag, false);
} else {
subTypeTag = subType.getTypeTag();
subFieldLength = NonTaggedFormatUtil.getFieldValueLength(serRecord, subFieldOffset, subTypeTag, false);
}
if (pathIndex < fieldPointables.length - 1) {
//setup next iteration
subRecordTmpStream.reset();
subRecordTmpStream.write(subTypeTag.serialize());
subRecordTmpStream.write(serRecord, subFieldOffset, subFieldLength);
serRecord = subRecordTmpStream.getByteArray();
start = 0;
}
// type check
if (pathIndex < fieldPointables.length - 1 && serRecord[start] != ATypeTag.SERIALIZED_RECORD_TYPE_TAG) {
throw new UnsupportedTypeException(BuiltinFunctions.FIELD_ACCESS_NESTED, serRecord[start]);
}
}
// Moving through open fields after we hit the first open field.
for (; pathIndex < fieldPointables.length; pathIndex++) {
openField = true;
subFieldOffset = ARecordSerializerDeserializer.getFieldOffsetByName(serRecord, start, len, fieldPointables[pathIndex].getByteArray(), fieldPointables[pathIndex].getStartOffset());
if (subFieldOffset < 0) {
out.writeByte(ATypeTag.SERIALIZED_MISSING_TYPE_TAG);
result.set(resultStorage);
return;
}
subTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serRecord[subFieldOffset]);
subFieldLength = NonTaggedFormatUtil.getFieldValueLength(serRecord, subFieldOffset, subTypeTag, true) + 1;
if (pathIndex >= fieldPointables.length - 1) {
continue;
}
//setup next iteration
start = subFieldOffset;
len = subFieldLength;
// type check
if (serRecord[start] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
missingSerde.serialize(AMissing.MISSING, out);
result.set(resultStorage);
return;
}
if (serRecord[start] != ATypeTag.SERIALIZED_RECORD_TYPE_TAG) {
throw new UnsupportedTypeException(BuiltinFunctions.FIELD_ACCESS_NESTED.getName(), serRecord[start]);
}
}
// emit the final result.
if (openField) {
result.set(serRecord, subFieldOffset, subFieldLength);
} else {
out.writeByte(subTypeTag.serialize());
out.write(serRecord, subFieldOffset, subFieldLength);
result.set(resultStorage);
}
} catch (IOException | AsterixException e) {
throw new HyracksDataException(e);
}
}
};
}
use of org.apache.asterix.om.types.AUnionType in project asterixdb by apache.
the class TweetParser method writeField.
private boolean writeField(JsonNode fieldObj, IAType originalFieldType, DataOutput out) throws IOException {
boolean writeResult = true;
IAType fieldType = originalFieldType;
if (originalFieldType instanceof AUnionType) {
fieldType = ((AUnionType) originalFieldType).getActualType();
}
if (fieldType != null) {
switch(fieldType.getTypeTag()) {
case STRING:
out.write(BuiltinType.ASTRING.getTypeTag().serialize());
utf8Writer.writeUTF8(fieldObj.asText(), out);
break;
case BIGINT:
aInt64.setValue(fieldObj.asLong());
int64Serde.serialize(aInt64, out);
break;
case INTEGER:
out.write(BuiltinType.AINT32.getTypeTag().serialize());
out.writeInt(fieldObj.asInt());
break;
case DOUBLE:
out.write(BuiltinType.ADOUBLE.getTypeTag().serialize());
out.writeDouble(fieldObj.asDouble());
break;
case BOOLEAN:
out.write(BuiltinType.ABOOLEAN.getTypeTag().serialize());
out.writeBoolean(fieldObj.asBoolean());
break;
case OBJECT:
writeRecord(fieldObj, out, (ARecordType) fieldType);
break;
case ARRAY:
parseArrayList(fieldObj, out);
break;
default:
writeResult = false;
}
} else {
if (fieldObj.isNull()) {
nullSerde.serialize(ANull.NULL, out);
} else if (fieldObj.isInt()) {
out.write(BuiltinType.AINT32.getTypeTag().serialize());
out.writeInt(fieldObj.asInt());
} else if (fieldObj.isBoolean()) {
out.write(BuiltinType.ABOOLEAN.getTypeTag().serialize());
out.writeBoolean(fieldObj.asBoolean());
} else if (fieldObj.isDouble()) {
out.write(BuiltinType.ADOUBLE.getTypeTag().serialize());
out.writeDouble(fieldObj.asDouble());
} else if (fieldObj.isLong()) {
out.write(BuiltinType.AINT64.getTypeTag().serialize());
out.writeLong(fieldObj.asLong());
} else if (fieldObj.isTextual()) {
out.write(BuiltinType.ASTRING.getTypeTag().serialize());
utf8Writer.writeUTF8(fieldObj.asText(), out);
} else if (fieldObj.isArray()) {
if ((fieldObj).size() != 0) {
parseArrayList(fieldObj, out);
} else {
writeResult = false;
}
} else if (fieldObj.isObject()) {
if ((fieldObj).size() != 0) {
writeRecord(fieldObj, out, null);
} else {
writeResult = false;
}
}
}
return writeResult;
}
Aggregations