@Override
 protected void setSecondaryRecDescAndComparators(
     CompiledCreateIndexStatement createIndexStmt, AqlMetadataProvider metadata)
     throws AlgebricksException, AsterixException {
   List<String> secondaryKeyFields = createIndexStmt.getKeyFields();
   int numSecondaryKeys = secondaryKeyFields.size();
   if (numSecondaryKeys != 1) {
     throw new AsterixException(
         "Cannot use "
             + numSecondaryKeys
             + " fields as a key for the R-tree index. There can be only one field as a key for the R-tree index.");
   }
   Pair<IAType, Boolean> spatialTypePair =
       Index.getNonNullableKeyFieldType(secondaryKeyFields.get(0), itemType);
   IAType spatialType = spatialTypePair.first;
   anySecondaryKeyIsNullable = spatialTypePair.second;
   if (spatialType == null) {
     throw new AsterixException(
         "Could not find field " + secondaryKeyFields.get(0) + " in the schema.");
   }
   int numDimensions = NonTaggedFormatUtil.getNumDimensions(spatialType.getTypeTag());
   numNestedSecondaryKeyFields = numDimensions * 2;
   secondaryFieldAccessEvalFactories =
       metadata
           .getFormat()
           .createMBRFactory(itemType, secondaryKeyFields.get(0), numPrimaryKeys, numDimensions);
   secondaryComparatorFactories = new IBinaryComparatorFactory[numNestedSecondaryKeyFields];
   valueProviderFactories = new IPrimitiveValueProviderFactory[numNestedSecondaryKeyFields];
   ISerializerDeserializer[] secondaryRecFields =
       new ISerializerDeserializer[numPrimaryKeys + numNestedSecondaryKeyFields];
   ITypeTraits[] secondaryTypeTraits =
       new ITypeTraits[numNestedSecondaryKeyFields + numPrimaryKeys];
   IAType nestedKeyType = NonTaggedFormatUtil.getNestedSpatialType(spatialType.getTypeTag());
   keyType = nestedKeyType.getTypeTag();
   for (int i = 0; i < numNestedSecondaryKeyFields; i++) {
     ISerializerDeserializer keySerde =
         AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(nestedKeyType);
     secondaryRecFields[i] = keySerde;
     secondaryComparatorFactories[i] =
         AqlBinaryComparatorFactoryProvider.INSTANCE.getBinaryComparatorFactory(
             nestedKeyType, true);
     secondaryTypeTraits[i] = AqlTypeTraitProvider.INSTANCE.getTypeTrait(nestedKeyType);
     valueProviderFactories[i] = AqlPrimitiveValueProviderFactory.INSTANCE;
   }
   // Add serializers and comparators for primary index fields.
   for (int i = 0; i < numPrimaryKeys; i++) {
     secondaryRecFields[numNestedSecondaryKeyFields + i] = primaryRecDesc.getFields()[i];
     secondaryTypeTraits[numNestedSecondaryKeyFields + i] = primaryRecDesc.getTypeTraits()[i];
   }
   secondaryRecDesc = new RecordDescriptor(secondaryRecFields, secondaryTypeTraits);
 }
 public IAType getClosedFieldType(ARecordType recordType, int fieldId) {
   IAType aType = recordType.getFieldTypes()[fieldId];
   if (NonTaggedFormatUtil.isOptional(aType)) {
     // optional field: add the embedded non-null type tag
     aType = ((AUnionType) aType).getNullableType();
   }
   return aType;
 }
 public int getClosedFieldSize(ARecordType recordType, int fieldId) throws AsterixException {
   if (isClosedFieldNull(recordType, fieldId)) {
     return 0;
   }
   return NonTaggedFormatUtil.getFieldValueLength(
       bytes,
       getClosedFieldOffset(recordType, fieldId),
       getClosedFieldType(recordType, fieldId).getTypeTag(),
       false);
 }
  @Override
  public void set(byte[] b, int s, int len) {
    reset();
    super.set(b, s, len);

    int numberOfitems = AInt32SerializerDeserializer.getInt(b, s + 6);
    int itemOffset;
    if (typedItemList) {
      switch (itemTag) {
        case STRING:
        case BINARY:
        case RECORD:
        case ORDEREDLIST:
        case UNORDEREDLIST:
        case ANY:
          itemOffset = s + 10 + (numberOfitems * 4);
          break;
        default:
          itemOffset = s + 10;
      }
    } else {
      itemOffset = s + 10 + (numberOfitems * 4);
    }
    int itemLength = 0;
    try {
      if (typedItemList) {
        for (int i = 0; i < numberOfitems; i++) {
          itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, false);
          IVisitablePointable tag = allocator.allocateEmpty();
          IVisitablePointable item = allocator.allocateFieldValue(itemType);

          // set item type tag
          int start = dataBos.size();
          dataDos.writeByte(itemTag.serialize());
          int end = dataBos.size();
          tag.set(dataBos.getByteArray(), start, end - start);
          itemTags.add(tag);

          // set item value
          start = dataBos.size();
          dataDos.writeByte(itemTag.serialize());
          dataDos.write(b, itemOffset, itemLength);
          end = dataBos.size();
          item.set(dataBos.getByteArray(), start, end - start);
          itemOffset += itemLength;
          items.add(item);
        }
      } else {
        for (int i = 0; i < numberOfitems; i++) {
          itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[itemOffset]);
          itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, true) + 1;
          IVisitablePointable tag = allocator.allocateEmpty();
          IVisitablePointable item = allocator.allocateFieldValue(itemTag, b, itemOffset + 1);

          // set item type tag
          int start = dataBos.size();
          dataDos.writeByte(itemTag.serialize());
          int end = dataBos.size();
          tag.set(dataBos.getByteArray(), start, end - start);
          itemTags.add(tag);

          // open part field already include the type tag
          item.set(b, itemOffset, itemLength);
          itemOffset += itemLength;
          items.add(item);
        }
      }
    } catch (Exception e) {
      throw new IllegalStateException(e);
    }
  }
  @Override
  public IPrinterFactory getPrinterFactory(Object type) throws AlgebricksException {
    IAType aqlType = (IAType) type;

    if (aqlType != null) {
      switch (aqlType.getTypeTag()) {
          // case ANYTYPE:
          // return AAnyTypePrinterFactory.INSTANCE;
        case INT8:
          return AInt8PrinterFactory.INSTANCE;
        case INT16:
          return AInt16PrinterFactory.INSTANCE;
        case INT32:
          return AInt32PrinterFactory.INSTANCE;
        case INT64:
          return AInt64PrinterFactory.INSTANCE;
        case NULL:
          return ANullPrinterFactory.INSTANCE;
        case BOOLEAN:
          return ABooleanPrinterFactory.INSTANCE;
        case FLOAT:
          return AFloatPrinterFactory.INSTANCE;
        case DOUBLE:
          return ADoublePrinterFactory.INSTANCE;
        case TIME:
          return ATimePrinterFactory.INSTANCE;
        case DATE:
          return ADatePrinterFactory.INSTANCE;
        case DATETIME:
          return ADateTimePrinterFactory.INSTANCE;
        case DURATION:
          return ADurationPrinterFactory.INSTANCE;
        case POINT:
          return APointPrinterFactory.INSTANCE;
        case POINT3D:
          return APoint3DPrinterFactory.INSTANCE;
        case LINE:
          return ALinePrinterFactory.INSTANCE;
        case POLYGON:
          return APolygonPrinterFactory.INSTANCE;
        case CIRCLE:
          return ACirclePrinterFactory.INSTANCE;
        case RECTANGLE:
          return ARectanglePrinterFactory.INSTANCE;
        case STRING:
          return AStringPrinterFactory.INSTANCE;
        case RECORD:
          return new ARecordPrinterFactory((ARecordType) aqlType);
        case ORDEREDLIST:
          return new AOrderedlistPrinterFactory((AOrderedListType) aqlType);
        case UNORDEREDLIST:
          return new AUnorderedlistPrinterFactory((AUnorderedListType) aqlType);
        case UNION:
          {
            if (NonTaggedFormatUtil.isOptionalField((AUnionType) aqlType))
              return new ANullableFieldPrinterFactory((AUnionType) aqlType);
            else return new AUnionPrinterFactory((AUnionType) aqlType);
          }
      }
    }
    return AObjectPrinterFactory.INSTANCE;
  }
 public int getOpenFieldValueSize(ARecordType recordType, int fieldId) throws AsterixException {
   int offset = getOpenFieldValueOffset(recordType, fieldId);
   ATypeTag tag =
       EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(getOpenFieldTag(recordType, fieldId));
   return NonTaggedFormatUtil.getFieldValueLength(bytes, offset, tag, true);
 }