http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/MonthsFromYearMonthDurationDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/MonthsFromYearMonthDurationDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/MonthsFromYearMonthDurationDescriptor.java index d7198f1..0d2b934 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/MonthsFromYearMonthDurationDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/MonthsFromYearMonthDurationDescriptor.java @@ -24,7 +24,6 @@ import org.apache.asterix.dataflow.data.nontagged.serde.AYearMonthDurationSerial import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; import org.apache.asterix.om.base.AInt64; import org.apache.asterix.om.base.AMutableInt64; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.functions.AsterixBuiltinFunctions; import org.apache.asterix.om.functions.IFunctionDescriptor; import org.apache.asterix.om.functions.IFunctionDescriptorFactory; @@ -71,10 +70,6 @@ public class MonthsFromYearMonthDurationDescriptor extends AbstractScalarFunctio private IPointable argPtr0 = new VoidPointable(); private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx); - // possible output types - @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); @SuppressWarnings("unchecked") private ISerializerDeserializer<AInt64> int64Serde = AqlSerializerDeserializerProvider.INSTANCE .getSerializerDeserializer(BuiltinType.AINT64); @@ -90,12 +85,6 @@ public class MonthsFromYearMonthDurationDescriptor extends AbstractScalarFunctio int offset = argPtr0.getStartOffset(); try { - if (bytes[offset] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - result.set(resultStorage); - return; - } - if (bytes[offset] != ATypeTag.SERIALIZED_YEAR_MONTH_DURATION_TYPE_TAG) { throw new AlgebricksException( FID.getName() + ": expects NULL/YEAR-MONTH-DURATION, but got "
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/OverlapBinsDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/OverlapBinsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/OverlapBinsDescriptor.java index fcf22e4..836408d 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/OverlapBinsDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/OverlapBinsDescriptor.java @@ -31,7 +31,6 @@ import org.apache.asterix.dataflow.data.nontagged.serde.AYearMonthDurationSerial import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; import org.apache.asterix.om.base.AInterval; import org.apache.asterix.om.base.AMutableInterval; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.base.temporal.DurationArithmeticOperations; import org.apache.asterix.om.base.temporal.GregorianCalendarSystem; import org.apache.asterix.om.functions.AsterixBuiltinFunctions; @@ -48,7 +47,6 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; import org.apache.hyracks.api.context.IHyracksTaskContext; import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer; -import org.apache.hyracks.api.exceptions.HyracksDataException; import org.apache.hyracks.data.std.api.IPointable; import org.apache.hyracks.data.std.primitive.VoidPointable; import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; @@ -93,10 +91,6 @@ public class OverlapBinsDescriptor extends AbstractScalarFunctionDynamicDescript protected final AOrderedListType intListType = new AOrderedListType(BuiltinType.AINTERVAL, null); private final AMutableInterval aInterval = new AMutableInterval(0, 0, (byte) -1); - - @SuppressWarnings("unchecked") - private final ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); @SuppressWarnings("unchecked") private final ISerializerDeserializer<AInterval> intervalSerde = AqlSerializerDeserializerProvider.INSTANCE .getSerializerDeserializer(BuiltinType.AINTERVAL); @@ -107,6 +101,9 @@ public class OverlapBinsDescriptor extends AbstractScalarFunctionDynamicDescript public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException { resultStorage.reset(); eval0.evaluate(tuple, argPtr0); + eval1.evaluate(tuple, argPtr1); + eval2.evaluate(tuple, argPtr2); + byte[] bytes0 = argPtr0.getByteArray(); int offset0 = argPtr0.getStartOffset(); @@ -119,32 +116,18 @@ public class OverlapBinsDescriptor extends AbstractScalarFunctionDynamicDescript intervalStart = AIntervalSerializerDeserializer.getIntervalStart(bytes0, offset0 + 1); intervalEnd = AIntervalSerializerDeserializer.getIntervalEnd(bytes0, offset0 + 1); intervalTypeTag = AIntervalSerializerDeserializer.getIntervalTimeType(bytes0, offset0 + 1); - } else if (type0 == ATypeTag.NULL) { - try { - nullSerde.serialize(ANull.NULL, out); - } catch (HyracksDataException e) { - throw new AlgebricksException(e); - } - result.set(resultStorage); - return; } else { throw new AlgebricksException(getIdentifier().getName() - + ": the first argument should be INTERVAL/NULL but got " + type0); + + ": the first argument should be INTERVAL/NULL/MISSING but got " + type0); } // get the anchor instance time - eval1.evaluate(tuple, argPtr1); byte[] bytes1 = argPtr1.getByteArray(); int offset1 = argPtr1.getStartOffset(); - ATypeTag type1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes1[offset1]); - - if (intervalTypeTag != type1.serialize()) { - if (intervalTypeTag != ATypeTag.SERIALIZED_NULL_TYPE_TAG && type1 != ATypeTag.NULL) { - throw new AlgebricksException( - getIdentifier().getName() + ": expecting compatible type to " + type0 + "(" - + intervalTypeTag + ") for the second argument but got " + type1); - } + if (intervalTypeTag != bytes1[offset1]) { + throw new AlgebricksException(getIdentifier().getName() + ": expecting compatible type to " + + type0 + "(" + intervalTypeTag + ") for the second argument but got " + type1); } long anchorTime = 0; @@ -159,21 +142,12 @@ public class OverlapBinsDescriptor extends AbstractScalarFunctionDynamicDescript case DATETIME: anchorTime = ADateTimeSerializerDeserializer.getChronon(bytes1, offset1 + 1); break; - case NULL: - try { - nullSerde.serialize(ANull.NULL, out); - } catch (HyracksDataException e) { - throw new AlgebricksException(e); - } - result.set(resultStorage); - return; default: throw new AlgebricksException( getIdentifier().getName() + ": expecting compatible type to " + type0 + "(" + intervalTypeTag + ") for the second argument but got " + type1); } - eval2.evaluate(tuple, argPtr2); byte[] bytes2 = argPtr2.getByteArray(); int offset2 = argPtr2.getStartOffset(); @@ -215,16 +189,6 @@ public class OverlapBinsDescriptor extends AbstractScalarFunctionDynamicDescript firstBinIndex = totalChronon / dayTime + ((totalChronon < 0 && totalChronon % dayTime != 0) ? -1 : 0); break; - - case NULL: - try { - nullSerde.serialize(ANull.NULL, out); - } catch (HyracksDataException e) { - throw new AlgebricksException(e); - } - result.set(resultStorage); - return; - default: throw new AlgebricksException(getIdentifier().getName() + ": expecting YEARMONTHDURATION/DAYTIMEDURATION for the thrid argument but got " http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java index 1243394..1810b48 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java @@ -23,7 +23,6 @@ import java.io.DataOutput; import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; import org.apache.asterix.om.base.ADate; import org.apache.asterix.om.base.AMutableDate; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.base.temporal.AsterixTemporalTypeParseException; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode; @@ -83,9 +82,6 @@ public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx); @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); - @SuppressWarnings("unchecked") private ISerializerDeserializer<ADate> dateSerde = AqlSerializerDeserializerProvider.INSTANCE .getSerializerDeserializer(BuiltinType.ADATE); @@ -106,13 +102,6 @@ public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor int len1 = argPtr1.getLength(); try { - if (bytes0[offset0] == ATypeTag.SERIALIZED_NULL_TYPE_TAG - || bytes1[offset1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - result.set(resultStorage); - return; - } - if (bytes0[offset0] != ATypeTag.SERIALIZED_STRING_TYPE_TAG || bytes1[offset1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { throw new AlgebricksException(getIdentifier().getName() http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java index 7c8847a..9717f8e 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java @@ -23,7 +23,6 @@ import java.io.DataOutput; import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; import org.apache.asterix.om.base.ADateTime; import org.apache.asterix.om.base.AMutableDateTime; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.base.temporal.AsterixTemporalTypeParseException; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode; @@ -78,9 +77,6 @@ public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx); @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); - @SuppressWarnings("unchecked") private ISerializerDeserializer<ADateTime> datetimeSerde = AqlSerializerDeserializerProvider.INSTANCE .getSerializerDeserializer(BuiltinType.ADATETIME); @@ -101,13 +97,6 @@ public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri int len1 = argPtr1.getLength(); try { - if (bytes0[offset0] == ATypeTag.SERIALIZED_NULL_TYPE_TAG - || bytes1[offset1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - result.set(resultStorage); - return; - } - if (bytes0[offset0] != ATypeTag.SERIALIZED_STRING_TYPE_TAG || bytes1[offset1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { throw new AlgebricksException(getIdentifier().getName() http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java index 893c357..fb4bc55 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java @@ -22,7 +22,6 @@ import java.io.DataOutput; import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; import org.apache.asterix.om.base.AMutableTime; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.base.ATime; import org.apache.asterix.om.base.temporal.AsterixTemporalTypeParseException; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils; @@ -79,9 +78,6 @@ public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx); @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); - @SuppressWarnings("unchecked") private ISerializerDeserializer<ATime> timeSerde = AqlSerializerDeserializerProvider.INSTANCE .getSerializerDeserializer(BuiltinType.ATIME); @@ -102,13 +98,6 @@ public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor int len1 = argPtr1.getLength(); try { - if (bytes0[offset0] == ATypeTag.SERIALIZED_NULL_TYPE_TAG - || bytes1[offset1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - result.set(resultStorage); - return; - } - if (bytes0[offset0] != ATypeTag.SERIALIZED_STRING_TYPE_TAG || bytes1[offset1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { throw new AlgebricksException(getIdentifier().getName() http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java index f48a5c4..b979786 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java @@ -22,8 +22,6 @@ import java.io.DataOutput; import java.io.IOException; import org.apache.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer; -import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode; import org.apache.asterix.om.base.temporal.GregorianCalendarSystem; @@ -31,7 +29,6 @@ import org.apache.asterix.om.functions.AsterixBuiltinFunctions; import org.apache.asterix.om.functions.IFunctionDescriptor; import org.apache.asterix.om.functions.IFunctionDescriptorFactory; import org.apache.asterix.om.types.ATypeTag; -import org.apache.asterix.om.types.BuiltinType; import org.apache.asterix.om.types.EnumDeserializer; import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; @@ -39,7 +36,6 @@ import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; import org.apache.hyracks.api.context.IHyracksTaskContext; -import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer; import org.apache.hyracks.data.std.api.IPointable; import org.apache.hyracks.data.std.primitive.VoidPointable; import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; @@ -78,10 +74,6 @@ public class PrintDateDescriptor extends AbstractScalarFunctionDynamicDescriptor private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx); private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx); - @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); - private StringBuilder sbder = new StringBuilder(); private final UTF8StringWriter utf8Writer = new UTF8StringWriter(); @@ -97,13 +89,6 @@ public class PrintDateDescriptor extends AbstractScalarFunctionDynamicDescriptor int offset1 = argPtr1.getStartOffset(); try { - if (bytes0[offset0] == ATypeTag.SERIALIZED_NULL_TYPE_TAG - || bytes1[offset1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - result.set(resultStorage); - return; - } - if (bytes0[offset0] != ATypeTag.SERIALIZED_DATE_TYPE_TAG || bytes1[offset1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { throw new AlgebricksException(getIdentifier().getName() http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java index 75fcfe7..780d09a 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java @@ -22,15 +22,12 @@ import java.io.DataOutput; import java.io.IOException; import org.apache.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer; -import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode; import org.apache.asterix.om.functions.AsterixBuiltinFunctions; import org.apache.asterix.om.functions.IFunctionDescriptor; import org.apache.asterix.om.functions.IFunctionDescriptorFactory; import org.apache.asterix.om.types.ATypeTag; -import org.apache.asterix.om.types.BuiltinType; import org.apache.asterix.om.types.EnumDeserializer; import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; @@ -38,7 +35,6 @@ import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; import org.apache.hyracks.api.context.IHyracksTaskContext; -import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer; import org.apache.hyracks.data.std.api.IPointable; import org.apache.hyracks.data.std.primitive.UTF8StringPointable; import org.apache.hyracks.data.std.primitive.VoidPointable; @@ -76,11 +72,6 @@ public class PrintDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri private IPointable argPtr1 = new VoidPointable(); private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx); private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx); - - @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); - private StringBuilder sbder = new StringBuilder(); private UTF8StringWriter utf8Writer = new UTF8StringWriter(); private UTF8StringPointable utf8Ptr = new UTF8StringPointable(); @@ -98,13 +89,6 @@ public class PrintDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri int len1 = argPtr1.getLength(); try { - if (bytes0[offset0] == ATypeTag.SERIALIZED_NULL_TYPE_TAG - || bytes1[offset1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - result.set(resultStorage); - return; - } - if (bytes0[offset0] != ATypeTag.SERIALIZED_DATETIME_TYPE_TAG || bytes1[offset1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { throw new AlgebricksException(getIdentifier().getName() http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java index 2318412..576de35 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java @@ -22,15 +22,12 @@ import java.io.DataOutput; import java.io.IOException; import org.apache.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer; -import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils; import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode; import org.apache.asterix.om.functions.AsterixBuiltinFunctions; import org.apache.asterix.om.functions.IFunctionDescriptor; import org.apache.asterix.om.functions.IFunctionDescriptorFactory; import org.apache.asterix.om.types.ATypeTag; -import org.apache.asterix.om.types.BuiltinType; import org.apache.asterix.om.types.EnumDeserializer; import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; @@ -38,7 +35,6 @@ import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; import org.apache.hyracks.api.context.IHyracksTaskContext; -import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer; import org.apache.hyracks.data.std.api.IPointable; import org.apache.hyracks.data.std.primitive.UTF8StringPointable; import org.apache.hyracks.data.std.primitive.VoidPointable; @@ -77,10 +73,6 @@ public class PrintTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx); private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx); - @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); - private StringBuilder sbder = new StringBuilder(); private final UTF8StringWriter writer = new UTF8StringWriter(); private final UTF8StringPointable utf8Ptr = new UTF8StringPointable(); @@ -98,13 +90,6 @@ public class PrintTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor int len1 = argPtr1.getLength(); try { - if (bytes0[offset0] == ATypeTag.SERIALIZED_NULL_TYPE_TAG - || bytes1[offset1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - result.set(resultStorage); - return; - } - if (bytes0[offset0] != ATypeTag.SERIALIZED_TIME_TYPE_TAG || bytes1[offset1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) { throw new AlgebricksException(getIdentifier().getName() http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromDatetimeDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromDatetimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromDatetimeDescriptor.java index a8c3fe6..6846ef8 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromDatetimeDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromDatetimeDescriptor.java @@ -23,7 +23,6 @@ import java.io.DataOutput; import org.apache.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer; import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; import org.apache.asterix.om.base.AMutableTime; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.base.ATime; import org.apache.asterix.om.base.temporal.GregorianCalendarSystem; import org.apache.asterix.om.functions.AsterixBuiltinFunctions; @@ -83,10 +82,6 @@ public class TimeFromDatetimeDescriptor extends AbstractScalarFunctionDynamicDes .getSerializerDeserializer(BuiltinType.ATIME); private AMutableTime aTime = new AMutableTime(0); - @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); - @Override public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException { resultStorage.reset(); @@ -96,22 +91,18 @@ public class TimeFromDatetimeDescriptor extends AbstractScalarFunctionDynamicDes int offset = argPtr.getStartOffset(); try { - if (bytes[offset] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - } else { - if (bytes[offset] != ATypeTag.SERIALIZED_DATETIME_TYPE_TAG) { - throw new AlgebricksException( - FID.getName() + ": expects input type DATETIME/NULL but got " - + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes[offset])); - } - long datetimeChronon = ADateTimeSerializerDeserializer.getChronon(bytes, offset + 1); - int timeChronon = (int) (datetimeChronon % GregorianCalendarSystem.CHRONON_OF_DAY); - if (timeChronon < 0) { - timeChronon += GregorianCalendarSystem.CHRONON_OF_DAY; - } - aTime.setValue(timeChronon); - timeSerde.serialize(aTime, out); + if (bytes[offset] != ATypeTag.SERIALIZED_DATETIME_TYPE_TAG) { + throw new AlgebricksException( + FID.getName() + ": expects input type DATETIME/NULL but got " + + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes[offset])); + } + long datetimeChronon = ADateTimeSerializerDeserializer.getChronon(bytes, offset + 1); + int timeChronon = (int) (datetimeChronon % GregorianCalendarSystem.CHRONON_OF_DAY); + if (timeChronon < 0) { + timeChronon += GregorianCalendarSystem.CHRONON_OF_DAY; } + aTime.setValue(timeChronon); + timeSerde.serialize(aTime, out); } catch (HyracksDataException hex) { throw new AlgebricksException(hex); } http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromUnixTimeInMsDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromUnixTimeInMsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromUnixTimeInMsDescriptor.java index 48be51d..e46241d 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromUnixTimeInMsDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/TimeFromUnixTimeInMsDescriptor.java @@ -22,12 +22,10 @@ import java.io.DataOutput; import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; import org.apache.asterix.om.base.AMutableTime; -import org.apache.asterix.om.base.ANull; import org.apache.asterix.om.base.ATime; import org.apache.asterix.om.functions.AsterixBuiltinFunctions; import org.apache.asterix.om.functions.IFunctionDescriptor; import org.apache.asterix.om.functions.IFunctionDescriptorFactory; -import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.BuiltinType; import org.apache.asterix.om.types.hierachy.ATypeHierarchy; import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; @@ -77,9 +75,6 @@ public class TimeFromUnixTimeInMsDescriptor extends AbstractScalarFunctionDynami @SuppressWarnings("unchecked") private ISerializerDeserializer<ATime> timeSerde = AqlSerializerDeserializerProvider.INSTANCE .getSerializerDeserializer(BuiltinType.ATIME); - @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); private AMutableTime aTime = new AMutableTime(0); @@ -88,13 +83,9 @@ public class TimeFromUnixTimeInMsDescriptor extends AbstractScalarFunctionDynami resultStorage.reset(); eval.evaluate(tuple, argPtr); try { - if (argPtr.getByteArray()[argPtr.getStartOffset()] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - } else { - aTime.setValue( - ATypeHierarchy.getIntegerValue(argPtr.getByteArray(), argPtr.getStartOffset())); - timeSerde.serialize(aTime, out); - } + aTime.setValue( + ATypeHierarchy.getIntegerValue(argPtr.getByteArray(), argPtr.getStartOffset())); + timeSerde.serialize(aTime, out); } catch (HyracksDataException hex) { throw new AlgebricksException(hex); } http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationComparatorDecriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationComparatorDecriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationComparatorDecriptor.java deleted file mode 100644 index 52cbaf5..0000000 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationComparatorDecriptor.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.asterix.runtime.evaluators.functions.temporal; - -import java.io.DataOutput; - -import org.apache.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer; -import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; -import org.apache.asterix.om.base.ABoolean; -import org.apache.asterix.om.base.ANull; -import org.apache.asterix.om.functions.AsterixBuiltinFunctions; -import org.apache.asterix.om.functions.IFunctionDescriptor; -import org.apache.asterix.om.functions.IFunctionDescriptorFactory; -import org.apache.asterix.om.types.ATypeTag; -import org.apache.asterix.om.types.BuiltinType; -import org.apache.asterix.om.types.EnumDeserializer; -import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; -import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; -import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; -import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; -import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; -import org.apache.hyracks.api.context.IHyracksTaskContext; -import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer; -import org.apache.hyracks.api.exceptions.HyracksDataException; -import org.apache.hyracks.data.std.api.IPointable; -import org.apache.hyracks.data.std.primitive.VoidPointable; -import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; -import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; - -public class YearMonthDurationComparatorDecriptor extends AbstractScalarFunctionDynamicDescriptor { - private final static long serialVersionUID = 1L; - public final static FunctionIdentifier GREATER_THAN_FID = AsterixBuiltinFunctions.YEAR_MONTH_DURATION_GREATER_THAN; - public final static FunctionIdentifier LESS_THAN_FID = AsterixBuiltinFunctions.YEAR_MONTH_DURATION_LESS_THAN; - private final boolean isGreaterThan; - - private YearMonthDurationComparatorDecriptor(boolean isGreaterThan) { - this.isGreaterThan = isGreaterThan; - } - - public final static IFunctionDescriptorFactory GREATER_THAN_FACTORY = new IFunctionDescriptorFactory() { - - @Override - public IFunctionDescriptor createFunctionDescriptor() { - return new YearMonthDurationComparatorDecriptor(true); - } - }; - - public final static IFunctionDescriptorFactory LESS_THAN_FACTORY = new IFunctionDescriptorFactory() { - - @Override - public IFunctionDescriptor createFunctionDescriptor() { - return new YearMonthDurationComparatorDecriptor(false); - } - }; - - @Override - public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) - throws AlgebricksException { - return new IScalarEvaluatorFactory() { - - private static final long serialVersionUID = 1L; - - @Override - public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws AlgebricksException { - return new IScalarEvaluator() { - - private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); - private DataOutput out = resultStorage.getDataOutput(); - private IPointable argPtr0 = new VoidPointable(); - private IPointable argPtr1 = new VoidPointable(); - private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx); - private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx); - - // possible output types - @SuppressWarnings("unchecked") - private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ANULL); - @SuppressWarnings("unchecked") - private ISerializerDeserializer<ABoolean> boolSerde = AqlSerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ABOOLEAN); - - @Override - public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException { - resultStorage.reset(); - eval0.evaluate(tuple, argPtr0); - eval1.evaluate(tuple, argPtr1); - - byte[] bytes0 = argPtr0.getByteArray(); - int offset0 = argPtr0.getStartOffset(); - byte[] bytes1 = argPtr1.getByteArray(); - int offset1 = argPtr1.getStartOffset(); - - try { - if (bytes0[offset0] == ATypeTag.SERIALIZED_NULL_TYPE_TAG - || bytes1[offset1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) { - nullSerde.serialize(ANull.NULL, out); - result.set(resultStorage); - return; - } - - if (bytes0[offset0] != ATypeTag.SERIALIZED_DURATION_TYPE_TAG - || bytes1[offset1] != ATypeTag.SERIALIZED_DURATION_TYPE_TAG) { - throw new AlgebricksException(getIdentifier().getName() - + ": expects type NULL/DURATION, NULL/DURATION but got " - + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes0[offset0]) + " and " - + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes1[offset1])); - } - - if ((ADurationSerializerDeserializer.getDayTime(bytes0, offset0 + 1) != 0) - || (ADurationSerializerDeserializer.getDayTime(bytes1, offset1 + 1) != 0)) { - throw new AlgebricksException( - getIdentifier().getName() + ": only year-month durations are allowed."); - } - - if (ADurationSerializerDeserializer.getYearMonth(bytes0, - offset0 + 1) > ADurationSerializerDeserializer.getYearMonth(bytes1, offset1 + 1)) { - boolSerde.serialize(isGreaterThan ? ABoolean.TRUE : ABoolean.FALSE, out); - } else { - boolSerde.serialize(isGreaterThan ? ABoolean.FALSE : ABoolean.TRUE, out); - } - } catch (HyracksDataException hex) { - throw new AlgebricksException(hex); - } - result.set(resultStorage); - } - }; - } - }; - } - - /* (non-Javadoc) - * @see org.apache.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier() - */ - @Override - public FunctionIdentifier getIdentifier() { - return isGreaterThan ? GREATER_THAN_FID : LESS_THAN_FID; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationComparatorDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationComparatorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationComparatorDescriptor.java new file mode 100644 index 0000000..10b8116 --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationComparatorDescriptor.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.asterix.runtime.evaluators.functions.temporal; + +import java.io.DataOutput; + +import org.apache.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer; +import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider; +import org.apache.asterix.om.base.ABoolean; +import org.apache.asterix.om.functions.AsterixBuiltinFunctions; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.asterix.om.types.BuiltinType; +import org.apache.asterix.om.types.EnumDeserializer; +import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; +import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; +import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; +import org.apache.hyracks.api.context.IHyracksTaskContext; +import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer; +import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.apache.hyracks.data.std.api.IPointable; +import org.apache.hyracks.data.std.primitive.VoidPointable; +import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; +import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; + +public class YearMonthDurationComparatorDescriptor extends AbstractScalarFunctionDynamicDescriptor { + private static final long serialVersionUID = 1L; + public static final FunctionIdentifier GREATER_THAN_FID = AsterixBuiltinFunctions.YEAR_MONTH_DURATION_GREATER_THAN; + public static final FunctionIdentifier LESS_THAN_FID = AsterixBuiltinFunctions.YEAR_MONTH_DURATION_LESS_THAN; + private final boolean isGreaterThan; + + protected YearMonthDurationComparatorDescriptor(boolean isGreaterThan) { + this.isGreaterThan = isGreaterThan; + } + + @Override + public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) + throws AlgebricksException { + return new IScalarEvaluatorFactory() { + + private static final long serialVersionUID = 1L; + + @Override + public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws AlgebricksException { + return new IScalarEvaluator() { + + private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); + private DataOutput out = resultStorage.getDataOutput(); + private IPointable argPtr0 = new VoidPointable(); + private IPointable argPtr1 = new VoidPointable(); + private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx); + private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx); + + @SuppressWarnings("unchecked") + private ISerializerDeserializer<ABoolean> boolSerde = AqlSerializerDeserializerProvider.INSTANCE + .getSerializerDeserializer(BuiltinType.ABOOLEAN); + + @Override + public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException { + resultStorage.reset(); + eval0.evaluate(tuple, argPtr0); + eval1.evaluate(tuple, argPtr1); + + byte[] bytes0 = argPtr0.getByteArray(); + int offset0 = argPtr0.getStartOffset(); + byte[] bytes1 = argPtr1.getByteArray(); + int offset1 = argPtr1.getStartOffset(); + + try { + if (bytes0[offset0] != ATypeTag.SERIALIZED_DURATION_TYPE_TAG + || bytes1[offset1] != ATypeTag.SERIALIZED_DURATION_TYPE_TAG) { + throw new AlgebricksException(getIdentifier().getName() + + ": expects type NULL/DURATION, NULL/DURATION but got " + + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes0[offset0]) + " and " + + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes1[offset1])); + } + + if ((ADurationSerializerDeserializer.getDayTime(bytes0, offset0 + 1) != 0) + || (ADurationSerializerDeserializer.getDayTime(bytes1, offset1 + 1) != 0)) { + throw new AlgebricksException( + getIdentifier().getName() + ": only year-month durations are allowed."); + } + + if (ADurationSerializerDeserializer.getYearMonth(bytes0, + offset0 + 1) > ADurationSerializerDeserializer.getYearMonth(bytes1, offset1 + 1)) { + boolSerde.serialize(isGreaterThan ? ABoolean.TRUE : ABoolean.FALSE, out); + } else { + boolSerde.serialize(isGreaterThan ? ABoolean.FALSE : ABoolean.TRUE, out); + } + } catch (HyracksDataException hex) { + throw new AlgebricksException(hex); + } + result.set(resultStorage); + } + }; + } + }; + } + + /* (non-Javadoc) + * @see org.apache.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier() + */ + @Override + public FunctionIdentifier getIdentifier() { + return isGreaterThan ? GREATER_THAN_FID : LESS_THAN_FID; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationGreaterThanComparatorDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationGreaterThanComparatorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationGreaterThanComparatorDescriptor.java new file mode 100644 index 0000000..42458ad --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationGreaterThanComparatorDescriptor.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.asterix.runtime.evaluators.functions.temporal; + +import org.apache.asterix.om.functions.IFunctionDescriptor; +import org.apache.asterix.om.functions.IFunctionDescriptorFactory; + +public class YearMonthDurationGreaterThanComparatorDescriptor extends YearMonthDurationComparatorDescriptor { + + private static final long serialVersionUID = 1L; + public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { + + @Override + public IFunctionDescriptor createFunctionDescriptor() { + return new YearMonthDurationGreaterThanComparatorDescriptor(); + } + }; + + protected YearMonthDurationGreaterThanComparatorDescriptor() { + super(true); + } +} http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationLessThanComparatorDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationLessThanComparatorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationLessThanComparatorDescriptor.java new file mode 100644 index 0000000..da8867d --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/YearMonthDurationLessThanComparatorDescriptor.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.asterix.runtime.evaluators.functions.temporal; + +import org.apache.asterix.om.functions.IFunctionDescriptor; +import org.apache.asterix.om.functions.IFunctionDescriptorFactory; + +public class YearMonthDurationLessThanComparatorDescriptor extends YearMonthDurationComparatorDescriptor { + + private static final long serialVersionUID = 1L; + public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { + + @Override + public IFunctionDescriptor createFunctionDescriptor() { + return new YearMonthDurationLessThanComparatorDescriptor(); + } + }; + + protected YearMonthDurationLessThanComparatorDescriptor() { + super(false); + } +} http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/CodeGenUtil.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/CodeGenUtil.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/CodeGenUtil.java index 3de9fc4..1da88a1 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/CodeGenUtil.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/CodeGenUtil.java @@ -22,6 +22,8 @@ package org.apache.asterix.runtime.evaluators.staticcodegen; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -36,11 +38,16 @@ public class CodeGenUtil { public final static String DEFAULT_SUFFIX_FOR_GENERATED_CLASS = "Gen"; private final static String OBJECT_CLASS_NAME = "java/lang/Object"; + private final static String DESCRIPTOR_SUPER_CLASS_NAME = "org/apache/asterix/runtime/" + + "evaluators/base/AbstractScalarFunctionDynamicDescriptor"; private final static String EVALUATOR_FACTORY = "EvaluatorFactory"; private final static String EVALUATOR = "Evaluator"; private final static String INNER = "Inner"; private final static String DESCRIPTOR = "Descriptor"; + private final static String ACCESSOR = "Accessor"; private final static String DOLLAR = "$"; + private final static String PKG_SUFFIX = "/generated"; + private final static String ASTERIXDB_PREFIX = "org/apache/asterix"; /** * The callback interface for a caller to determine what it needs to do for @@ -74,15 +81,26 @@ public class CodeGenUtil { * @throws IOException * @throws ClassNotFoundException */ - public static void generateScalarFunctionDescriptorBinary(String packagePrefix, + public static List<Pair<String, String>> generateScalarFunctionDescriptorBinary(String packagePrefix, String originalFuncDescriptorClassName, String suffixForGeneratedClass, ClassLoader classLoader, ClassByteCodeAction action) throws IOException, ClassNotFoundException { originalFuncDescriptorClassName = toInternalClassName(originalFuncDescriptorClassName); - String targetFuncDescriptorClassName = toInternalClassName( - originalFuncDescriptorClassName + suffixForGeneratedClass); + if (originalFuncDescriptorClassName.equals(DESCRIPTOR_SUPER_CLASS_NAME)) { + return Collections.emptyList(); + } + + String targetFuncDescriptorClassName = getGeneratedFunctionDescriptorInternalClassName( + originalFuncDescriptorClassName, suffixForGeneratedClass); // Adds the mapping of the old/new names of the function descriptor. List<Pair<String, String>> nameMappings = new ArrayList<>(); + + // Generates code for super classes except java.lang.Object. + Class<?> evaluatorClass = CodeGenUtil.class.getClassLoader() + .loadClass(toJdkStandardName(originalFuncDescriptorClassName)); + nameMappings.addAll(generateScalarFunctionDescriptorBinary(packagePrefix, + evaluatorClass.getSuperclass().getName(), suffixForGeneratedClass, classLoader, action)); + nameMappings.add(Pair.of(originalFuncDescriptorClassName, targetFuncDescriptorClassName)); nameMappings.add(Pair.of(toJdkStandardName(originalFuncDescriptorClassName), toJdkStandardName(targetFuncDescriptorClassName))); @@ -102,7 +120,7 @@ public class CodeGenUtil { int evalFactoryCounter = 0; for (String evaluateFactoryClassName : evaluatorFactoryClassNames) { generateEvaluatorFactoryClassBinary(packagePrefix, evaluateFactoryClassName, suffixForGeneratedClass, - ++evalFactoryCounter, nameMappings, classLoader, action); + evalFactoryCounter++, nameMappings, classLoader, action); } // Transforms the function descriptor class and outputs the generated class binary. @@ -110,6 +128,21 @@ public class CodeGenUtil { RenameClassVisitor renamingVisitor = new RenameClassVisitor(writer, nameMappings); reader.accept(renamingVisitor, 0); action.runAction(targetFuncDescriptorClassName, writer.toByteArray()); + return nameMappings; + } + + public static String getGeneratedFunctionDescriptorClassName(String originalFuncDescriptorClassName, + String suffixForGeneratedClass) { + return toJdkStandardName(getGeneratedFunctionDescriptorInternalClassName(originalFuncDescriptorClassName, + suffixForGeneratedClass)); + } + + private static String getGeneratedFunctionDescriptorInternalClassName(String originalFuncDescriptorClassName, + String suffixForGeneratedClass) { + String originalFuncDescriptorClassInternalName = toInternalClassName(originalFuncDescriptorClassName); + String targetFuncDescriptorClassName = getGeneratedClassName(originalFuncDescriptorClassInternalName, + suffixForGeneratedClass, 0); + return targetFuncDescriptorClassName; } /** @@ -184,7 +217,7 @@ public class CodeGenUtil { // Generates code for all evaluators. int evalCounter = 0; for (String evaluateClassName : evaluatorClassNames) { - generateEvaluatorClassBinary(evaluateClassName, suffixForGeneratedClass, ++evalCounter, nameMappings, + generateEvaluatorClassBinary(evaluateClassName, suffixForGeneratedClass, evalCounter++, nameMappings, classLoader, action); } @@ -235,13 +268,31 @@ public class CodeGenUtil { nameMappings.add( Pair.of(toJdkStandardName(originalEvaluatorClassName), toJdkStandardName(targetEvaluatorClassName))); + ClassReader firstPassReader = new ClassReader(getResourceStream(originalEvaluatorClassName, classLoader)); + // Generates inner classes other than the evaluator. + Set<String> excludedNames = new HashSet<>(); + for (Pair<String, String> entry : nameMappings) { + excludedNames.add(entry.getKey()); + } + generateNonEvalInnerClasses(firstPassReader, excludedNames, nameMappings, suffixForGeneratedClass, classLoader, + action); + + // Injects missing-handling byte code. + ClassWriter firstPassWriter = new ClassWriter(firstPassReader, 0); + EvaluatorMissingCheckVisitor missingHandlingVisitor = new EvaluatorMissingCheckVisitor(firstPassWriter); + firstPassReader.accept(missingHandlingVisitor, 0); + + ClassReader secondPassReader = new ClassReader(firstPassWriter.toByteArray()); // Injects null-handling byte code and output the class binary. - ClassReader reader = new ClassReader(getResourceStream(originalEvaluatorClassName, classLoader)); - ClassWriter writer = new ClassWriter(reader, 0); - RenameClassVisitor renamingVisitor = new RenameClassVisitor(writer, nameMappings); - EvaluatorVisitor evaluateVisitor = new EvaluatorVisitor(renamingVisitor); - reader.accept(evaluateVisitor, 0); - action.runAction(targetEvaluatorClassName, writer.toByteArray()); + // Since we're going to add jump instructions, we have to let the ClassWriter to + // automatically generate frames for JVM to verify the class. + ClassWriter secondPassWriter = new ClassWriter(secondPassReader, + ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + RenameClassVisitor renamingVisitor = new RenameClassVisitor(secondPassWriter, nameMappings); + EvaluatorNullCheckVisitor nullHandlingVisitor = new EvaluatorNullCheckVisitor(renamingVisitor, + missingHandlingVisitor.getLastAddedLabel()); + secondPassReader.accept(nullHandlingVisitor, 0); + action.runAction(targetEvaluatorClassName, secondPassWriter.toByteArray()); } /** @@ -275,7 +326,7 @@ public class CodeGenUtil { String suffix = INNER + suffixForGeneratedClass; for (String innerClassName : innerClassNames) { // adds name mapping. - String targetInnerClassName = getGeneratedClassName(innerClassName, suffix, ++counter); + String targetInnerClassName = getGeneratedClassName(innerClassName, suffix, counter++); nameMappings.add(Pair.of(innerClassName, targetInnerClassName)); nameMappings.add(Pair.of(toJdkStandardName(innerClassName), toJdkStandardName(targetInnerClassName))); @@ -325,15 +376,25 @@ public class CodeGenUtil { StringBuilder sb = new StringBuilder(); int end = originalClassName.indexOf(DESCRIPTOR); if (end < 0) { + end = originalClassName.indexOf(ACCESSOR); + } + if (end < 0) { end = originalClassName.indexOf(DOLLAR); } if (end < 0) { - end = originalClassName.length() - 1; + end = originalClassName.length(); } - sb.append(originalClassName.substring(0, end)); + String name = originalClassName.substring(0, end); + String lastName = name.substring(ASTERIXDB_PREFIX.length()); + + sb.append(ASTERIXDB_PREFIX); + sb.append(PKG_SUFFIX); + sb.append(lastName); sb.append(suffix); - sb.append(counter); + if (counter > 0) { + sb.append(counter); + } return sb.toString(); } http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/EvaluatorMissingCheckVisitor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/EvaluatorMissingCheckVisitor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/EvaluatorMissingCheckVisitor.java new file mode 100644 index 0000000..adedee5 --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/EvaluatorMissingCheckVisitor.java @@ -0,0 +1,228 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.asterix.runtime.evaluators.staticcodegen; + +import java.util.ArrayList; +import java.util.List; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.IincInsnNode; +import org.objectweb.asm.tree.InsnNode; +import org.objectweb.asm.tree.IntInsnNode; +import org.objectweb.asm.tree.VarInsnNode; + +/** + * This visitor adds missing-handling byte code into an evaluator class. + */ +public class EvaluatorMissingCheckVisitor extends ClassVisitor { + private static final String EVALUATE_DESC = "(Lorg/apache/hyracks/dataflow/common/data/" + + "accessors/IFrameTupleReference;Lorg/apache/hyracks/data/std/api/IPointable;)V"; + private static final String EVALUATE = "evaluate"; + private static final MethodIdentifier METHOD_IDENTIFIER = new MethodIdentifier(EVALUATE, EVALUATE_DESC, null); + private static final String TYPE_CHECKER_CLASS = "org/apache/asterix/runtime/evaluators/staticcodegen/TypeChecker"; + private static final String TYPE_CHECKER_DESC = "L" + TYPE_CHECKER_CLASS + ";"; + private static final String TYPE_CHECKER_NAME = "typeChecker"; + private static final String IS_MISSING = "isMissing"; + private static final String TYPECHECK_METHOD_DESC = "(Lorg/apache/hyracks/data/std/api/IPointable;" + + "Lorg/apache/hyracks/data/std/api/IPointable;)Z"; + private static final String CONSTRUCTOR = "<init>"; + private String className = null; + private Label lastAddedLabel = null; + + public EvaluatorMissingCheckVisitor(ClassVisitor downStreamVisitor) { + super(Opcodes.ASM5, downStreamVisitor); + } + + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + if (cv != null) { + cv.visit(version, access, name, signature, superName, interfaces); + } + this.className = name; + } + + @Override + public void visitEnd() { + if (cv != null) { + cv.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, TYPE_CHECKER_NAME, TYPE_CHECKER_DESC, null, null); + cv.visitEnd(); + } + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); + if (!METHOD_IDENTIFIER.equals(new MethodIdentifier(name, desc, signature)) && !name.equals(CONSTRUCTOR)) { + return mv; + } + if (name.equals(CONSTRUCTOR) && mv != null) { + return new ConstructorVisitor(Opcodes.ASM5, mv); + } + if (mv != null) { + return new InjectMissingCheckVisitor(Opcodes.ASM5, mv); + } + return null; + } + + // Obtains the last added label. + Label getLastAddedLabel() { + return lastAddedLabel; + } + + class ConstructorVisitor extends MethodVisitor { + + public ConstructorVisitor(int api, MethodVisitor mv) { + super(api, mv); + } + + @Override + public void visitInsn(int opcode) { + if (opcode != Opcodes.RETURN) { + mv.visitInsn(opcode); + return; + } + // Loads "this". + mv.visitVarInsn(Opcodes.ALOAD, 0); + // New TypeChecker. + mv.visitTypeInsn(Opcodes.NEW, TYPE_CHECKER_CLASS); + // Duplicate the top operand. + mv.visitInsn(Opcodes.DUP); + // Invoke the constructor of TypeChecker. + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, TYPE_CHECKER_CLASS, CONSTRUCTOR, "()V", true); + // Putfield for the field typeChecker. + mv.visitFieldInsn(Opcodes.PUTFIELD, className, TYPE_CHECKER_NAME, TYPE_CHECKER_DESC); + // RETURN. + mv.visitInsn(Opcodes.RETURN); + } + } + + class InjectMissingCheckVisitor extends MethodVisitor { + + private FieldInsnNode fieldAccessNode = null; + private List<AbstractInsnNode> instructionsAfterFieldAccess = new ArrayList<>(); + private boolean updateToNextLabel = false; + + public InjectMissingCheckVisitor(int opcode, MethodVisitor mv) { + super(opcode, mv); + } + + @Override + public void visitFieldInsn(int opcode, String owner, String name, String desc) { + mv.visitFieldInsn(opcode, owner, name, desc); + fieldAccessNode = new FieldInsnNode(opcode, owner, name, desc); + instructionsAfterFieldAccess.clear(); + } + + @Override + public void visitIincInsn(int var, int increment) { + if (fieldAccessNode != null) { + instructionsAfterFieldAccess.add(new IincInsnNode(var, increment)); + } + super.visitIincInsn(var, increment); + } + + @Override + public void visitInsn(int opcode) { + if (fieldAccessNode != null) { + instructionsAfterFieldAccess.add(new InsnNode(opcode)); + } + super.visitInsn(opcode); + } + + @Override + public void visitIntInsn(int opcode, int operand) { + if (fieldAccessNode != null) { + instructionsAfterFieldAccess.add(new IntInsnNode(opcode, operand)); + } + super.visitIntInsn(opcode, operand); + } + + @Override + public void visitVarInsn(int opcode, int operand) { + if (fieldAccessNode != null) { + instructionsAfterFieldAccess.add(new VarInsnNode(opcode, operand)); + } + super.visitVarInsn(opcode, operand); + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { + mv.visitMethodInsn(opcode, owner, name, desc, itf); + if (fieldAccessNode == null || !METHOD_IDENTIFIER.equals(new MethodIdentifier(name, desc, null))) { + return; + } + + // Loads the callee. + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitFieldInsn(Opcodes.GETFIELD, className, TYPE_CHECKER_NAME, TYPE_CHECKER_DESC); + + // Loads "this". + mv.visitVarInsn(Opcodes.ALOAD, 0); + // Replays the field access instruction. + fieldAccessNode.accept(mv); + + // Replays other instruction between the field access and the evaluator call. + for (AbstractInsnNode instruction : instructionsAfterFieldAccess) { + instruction.accept(mv); + } + + // Loads the result IPointable. + mv.visitVarInsn(Opcodes.ALOAD, 2); + + // Invokes the missing check method. + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_CHECKER_CLASS, IS_MISSING, TYPECHECK_METHOD_DESC, false); + lastAddedLabel = new Label(); + // Adds the if branch. + mv.visitJumpInsn(Opcodes.IFEQ, lastAddedLabel); + mv.visitInsn(Opcodes.RETURN); + mv.visitLabel(lastAddedLabel); + } + + @Override + public void visitLabel(Label label) { + if (updateToNextLabel) { + lastAddedLabel = label; + updateToNextLabel = false; + } + super.visitLabel(label); + } + + @Override + public void visitJumpInsn(int opcode, Label label) { + super.visitJumpInsn(opcode, label); + if (lastAddedLabel == null) { + return; + } + try { + if (label.getOffset() < lastAddedLabel.getOffset()) { + // Backward jump, i.e., loop. + updateToNextLabel = true; + } + } catch (IllegalStateException e) { + // Forward jump, the offset is not available. + } + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/EvaluatorNullCheckVisitor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/EvaluatorNullCheckVisitor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/EvaluatorNullCheckVisitor.java new file mode 100644 index 0000000..30f810b --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/staticcodegen/EvaluatorNullCheckVisitor.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.asterix.runtime.evaluators.staticcodegen; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * This visitor adds null-handling byte code into an evaluator class. + */ +public class EvaluatorNullCheckVisitor extends ClassVisitor { + private final static String EVALUATE_DESC = "(Lorg/apache/hyracks/dataflow/common/data/accessors/" + + "IFrameTupleReference;Lorg/apache/hyracks/data/std/api/IPointable;)V"; + private final static String EVALUATE = "evaluate"; + private final static MethodIdentifier METHOD_IDENTIFIER = new MethodIdentifier(EVALUATE, EVALUATE_DESC, null); + private final static String TYPE_CHECKER_CLASS = "org/apache/asterix/runtime/evaluators/staticcodegen/" + + "TypeChecker"; + private final static String TYPE_CHECKER_DESC = "L" + TYPE_CHECKER_CLASS + ";"; + private final static String TYPE_CHECKER_NAME = "typeChecker"; + private final static String IS_NULL = "isNull"; + private final static String TYPECHECK_METHOD_DESC = "(Lorg/apache/hyracks/data/std/api/IPointable;)Z"; + private String className = null; + private final Label lastAddedLabel; + + public EvaluatorNullCheckVisitor(ClassVisitor downStreamVisitor, Label lastAddedLabel) { + super(Opcodes.ASM5, downStreamVisitor); + this.lastAddedLabel = lastAddedLabel; + } + + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + if (cv != null) { + cv.visit(version, access, name, signature, superName, interfaces); + } + this.className = name; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); + if (!METHOD_IDENTIFIER.equals(new MethodIdentifier(name, desc, signature))) { + return mv; + } + if (mv != null) { + return new InjectNullCheckVisitor(Opcodes.ASM5, mv); + } + return null; + } + + // Obtains the last added label. + Label getLastAddedLabel() { + return lastAddedLabel; + } + + class InjectNullCheckVisitor extends MethodVisitor { + + public InjectNullCheckVisitor(int api, MethodVisitor mv) { + super(api, mv); + } + + @Override + public void visitLabel(Label label) { + // Emits the label. + mv.visitLabel(label); + + // Injects null-handling after the last missing-handling byte code. + if (lastAddedLabel == null || lastAddedLabel.getOffset() != label.getOffset()) { + return; + } + + // Loads the callee. + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitFieldInsn(Opcodes.GETFIELD, className, TYPE_CHECKER_NAME, TYPE_CHECKER_DESC); + + // Loads the result IPointable. + mv.visitVarInsn(Opcodes.ALOAD, 2); + + // Invokes the null check method. + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, TYPE_CHECKER_CLASS, IS_NULL, TYPECHECK_METHOD_DESC, false); + Label notNull = new Label(); + // Adds the if branch. + mv.visitJumpInsn(Opcodes.IFEQ, notNull); + mv.visitInsn(Opcodes.RETURN); + mv.visitLabel(notNull); + } + } +}
