Search in sources :

Example 1 with ITypeConvertComputer

use of org.apache.asterix.om.types.hierachy.ITypeConvertComputer in project asterixdb by apache.

the class AObjectAscBinaryComparatorFactory method createBinaryComparator.

@Override
public IBinaryComparator createBinaryComparator() {
    return new ABinaryComparator() {

        // a storage to promote a value
        private ArrayBackedValueStorage castBuffer = new ArrayBackedValueStorage();

        private ITypeConvertComputer promoteComputer;

        // BOOLEAN
        final IBinaryComparator ascBoolComp = BooleanBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // TINYINT
        final IBinaryComparator ascByteComp = new PointableBinaryComparatorFactory(BytePointable.FACTORY).createBinaryComparator();

        // SMALLINT
        final IBinaryComparator ascShortComp = new PointableBinaryComparatorFactory(ShortPointable.FACTORY).createBinaryComparator();

        // INTEGER
        final IBinaryComparator ascIntComp = new PointableBinaryComparatorFactory(IntegerPointable.FACTORY).createBinaryComparator();

        // BIGINT
        final IBinaryComparator ascLongComp = LongBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // STRING
        final IBinaryComparator ascStrComp = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY).createBinaryComparator();

        // BINARY
        final IBinaryComparator ascByteArrayComp = new PointableBinaryComparatorFactory(ByteArrayPointable.FACTORY).createBinaryComparator();

        // FLOAT
        final IBinaryComparator ascFloatComp = new PointableBinaryComparatorFactory(FloatPointable.FACTORY).createBinaryComparator();

        // DOUBLE
        final IBinaryComparator ascDoubleComp = new PointableBinaryComparatorFactory(DoublePointable.FACTORY).createBinaryComparator();

        // RECTANGLE
        final IBinaryComparator ascRectangleComp = ARectanglePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // CIRCLE
        final IBinaryComparator ascCircleComp = ACirclePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // DURATION
        final IBinaryComparator ascDurationComp = ADurationPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // INTERVAL
        final IBinaryComparator ascIntervalComp = AIntervalAscPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // LINE
        final IBinaryComparator ascLineComp = ALinePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // POINT
        final IBinaryComparator ascPointComp = APointPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // POINT3D
        final IBinaryComparator ascPoint3DComp = APoint3DPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // POLYGON
        final IBinaryComparator ascPolygonComp = APolygonPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // UUID
        final IBinaryComparator ascUUIDComp = AUUIDPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // RAW
        final IBinaryComparator rawComp = RawBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        @Override
        public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) throws HyracksDataException {
            // Therefore, inside this method, we return an order between two values even if one value is MISSING.
            if (b1[s1] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
                return b2[s2] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG ? 0 : -1;
            } else {
                if (b2[s2] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
                    return 1;
                }
            }
            // Therefore, inside this method, we return an order between two values even if one value is NULL.
            if (b1[s1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                return b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG ? 0 : -1;
            } else {
                if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                    return 1;
                }
            }
            ATypeTag tag1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b1[s1]);
            ATypeTag tag2 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b2[s2]);
            // And, we don't need to continue. We just compare raw byte by byte.
            if (tag1 == null || tag2 == null) {
                return rawComp.compare(b1, s1, l1, b2, s2, l2);
            }
            // If two type does not match, we identify the source and the target and
            // promote the source to the target type if they are compatible.
            ATypeTag sourceTypeTag = null;
            ATypeTag targetTypeTag = null;
            boolean areTwoTagsEqual = false;
            boolean typePromotionApplied = false;
            boolean leftValueChanged = false;
            if (tag1 != tag2) {
                // tag1 can be promoted to tag2 (e.g. tag1: SMALLINT, tag2: INTEGER)
                if (ATypeHierarchy.canPromote(tag1, tag2)) {
                    sourceTypeTag = tag1;
                    targetTypeTag = tag2;
                    typePromotionApplied = true;
                    leftValueChanged = true;
                // or tag2 can be promoted to tag1 (e.g. tag2: INTEGER, tag1: DOUBLE)
                } else if (ATypeHierarchy.canPromote(tag2, tag1)) {
                    sourceTypeTag = tag2;
                    targetTypeTag = tag1;
                    typePromotionApplied = true;
                }
                // we promote the source to the target by using a promoteComputer
                if (typePromotionApplied) {
                    castBuffer.reset();
                    promoteComputer = ATypeHierarchy.getTypePromoteComputer(sourceTypeTag, targetTypeTag);
                    if (promoteComputer != null) {
                        try {
                            if (leftValueChanged) {
                                // left side is the source
                                promoteComputer.convertType(b1, s1 + 1, l1 - 1, castBuffer.getDataOutput());
                            } else {
                                // right side is the source
                                promoteComputer.convertType(b2, s2 + 1, l2 - 1, castBuffer.getDataOutput());
                            }
                        } catch (IOException e) {
                            throw new HyracksDataException("ComparatorFactory - failed to promote the type:" + sourceTypeTag + " to the type:" + targetTypeTag);
                        }
                    } else {
                        // No appropriate typePromoteComputer.
                        throw new HyracksDataException("No appropriate typePromoteComputer exists for " + sourceTypeTag + " to the " + targetTypeTag + " type. Please check the code.");
                    }
                }
            } else {
                // tag1 == tag2.
                sourceTypeTag = tag1;
                targetTypeTag = tag1;
                areTwoTagsEqual = true;
            }
            // This is especially useful when we need to generate some order between any two types.
            if ((!areTwoTagsEqual && !typePromotionApplied)) {
                return rawComp.compare(b1, s1, l1, b2, s2, l2);
            }
            // Conduct actual compare()
            switch(targetTypeTag) {
                case UUID:
                    return ascUUIDComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                case BOOLEAN:
                    {
                        return ascBoolComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case TINYINT:
                    {
                        // No type promotion from another type to the TINYINT can happen
                        return ascByteComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case SMALLINT:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascShortComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascShortComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascShortComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case TIME:
                case DATE:
                case YEARMONTHDURATION:
                case INTEGER:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascIntComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascIntComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascIntComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case DATETIME:
                case DAYTIMEDURATION:
                case BIGINT:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascLongComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascLongComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascLongComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case FLOAT:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascFloatComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascFloatComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascFloatComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case DOUBLE:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascDoubleComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascDoubleComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascDoubleComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case STRING:
                    {
                        return ascStrComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case RECTANGLE:
                    {
                        return ascRectangleComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case CIRCLE:
                    {
                        return ascCircleComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case POINT:
                    {
                        return ascPointComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case POINT3D:
                    {
                        return ascPoint3DComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case LINE:
                    {
                        return ascLineComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case POLYGON:
                    {
                        return ascPolygonComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case DURATION:
                    {
                        return ascDurationComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case INTERVAL:
                    {
                        return ascIntervalComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case BINARY:
                    {
                        return ascByteArrayComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                default:
                    {
                        // We include typeTag in comparison to compare between two type to enforce some ordering
                        return rawComp.compare(b1, s1, l1, b2, s2, l2);
                    }
            }
        }
    };
}
Also used : ITypeConvertComputer(org.apache.asterix.om.types.hierachy.ITypeConvertComputer) PointableBinaryComparatorFactory(org.apache.hyracks.data.std.accessors.PointableBinaryComparatorFactory) ArrayBackedValueStorage(org.apache.hyracks.data.std.util.ArrayBackedValueStorage) ATypeTag(org.apache.asterix.om.types.ATypeTag) IBinaryComparator(org.apache.hyracks.api.dataflow.value.IBinaryComparator) IOException(java.io.IOException) HyracksDataException(org.apache.hyracks.api.exceptions.HyracksDataException)

Example 2 with ITypeConvertComputer

use of org.apache.asterix.om.types.hierachy.ITypeConvertComputer in project asterixdb by apache.

the class ADMDataParser method parseConstructor.

private void parseConstructor(ATypeTag typeTag, IAType objectType, DataOutput out) throws IOException {
    ATypeTag targetTypeTag = getTargetTypeTag(typeTag, objectType);
    if (targetTypeTag != null) {
        DataOutput dataOutput = out;
        if (targetTypeTag != typeTag) {
            castBuffer.reset();
            dataOutput = castBuffer.getDataOutput();
        }
        int token = admLexer.next();
        if (token == AdmLexer.TOKEN_CONSTRUCTOR_OPEN) {
            token = admLexer.next();
            if (token == AdmLexer.TOKEN_STRING_LITERAL) {
                String unquoted = admLexer.getLastTokenImage().substring(1, admLexer.getLastTokenImage().length() - 1);
                if (!parseValue(unquoted, typeTag, dataOutput)) {
                    throw new ParseException(ErrorCode.PARSER_ADM_DATA_PARSER_CONSTRUCTOR_MISSING_DESERIALIZER, AdmLexer.tokenKindToString(token));
                }
                token = admLexer.next();
                if (token == AdmLexer.TOKEN_CONSTRUCTOR_CLOSE) {
                    if (targetTypeTag != typeTag) {
                        ITypeConvertComputer promoteComputer = ATypeHierarchy.getTypePromoteComputer(typeTag, targetTypeTag);
                        // the availability of a target type
                        assert promoteComputer != null;
                        // do the promotion; note that the type tag field should be skipped
                        promoteComputer.convertType(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, out);
                    }
                    return;
                }
            }
        }
    }
    throw new ParseException(ErrorCode.PARSER_ADM_DATA_PARSER_TYPE_MISMATCH, objectType.getTypeName() + " got " + typeTag);
}
Also used : ITypeConvertComputer(org.apache.asterix.om.types.hierachy.ITypeConvertComputer) DataOutput(java.io.DataOutput) ATypeTag(org.apache.asterix.om.types.ATypeTag)

Example 3 with ITypeConvertComputer

use of org.apache.asterix.om.types.hierachy.ITypeConvertComputer in project asterixdb by apache.

the class ADMDataParser method parseAndCastNumeric.

private void parseAndCastNumeric(ATypeTag typeTag, IAType objectType, DataOutput out) throws IOException {
    ATypeTag targetTypeTag = getTargetTypeTag(typeTag, objectType);
    DataOutput dataOutput = out;
    if (targetTypeTag != typeTag) {
        castBuffer.reset();
        dataOutput = castBuffer.getDataOutput();
    }
    if ((targetTypeTag == null) || !parseValue(admLexer.getLastTokenImage(), typeTag, dataOutput)) {
        throw new ParseException(mismatchErrorMessage + objectType.getTypeName() + mismatchErrorMessage2 + typeTag);
    }
    // target type
    if (targetTypeTag != typeTag) {
        if (ATypeHierarchy.canPromote(typeTag, targetTypeTag)) {
            // can promote typeTag to targetTypeTag
            ITypeConvertComputer promoteComputer = ATypeHierarchy.getTypePromoteComputer(typeTag, targetTypeTag);
            if (promoteComputer == null) {
                throw new ParseException(ErrorCode.PARSER_ADM_DATA_PARSER_CAST_ERROR, typeTag, targetTypeTag);
            }
            // do the promotion; note that the type tag field should be skipped
            promoteComputer.convertType(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, out);
        } else if (ATypeHierarchy.canDemote(typeTag, targetTypeTag)) {
            // can demote source type to the target type
            ITypeConvertComputer demoteComputer = ATypeHierarchy.getTypeDemoteComputer(typeTag, targetTypeTag, true);
            if (demoteComputer == null) {
                throw new ParseException(ErrorCode.PARSER_ADM_DATA_PARSER_CAST_ERROR, typeTag, targetTypeTag);
            }
            // do the demotion; note that the type tag field should be skipped
            demoteComputer.convertType(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, out);
        }
    }
}
Also used : ITypeConvertComputer(org.apache.asterix.om.types.hierachy.ITypeConvertComputer) DataOutput(java.io.DataOutput) ATypeTag(org.apache.asterix.om.types.ATypeTag)

Aggregations

ATypeTag (org.apache.asterix.om.types.ATypeTag)3 ITypeConvertComputer (org.apache.asterix.om.types.hierachy.ITypeConvertComputer)3 DataOutput (java.io.DataOutput)2 IOException (java.io.IOException)1 IBinaryComparator (org.apache.hyracks.api.dataflow.value.IBinaryComparator)1 HyracksDataException (org.apache.hyracks.api.exceptions.HyracksDataException)1 PointableBinaryComparatorFactory (org.apache.hyracks.data.std.accessors.PointableBinaryComparatorFactory)1 ArrayBackedValueStorage (org.apache.hyracks.data.std.util.ArrayBackedValueStorage)1