use of org.apache.asterix.om.pointables.base.IVisitablePointable in project asterixdb by apache.
the class ARecordCaster method loadRequiredType.
private void loadRequiredType(ARecordType reqType) throws IOException {
reqFieldNames.clear();
reqFieldTypeTags.clear();
allocator.reset();
cachedReqType = reqType;
int numSchemaFields = reqType.getFieldTypes().length;
IAType[] fieldTypes = reqType.getFieldTypes();
String[] fieldNames = reqType.getFieldNames();
fieldPermutation = new int[numSchemaFields];
optionalFields = new boolean[numSchemaFields];
for (int i = 0; i < optionalFields.length; i++) {
optionalFields[i] = false;
}
bos.reset(nullTypeTag.getStartOffset() + nullTypeTag.getLength());
for (int i = 0; i < numSchemaFields; i++) {
ATypeTag ftypeTag = fieldTypes[i].getTypeTag();
String fname = fieldNames[i];
// add type tag pointable
if (NonTaggedFormatUtil.isOptional(fieldTypes[i])) {
// optional field: add the embedded non-null type tag
ftypeTag = ((AUnionType) fieldTypes[i]).getActualType().getTypeTag();
optionalFields[i] = true;
}
int tagStart = bos.size();
dos.writeByte(ftypeTag.serialize());
int tagEnd = bos.size();
IVisitablePointable typeTagPointable = allocator.allocateEmpty();
typeTagPointable.set(bos.getByteArray(), tagStart, tagEnd - tagStart);
reqFieldTypeTags.add(typeTagPointable);
// add type name pointable (including a string type tag)
int nameStart = bos.size();
dos.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
utf8Writer.writeUTF8(fname, dos);
int nameEnd = bos.size();
IVisitablePointable typeNamePointable = allocator.allocateEmpty();
typeNamePointable.set(bos.getByteArray(), nameStart, nameEnd - nameStart);
reqFieldNames.add(typeNamePointable);
}
reqFieldNamesSortedIndex = new int[reqFieldNames.size()];
for (int i = 0; i < reqFieldNamesSortedIndex.length; i++) {
reqFieldNamesSortedIndex[i] = i;
}
// sort the field name index
quickSort(reqFieldNamesSortedIndex, reqFieldNames, 0, reqFieldNamesSortedIndex.length - 1);
}
use of org.apache.asterix.om.pointables.base.IVisitablePointable in project asterixdb by apache.
the class ARecordCaster method matchClosedPart.
private void matchClosedPart(List<IVisitablePointable> fieldNames, List<IVisitablePointable> fieldTypeTags) throws HyracksDataException {
// sort-merge based match
quickSort(fieldNamesSortedIndex, fieldNames, 0, numInputFields - 1);
int fnStart = 0;
int reqFnStart = 0;
while (fnStart < numInputFields && reqFnStart < reqFieldNames.size()) {
int fnPos = fieldNamesSortedIndex[fnStart];
int reqFnPos = reqFieldNamesSortedIndex[reqFnStart];
int c = compare(fieldNames.get(fnPos), reqFieldNames.get(reqFnPos));
if (c == 0) {
IVisitablePointable fieldTypeTag = fieldTypeTags.get(fnPos);
IVisitablePointable reqFieldTypeTag = reqFieldTypeTags.get(reqFnPos);
if (fieldTypeTag.equals(reqFieldTypeTag) || (// match the null type of optional field
optionalFields[reqFnPos] && (fieldTypeTag.equals(nullTypeTag)) || fieldTypeTag.equals(missingTypeTag))) {
fieldPermutation[reqFnPos] = fnPos;
openFields[fnPos] = false;
} else {
// if mismatch, check whether input type can be promoted to the required type
ATypeTag inputTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(fieldTypeTag.getByteArray()[fieldTypeTag.getStartOffset()]);
ATypeTag requiredTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(reqFieldTypeTag.getByteArray()[reqFieldTypeTag.getStartOffset()]);
if (ATypeHierarchy.canPromote(inputTypeTag, requiredTypeTag) || ATypeHierarchy.canDemote(inputTypeTag, requiredTypeTag)) {
fieldPermutation[reqFnPos] = fnPos;
openFields[fnPos] = false;
} else {
throw new HyracksDataException(ErrorCode.ASTERIX, ErrorCode.CASTING_FIELD, "Field type %1$s can't be promoted to type %2$s", inputTypeTag, requiredTypeTag);
}
}
fnStart++;
reqFnStart++;
}
if (c > 0) {
reqFnStart++;
}
if (c < 0) {
fnStart++;
}
}
// check unmatched fields in the input type
for (int i = 0; i < openFields.length; i++) {
if (openFields[i] && !cachedReqType.isOpen()) {
//print the field name
IVisitablePointable fieldName = fieldNames.get(i);
ByteArrayOutputStream fieldBos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(fieldBos);
APrintVisitor printVisitor = new APrintVisitor();
Pair<PrintStream, ATypeTag> visitorArg = new Pair<>(ps, ATypeTag.STRING);
fieldName.accept(printVisitor, visitorArg);
//print the colon
ps.print(":");
//print the field type
IVisitablePointable fieldType = fieldTypeTags.get(i);
ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(fieldType.getByteArray()[fieldType.getStartOffset()]);
ps.print(typeTag);
//collect the output message and throw the exception
throw new HyracksDataException("type mismatch: including an extra field " + fieldBos.toString());
}
}
// check unmatched fields in the required type
for (int i = 0; i < fieldPermutation.length; i++) {
if (fieldPermutation[i] < 0) {
IAType t = cachedReqType.getFieldTypes()[i];
if (!NonTaggedFormatUtil.isOptional(t)) {
// no matched field in the input for a required closed field
throw new HyracksDataException("type mismatch: missing a required closed field " + cachedReqType.getFieldNames()[i] + ": " + t.getTypeName());
}
}
}
}
use of org.apache.asterix.om.pointables.base.IVisitablePointable in project asterixdb by apache.
the class ARecordCaster method writeOutput.
private void writeOutput(List<IVisitablePointable> fieldNames, List<IVisitablePointable> fieldTypeTags, List<IVisitablePointable> fieldValues, DataOutput output, ACastVisitor visitor) throws HyracksDataException {
// reset the states of the record builder
recBuilder.reset(cachedReqType);
recBuilder.init();
// write the closed part
for (int i = 0; i < fieldPermutation.length; i++) {
final int pos = fieldPermutation[i];
final IVisitablePointable field = pos >= 0 ? fieldValues.get(pos) : missingTypeTag;
final IAType fType = cachedReqType.getFieldTypes()[i];
nestedVisitorArg.second = fType;
// as flat
if (optionalFields[i]) {
//the field is optional in the input record
IVisitablePointable fieldTypeTag = pos >= 0 ? fieldTypeTags.get(pos) : null;
if (fieldTypeTag == null || fieldTypeTag.equals(missingTypeTag)) {
nestedVisitorArg.second = BuiltinType.AMISSING;
} else if (fieldTypeTag.equals(nullTypeTag)) {
nestedVisitorArg.second = BuiltinType.ANULL;
} else {
nestedVisitorArg.second = ((AUnionType) fType).getActualType();
}
}
field.accept(visitor, nestedVisitorArg);
recBuilder.addField(i, nestedVisitorArg.first);
}
// write the open part
for (int i = 0; i < numInputFields; i++) {
if (openFields[i]) {
IVisitablePointable name = fieldNames.get(i);
IVisitablePointable field = fieldValues.get(i);
IVisitablePointable fieldTypeTag = fieldTypeTags.get(i);
ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(fieldTypeTag.getByteArray()[fieldTypeTag.getStartOffset()]);
nestedVisitorArg.second = DefaultOpenFieldType.getDefaultOpenFieldType(typeTag);
field.accept(visitor, nestedVisitorArg);
recBuilder.addField(name, nestedVisitorArg.first);
}
}
recBuilder.write(output, true);
}
use of org.apache.asterix.om.pointables.base.IVisitablePointable in project asterixdb by apache.
the class AListPrinter method printItem.
private void printItem(IPrintVisitor visitor, List<IVisitablePointable> itemTags, List<IVisitablePointable> items, int i) throws HyracksDataException {
IVisitablePointable itemTypeTag = itemTags.get(i);
IVisitablePointable item = items.get(i);
ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getByteArray()[itemTypeTag.getStartOffset()]);
itemVisitorArg.second = item.getLength() <= 1 ? ATypeTag.NULL : typeTag;
item.accept(visitor, itemVisitorArg);
}
use of org.apache.asterix.om.pointables.base.IVisitablePointable in project asterixdb by apache.
the class ARecordPrinter method printRecord.
public void printRecord(ARecordVisitablePointable recordAccessor, PrintStream ps, IPrintVisitor visitor) throws HyracksDataException {
final List<IVisitablePointable> fieldNames = recordAccessor.getFieldNames();
final List<IVisitablePointable> fieldValues = recordAccessor.getFieldValues();
nameVisitorArg.first = ps;
itemVisitorArg.first = ps;
ps.print(startRecord);
final int size = fieldNames.size();
boolean first = true;
for (int i = 0; i < size; ++i) {
final IVisitablePointable fieldName = fieldNames.get(i);
final IVisitablePointable fieldValue = fieldValues.get(i);
final ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(fieldValue.getByteArray()[fieldValue.getStartOffset()]);
// Prints the current field.
if (typeTag != ATypeTag.MISSING) {
if (first) {
//Skip printing field separator for the first field.
first = false;
} else {
ps.print(fieldSeparator);
}
printField(ps, visitor, fieldName, fieldValue, typeTag);
}
}
ps.print(endRecord);
}
Aggregations