Added asterix project
git-svn-id: https://asterixdb.googlecode.com/svn/trunk/asterix@12 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..07d8141
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
@@ -0,0 +1,12 @@
+package edu.uci.ics.asterix.runtime.aggregates.base;
+
+import edu.uci.ics.asterix.common.functions.FunctionDescriptorTag;
+import edu.uci.ics.asterix.runtime.base.IAggregateFunctionDynamicDescriptor;
+
+public abstract class AbstractAggregateFunctionDynamicDescriptor implements IAggregateFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ public FunctionDescriptorTag getFunctionDescriptorTag() {
+ return FunctionDescriptorTag.AGGREGATE;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/AbstractSerializableAggregateFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/AbstractSerializableAggregateFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..0634868
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/base/AbstractSerializableAggregateFunctionDynamicDescriptor.java
@@ -0,0 +1,15 @@
+package edu.uci.ics.asterix.runtime.aggregates.base;
+
+import edu.uci.ics.asterix.common.functions.FunctionDescriptorTag;
+import edu.uci.ics.asterix.runtime.base.ISerializableAggregateFunctionDynamicDescriptor;
+
+public abstract class AbstractSerializableAggregateFunctionDynamicDescriptor implements
+ ISerializableAggregateFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public FunctionDescriptorTag getFunctionDescriptorTag() {
+ return FunctionDescriptorTag.SERIALAGGREGATE;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/collections/ListifyAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/collections/ListifyAggregateDescriptor.java
new file mode 100644
index 0000000..b3a38a0
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/collections/ListifyAggregateDescriptor.java
@@ -0,0 +1,34 @@
+package edu.uci.ics.asterix.runtime.aggregates.collections;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+
+public class ListifyAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "listify", 1,
+ true);
+
+ private AOrderedListType oltype;
+
+ public void reset(AOrderedListType orderedListType) {
+ this.oltype = orderedListType;
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new ListifyAggregateFunctionEvalFactory(args, oltype);
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/collections/ListifyAggregateFunctionEvalFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/collections/ListifyAggregateFunctionEvalFactory.java
new file mode 100644
index 0000000..e1ccc93
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/collections/ListifyAggregateFunctionEvalFactory.java
@@ -0,0 +1,76 @@
+package edu.uci.ics.asterix.runtime.aggregates.collections;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ListifyAggregateFunctionEvalFactory implements IAggregateFunctionFactory {
+
+ private static final long serialVersionUID = 1L;
+ private IEvaluatorFactory[] args;
+ private final AOrderedListType orderedlistType;
+
+ public ListifyAggregateFunctionEvalFactory(IEvaluatorFactory[] args, AOrderedListType type) {
+ this.args = args;
+ this.orderedlistType = type;
+ }
+
+ @Override
+ public IAggregateFunction createAggregateFunction(final IDataOutputProvider provider) throws AlgebricksException {
+
+ return new IAggregateFunction() {
+
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(inputVal);
+ private DataOutput out = provider.getDataOutput();
+ private OrderedListBuilder builder = new OrderedListBuilder();
+
+ @Override
+ public void init() throws AlgebricksException {
+ try {
+ builder.reset(orderedlistType);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ inputVal.reset();
+ eval.evaluate(tuple);
+ builder.addItem(inputVal);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void finish() throws AlgebricksException {
+ try {
+ builder.write(out, true);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void finishPartial() throws AlgebricksException {
+ finish();
+ }
+
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/BufferSerDeUtil.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/BufferSerDeUtil.java
new file mode 100644
index 0000000..a0bccde
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/BufferSerDeUtil.java
@@ -0,0 +1,67 @@
+package edu.uci.ics.asterix.runtime.aggregates.serializable.std;
+
+public class BufferSerDeUtil {
+
+ public static double getDouble(byte[] bytes, int offset) {
+ return Double.longBitsToDouble(getLong(bytes, offset));
+ }
+
+ public static float getFloat(byte[] bytes, int offset) {
+ return Float.intBitsToFloat(getInt(bytes, offset));
+ }
+
+ public static boolean getBoolean(byte[] bytes, int offset) {
+ if (bytes[offset] == 0)
+ return false;
+ else
+ return true;
+ }
+
+ public static int getInt(byte[] bytes, int offset) {
+ return ((bytes[offset] & 0xff) << 24) + ((bytes[offset + 1] & 0xff) << 16) + ((bytes[offset + 2] & 0xff) << 8)
+ + ((bytes[offset + 3] & 0xff) << 0);
+ }
+
+ public static long getLong(byte[] bytes, int offset) {
+ return (((long) (bytes[offset] & 0xff)) << 56) + (((long) (bytes[offset + 1] & 0xff)) << 48)
+ + (((long) (bytes[offset + 2] & 0xff)) << 40) + (((long) (bytes[offset + 3] & 0xff)) << 32)
+ + (((long) (bytes[offset + 4] & 0xff)) << 24) + (((long) (bytes[offset + 5] & 0xff)) << 16)
+ + (((long) (bytes[offset + 6] & 0xff)) << 8) + (((long) (bytes[offset + 7] & 0xff)) << 0);
+ }
+
+ public static void writeBoolean(boolean value, byte[] bytes, int offset) {
+ if (value)
+ bytes[offset] = (byte) 1;
+ else
+ bytes[offset] = (byte) 0;
+ }
+
+ public static void writeInt(int value, byte[] bytes, int offset) {
+ bytes[offset++] = (byte) (value >> 24);
+ bytes[offset++] = (byte) (value >> 16);
+ bytes[offset++] = (byte) (value >> 8);
+ bytes[offset++] = (byte) (value);
+ }
+
+ public static void writeLong(long value, byte[] bytes, int offset) {
+ bytes[offset++] = (byte) (value >> 56);
+ bytes[offset++] = (byte) (value >> 48);
+ bytes[offset++] = (byte) (value >> 40);
+ bytes[offset++] = (byte) (value >> 32);
+ bytes[offset++] = (byte) (value >> 24);
+ bytes[offset++] = (byte) (value >> 16);
+ bytes[offset++] = (byte) (value >> 8);
+ bytes[offset++] = (byte) (value);
+ }
+
+ public static void writeDouble(double value, byte[] bytes, int offset) {
+ long lValue = Double.doubleToLongBits(value);
+ writeLong(lValue, bytes, offset);
+ }
+
+ public static void writeFloat(float value, byte[] bytes, int offset) {
+ int iValue = Float.floatToIntBits(value);
+ writeInt(iValue, bytes, offset);
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableAvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableAvgAggregateDescriptor.java
new file mode 100644
index 0000000..86b7052
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableAvgAggregateDescriptor.java
@@ -0,0 +1,171 @@
+package edu.uci.ics.asterix.runtime.aggregates.serializable.std;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractSerializableAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SerializableAvgAggregateDescriptor extends AbstractSerializableAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "avg-serial", 1,
+ true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public ISerializableAggregateFunctionFactory createAggregateFunctionFactory(IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ final IEvaluatorFactory[] evals = args;
+
+ return new ISerializableAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ public ISerializableAggregateFunction createAggregateFunction() throws AlgebricksException {
+ return new ISerializableAggregateFunction() {
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = evals[0].createEvaluator(inputVal);
+
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void init(DataOutput state) throws AlgebricksException {
+ try {
+ state.writeDouble(0.0);
+ state.writeLong(0);
+ state.writeBoolean(false);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple, byte[] state, int start, int len)
+ throws AlgebricksException {
+ inputVal.reset();
+ eval.evaluate(tuple);
+ double sum = BufferSerDeUtil.getDouble(state, start);
+ long count = BufferSerDeUtil.getLong(state, start + 8);
+ boolean metNull = BufferSerDeUtil.getBoolean(state, start + 16);
+ if (inputVal.getLength() > 0) {
+ ++count;
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(inputVal.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ byte val = AInt8SerializerDeserializer.getByte(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT16: {
+ short val = AInt16SerializerDeserializer.getShort(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT32: {
+ int val = AInt32SerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT64: {
+ long val = AInt64SerializerDeserializer.getLong(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case FLOAT: {
+ float val = AFloatSerializerDeserializer.getFloat(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case DOUBLE: {
+ double val = ADoubleSerializerDeserializer.getDouble(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case NULL: {
+ metNull = true;
+ break;
+ }
+ default: {
+ throw new NotImplementedException("Cannot compute AVG for values of type "
+ + typeTag);
+ }
+ }
+ inputVal.reset();
+ }
+ BufferSerDeUtil.writeDouble(sum, state, start);
+ BufferSerDeUtil.writeLong(count, state, start + 8);
+ BufferSerDeUtil.writeBoolean(metNull, state, start + 16);
+ }
+
+ @Override
+ public void finish(byte[] state, int start, int len, DataOutput result) throws AlgebricksException {
+ double sum = BufferSerDeUtil.getDouble(state, start);
+ long count = BufferSerDeUtil.getLong(state, start + 8);
+ boolean metNull = BufferSerDeUtil.getBoolean(state, start + 16);
+
+ if (count == 0) {
+ GlobalConfig.ASTERIX_LOGGER.fine("AVG aggregate ran over empty input.");
+ } else {
+ try {
+ if (metNull)
+ nullSerde.serialize(ANull.NULL, result);
+ else {
+ aDouble.setValue(sum / count);
+ doubleSerde.serialize(aDouble, result);
+ }
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+ @Override
+ public void finishPartial(byte[] data, int start, int len, DataOutput partialResult)
+ throws AlgebricksException {
+ try {
+ partialResult.write(data, start, len);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ };
+ }
+ };
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableCountAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableCountAggregateDescriptor.java
new file mode 100644
index 0000000..62e1efc
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableCountAggregateDescriptor.java
@@ -0,0 +1,87 @@
+package edu.uci.ics.asterix.runtime.aggregates.serializable.std;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractSerializableAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+/**
+ * NULLs are also counted.
+ */
+public class SerializableCountAggregateDescriptor extends AbstractSerializableAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "count-serial",
+ 1, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public ISerializableAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new ISerializableAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public ISerializableAggregateFunction createAggregateFunction() throws AlgebricksException {
+
+ return new ISerializableAggregateFunction() {
+ private AMutableInt32 result = new AMutableInt32(-1);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+
+ @Override
+ public void init(DataOutput state) throws AlgebricksException {
+ try {
+ state.writeInt(0);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple, byte[] state, int start, int len)
+ throws AlgebricksException {
+ int cnt = BufferSerDeUtil.getInt(state, start);
+ cnt++;
+ BufferSerDeUtil.writeInt(cnt, state, start);
+ }
+
+ @Override
+ public void finish(byte[] state, int start, int len, DataOutput out) throws AlgebricksException {
+ int cnt = BufferSerDeUtil.getInt(state, start);
+ try {
+ result.setValue(cnt);
+ int32Serde.serialize(result, out);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void finishPartial(byte[] state, int start, int len, DataOutput out)
+ throws AlgebricksException {
+ finish(state, start, len, out);
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableGlobalAvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableGlobalAvgAggregateDescriptor.java
new file mode 100644
index 0000000..c046652
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableGlobalAvgAggregateDescriptor.java
@@ -0,0 +1,195 @@
+package edu.uci.ics.asterix.runtime.aggregates.serializable.std;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARecordSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AInt64;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractSerializableAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.AccessibleByteArrayEval;
+import edu.uci.ics.asterix.runtime.evaluators.common.ClosedRecordConstructorEvalFactory.ClosedRecordConstructorEval;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SerializableGlobalAvgAggregateDescriptor extends AbstractSerializableAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "global-avg-serial", 1, true);
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static byte SER_RECORD_TYPE_TAG = ATypeTag.RECORD.serialize();
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public ISerializableAggregateFunctionFactory createAggregateFunctionFactory(IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ final IEvaluatorFactory[] evals = args;
+ List<IAType> unionList = new ArrayList<IAType>();
+ unionList.add(BuiltinType.ANULL);
+ unionList.add(BuiltinType.ADOUBLE);
+ final ARecordType recType = new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
+ new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT64 }, true);
+
+ return new ISerializableAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public ISerializableAggregateFunction createAggregateFunction() throws AlgebricksException {
+
+ return new ISerializableAggregateFunction() {
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = evals[0].createEvaluator(inputVal);
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+
+ private ArrayBackedValueStorage avgBytes = new ArrayBackedValueStorage();
+ private ByteArrayAccessibleOutputStream sumBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput sumBytesOutput = new DataOutputStream(sumBytes);
+ private ByteArrayAccessibleOutputStream countBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput countBytesOutput = new DataOutputStream(countBytes);
+ private IEvaluator evalSum = new AccessibleByteArrayEval(avgBytes.getDataOutput(), sumBytes);
+ private IEvaluator evalCount = new AccessibleByteArrayEval(avgBytes.getDataOutput(), countBytes);
+ private ClosedRecordConstructorEval recordEval;
+
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt64> longSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void init(DataOutput state) throws AlgebricksException {
+ try {
+ state.writeDouble(0.0);
+ state.writeLong(0);
+ state.writeBoolean(false);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple, byte[] state, int start, int len)
+ throws AlgebricksException {
+ double globalSum = BufferSerDeUtil.getDouble(state, start);
+ long globalCount = BufferSerDeUtil.getLong(state, start + 8);
+ boolean metNull = BufferSerDeUtil.getBoolean(state, start + 16);
+
+ inputVal.reset();
+ eval.evaluate(tuple);
+ byte[] serBytes = inputVal.getBytes();
+ if (serBytes[0] == SER_NULL_TYPE_TAG)
+ metNull = true;
+ if (serBytes[0] != SER_RECORD_TYPE_TAG) {
+ throw new AlgebricksException("Global-Avg is not defined for values of type "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serBytes[0]));
+ }
+ int offset1 = ARecordSerializerDeserializer.getFieldOffsetById(serBytes, 0, 1, true);
+ if (offset1 == 0) // the sum is null
+ metNull = true;
+ else
+ globalSum += ADoubleSerializerDeserializer.getDouble(serBytes, offset1);
+ int offset2 = ARecordSerializerDeserializer.getFieldOffsetById(serBytes, 1, 1, true);
+ if (offset2 != 0) // the count is not null
+ globalCount += AInt64SerializerDeserializer.getLong(serBytes, offset2);
+
+ BufferSerDeUtil.writeDouble(globalSum, state, start);
+ BufferSerDeUtil.writeLong(globalCount, state, start + 8);
+ BufferSerDeUtil.writeBoolean(metNull, state, start + 16);
+
+ }
+
+ @Override
+ public void finish(byte[] state, int start, int len, DataOutput result) throws AlgebricksException {
+ double globalSum = BufferSerDeUtil.getDouble(state, start);
+ long globalCount = BufferSerDeUtil.getLong(state, start + 8);
+ boolean metNull = BufferSerDeUtil.getBoolean(state, start + 16);
+
+ if (globalCount == 0) {
+ GlobalConfig.ASTERIX_LOGGER.fine("AVG aggregate ran over empty input.");
+ } else {
+ try {
+ if (metNull)
+ nullSerde.serialize(ANull.NULL, result);
+ else {
+ aDouble.setValue(globalSum / globalCount);
+ doubleSerde.serialize(aDouble, result);
+ }
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+ @Override
+ public void finishPartial(byte[] state, int start, int len, DataOutput result)
+ throws AlgebricksException {
+ double globalSum = BufferSerDeUtil.getDouble(state, start);
+ long globalCount = BufferSerDeUtil.getLong(state, start + 8);
+ boolean metNull = BufferSerDeUtil.getBoolean(state, start + 16);
+
+ if (recordEval == null)
+ recordEval = new ClosedRecordConstructorEval(recType,
+ new IEvaluator[] { evalSum, evalCount }, avgBytes, result);
+
+ if (globalCount == 0) {
+ GlobalConfig.ASTERIX_LOGGER.fine("AVG aggregate ran over empty input.");
+ } else {
+ try {
+ if (metNull) {
+ sumBytes.reset();
+ nullSerde.serialize(ANull.NULL, sumBytesOutput);
+ } else {
+ sumBytes.reset();
+ aDouble.setValue(globalSum);
+ doubleSerde.serialize(aDouble, sumBytesOutput);
+ }
+ countBytes.reset();
+ aInt64.setValue(globalCount);
+ longSerde.serialize(aInt64, countBytesOutput);
+ recordEval.evaluate(null);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableLocalAvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableLocalAvgAggregateDescriptor.java
new file mode 100644
index 0000000..09f68ac
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableLocalAvgAggregateDescriptor.java
@@ -0,0 +1,208 @@
+package edu.uci.ics.asterix.runtime.aggregates.serializable.std;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AInt64;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractSerializableAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.AccessibleByteArrayEval;
+import edu.uci.ics.asterix.runtime.evaluators.common.ClosedRecordConstructorEvalFactory.ClosedRecordConstructorEval;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SerializableLocalAvgAggregateDescriptor extends AbstractSerializableAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "local-avg-serial", 1, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public ISerializableAggregateFunctionFactory createAggregateFunctionFactory(IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ final IEvaluatorFactory[] evals = args;
+ List<IAType> unionList = new ArrayList<IAType>();
+ unionList.add(BuiltinType.ANULL);
+ unionList.add(BuiltinType.ADOUBLE);
+ final ARecordType recType = new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
+ new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT64 }, true);
+
+ return new ISerializableAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ public ISerializableAggregateFunction createAggregateFunction() throws AlgebricksException {
+ return new ISerializableAggregateFunction() {
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = evals[0].createEvaluator(inputVal);
+ private ClosedRecordConstructorEval recordEval;
+
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt64> int64Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ private ArrayBackedValueStorage avgBytes = new ArrayBackedValueStorage();
+ private ByteArrayAccessibleOutputStream sumBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput sumBytesOutput = new DataOutputStream(sumBytes);
+ private ByteArrayAccessibleOutputStream countBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput countBytesOutput = new DataOutputStream(countBytes);
+ private IEvaluator evalSum = new AccessibleByteArrayEval(avgBytes.getDataOutput(), sumBytes);
+ private IEvaluator evalCount = new AccessibleByteArrayEval(avgBytes.getDataOutput(), countBytes);
+
+ @Override
+ public void init(DataOutput state) throws AlgebricksException {
+ try {
+ state.writeDouble(0.0);
+ state.writeLong(0);
+ state.writeBoolean(false);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple, byte[] state, int start, int len)
+ throws AlgebricksException {
+ inputVal.reset();
+ eval.evaluate(tuple);
+ double sum = BufferSerDeUtil.getDouble(state, start);
+ long count = BufferSerDeUtil.getLong(state, start + 8);
+ boolean metNull = BufferSerDeUtil.getBoolean(state, start + 16);
+ if (inputVal.getLength() > 0) {
+ ++count;
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(inputVal.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ byte val = AInt8SerializerDeserializer.getByte(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT16: {
+ short val = AInt16SerializerDeserializer.getShort(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT32: {
+ int val = AInt32SerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT64: {
+ long val = AInt64SerializerDeserializer.getLong(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case FLOAT: {
+ float val = AFloatSerializerDeserializer.getFloat(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case DOUBLE: {
+ double val = ADoubleSerializerDeserializer.getDouble(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case NULL: {
+ metNull = true;
+ break;
+ }
+ default: {
+ throw new NotImplementedException("Cannot compute AVG for values of type "
+ + typeTag);
+ }
+ }
+ inputVal.reset();
+ }
+ BufferSerDeUtil.writeDouble(sum, state, start);
+ BufferSerDeUtil.writeLong(count, state, start + 8);
+ BufferSerDeUtil.writeBoolean(metNull, state, start + 16);
+ }
+
+ @Override
+ public void finish(byte[] state, int start, int len, DataOutput result) throws AlgebricksException {
+ double sum = BufferSerDeUtil.getDouble(state, start);
+ long count = BufferSerDeUtil.getLong(state, start + 8);
+ boolean metNull = BufferSerDeUtil.getBoolean(state, start + 16);
+ if (recordEval == null)
+ recordEval = new ClosedRecordConstructorEval(recType,
+ new IEvaluator[] { evalSum, evalCount }, avgBytes, result);
+ if (count == 0) {
+ if (GlobalConfig.DEBUG) {
+ GlobalConfig.ASTERIX_LOGGER.finest("AVG aggregate ran over empty input.");
+ }
+ } else {
+ try {
+ if (metNull) {
+ sumBytes.reset();
+ nullSerde.serialize(ANull.NULL, sumBytesOutput);
+ } else {
+ sumBytes.reset();
+ aDouble.setValue(sum);
+ doubleSerde.serialize(aDouble, sumBytesOutput);
+ }
+ countBytes.reset();
+ aInt64.setValue(count);
+ int64Serde.serialize(aInt64, countBytesOutput);
+ recordEval.evaluate(null);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+ @Override
+ public void finishPartial(byte[] state, int start, int len, DataOutput partialResult)
+ throws AlgebricksException {
+ finish(state, start, len, partialResult);
+ }
+
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableSumAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableSumAggregateDescriptor.java
new file mode 100644
index 0000000..ed4d728
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/serializable/std/SerializableSumAggregateDescriptor.java
@@ -0,0 +1,230 @@
+package edu.uci.ics.asterix.runtime.aggregates.serializable.std;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractSerializableAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SerializableSumAggregateDescriptor extends AbstractSerializableAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "sum-serial", 1,
+ true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public ISerializableAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new ISerializableAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public ISerializableAggregateFunction createAggregateFunction() throws AlgebricksException {
+
+ return new ISerializableAggregateFunction() {
+
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(inputVal);
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer serde;
+
+ @Override
+ public void init(DataOutput state) throws AlgebricksException {
+ try {
+ state.writeBoolean(false);
+ state.writeBoolean(false);
+ state.writeBoolean(false);
+ state.writeBoolean(false);
+ state.writeBoolean(false);
+ state.writeBoolean(false);
+ state.writeBoolean(false);
+ state.writeDouble(0.0);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple, byte[] state, int start, int len)
+ throws AlgebricksException {
+ int pos = start;
+ boolean metInt8s = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metInt16s = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metInt32s = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metInt64s = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metFloats = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metDoubles = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metNull = BufferSerDeUtil.getBoolean(state, pos++);
+ double sum = BufferSerDeUtil.getDouble(state, pos);
+
+ inputVal.reset();
+ eval.evaluate(tuple);
+ if (inputVal.getLength() > 0) {
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(inputVal.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ metInt8s = true;
+ byte val = AInt8SerializerDeserializer.getByte(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT16: {
+ metInt16s = true;
+ short val = AInt16SerializerDeserializer.getShort(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT32: {
+ metInt32s = true;
+ int val = AInt32SerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT64: {
+ metInt64s = true;
+ long val = AInt64SerializerDeserializer.getLong(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case FLOAT: {
+ metFloats = true;
+ float val = AFloatSerializerDeserializer.getFloat(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case DOUBLE: {
+ metDoubles = true;
+ double val = ADoubleSerializerDeserializer.getDouble(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case NULL: {
+ metNull = true;
+ break;
+ }
+ default: {
+ throw new NotImplementedException("Cannot compute SUM for values of type "
+ + typeTag);
+ }
+ }
+ }
+
+ pos = start;
+ BufferSerDeUtil.writeBoolean(metInt8s, state, pos++);
+ BufferSerDeUtil.writeBoolean(metInt16s, state, pos++);
+ BufferSerDeUtil.writeBoolean(metInt32s, state, pos++);
+ BufferSerDeUtil.writeBoolean(metInt64s, state, pos++);
+ BufferSerDeUtil.writeBoolean(metFloats, state, pos++);
+ BufferSerDeUtil.writeBoolean(metDoubles, state, pos++);
+ BufferSerDeUtil.writeBoolean(metNull, state, pos++);
+ BufferSerDeUtil.writeDouble(sum, state, pos);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void finish(byte[] state, int start, int len, DataOutput out) throws AlgebricksException {
+ int pos = start;
+ boolean metInt8s = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metInt16s = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metInt32s = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metInt64s = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metFloats = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metDoubles = BufferSerDeUtil.getBoolean(state, pos++);
+ boolean metNull = BufferSerDeUtil.getBoolean(state, pos++);
+ double sum = BufferSerDeUtil.getDouble(state, pos);
+ try {
+ if (metNull) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ } else if (metDoubles) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ aDouble.setValue(sum);
+ serde.serialize(aDouble, out);
+ } else if (metFloats) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ aFloat.setValue((float) sum);
+ serde.serialize(aFloat, out);
+ } else if (metInt64s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ aInt64.setValue((long) sum);
+ serde.serialize(aInt64, out);
+ } else if (metInt32s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ aInt32.setValue((int) sum);
+ serde.serialize(aInt32, out);
+ } else if (metInt16s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ aInt16.setValue((short) sum);
+ serde.serialize(aInt16, out);
+ } else if (metInt8s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ aInt8.setValue((byte) sum);
+ serde.serialize(aInt8, out);
+ } else {
+ GlobalConfig.ASTERIX_LOGGER.fine("SUM aggregate ran over empty input.");
+ }
+
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+
+ }
+
+ @Override
+ public void finishPartial(byte[] state, int start, int len, DataOutput out)
+ throws AlgebricksException {
+ finish(state, start, len, out);
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/AvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/AvgAggregateDescriptor.java
new file mode 100644
index 0000000..e548fb8
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/AvgAggregateDescriptor.java
@@ -0,0 +1,209 @@
+package edu.uci.ics.asterix.runtime.aggregates.std;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.AccessibleByteArrayEval;
+import edu.uci.ics.asterix.runtime.evaluators.common.ClosedRecordConstructorEvalFactory.ClosedRecordConstructorEval;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AvgAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-avg", 1,
+ true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ List<IAType> unionList = new ArrayList<IAType>();
+ unionList.add(BuiltinType.ANULL);
+ unionList.add(BuiltinType.ADOUBLE);
+ final ARecordType recType = new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
+ new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT32 }, true);
+
+ return new IAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IAggregateFunction createAggregateFunction(final IDataOutputProvider provider)
+ throws AlgebricksException {
+
+ return new IAggregateFunction() {
+
+ private DataOutput out = provider.getDataOutput();
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(inputVal);
+ private double sum;
+ private int count;
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+
+ private ArrayBackedValueStorage avgBytes = new ArrayBackedValueStorage();
+ private ByteArrayAccessibleOutputStream sumBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput sumBytesOutput = new DataOutputStream(sumBytes);
+ private ByteArrayAccessibleOutputStream countBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput countBytesOutput = new DataOutputStream(countBytes);
+ private IEvaluator evalSum = new AccessibleByteArrayEval(avgBytes.getDataOutput(), sumBytes);
+ private IEvaluator evalCount = new AccessibleByteArrayEval(avgBytes.getDataOutput(), countBytes);
+ private ClosedRecordConstructorEval recordEval = new ClosedRecordConstructorEval(recType,
+ new IEvaluator[] { evalSum, evalCount }, avgBytes, out);
+
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> intSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private boolean metNull;
+
+ @Override
+ public void init() throws AlgebricksException {
+ sum = 0.0;
+ count = 0;
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ inputVal.reset();
+ eval.evaluate(tuple);
+ if (inputVal.getLength() > 0) {
+ ++count;
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(inputVal.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ byte val = AInt8SerializerDeserializer.getByte(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT16: {
+ short val = AInt16SerializerDeserializer.getShort(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT32: {
+ int val = AInt32SerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT64: {
+ long val = AInt64SerializerDeserializer.getLong(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case FLOAT: {
+ float val = AFloatSerializerDeserializer.getFloat(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case DOUBLE: {
+ double val = ADoubleSerializerDeserializer.getDouble(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case NULL: {
+ metNull = true;
+ break;
+ }
+ default: {
+ throw new NotImplementedException("Cannot compute AVG for values of type "
+ + typeTag);
+ }
+ }
+ inputVal.reset();
+ }
+ }
+
+ @Override
+ public void finish() throws AlgebricksException {
+ if (count == 0) {
+ GlobalConfig.ASTERIX_LOGGER.fine("AVG aggregate ran over empty input.");
+ } else {
+ try {
+ if (metNull)
+ nullSerde.serialize(ANull.NULL, out);
+ else {
+ aDouble.setValue(sum / count);
+ doubleSerde.serialize(aDouble, out);
+ }
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+ @Override
+ public void finishPartial() throws AlgebricksException {
+ if (count == 0) {
+ if (GlobalConfig.DEBUG) {
+ GlobalConfig.ASTERIX_LOGGER.finest("AVG aggregate ran over empty input.");
+ }
+ } else {
+ try {
+ if (metNull) {
+ sumBytes.reset();
+ nullSerde.serialize(ANull.NULL, sumBytesOutput);
+ } else {
+ sumBytes.reset();
+ aDouble.setValue(sum);
+ doubleSerde.serialize(aDouble, sumBytesOutput);
+ }
+ countBytes.reset();
+ aInt32.setValue(count);
+ intSerde.serialize(aInt32, countBytesOutput);
+ recordEval.evaluate(null);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/CountAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/CountAggregateDescriptor.java
new file mode 100644
index 0000000..39c7910
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/CountAggregateDescriptor.java
@@ -0,0 +1,83 @@
+package edu.uci.ics.asterix.runtime.aggregates.std;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+/**
+ * NULLs are also counted.
+ */
+public class CountAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-count", 1,
+ true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IAggregateFunctionFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IAggregateFunction createAggregateFunction(IDataOutputProvider provider) throws AlgebricksException {
+
+ final DataOutput out = provider.getDataOutput();
+
+ return new IAggregateFunction() {
+ private AMutableInt32 result = new AMutableInt32(-1);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ private int cnt;
+
+ @Override
+ public void init() {
+ cnt = 0;
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ cnt++;
+ }
+
+ @Override
+ public void finish() throws AlgebricksException {
+ try {
+ result.setValue(cnt);
+ int32Serde.serialize(result, out);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void finishPartial() throws AlgebricksException {
+ finish();
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java
new file mode 100644
index 0000000..dee94ec
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java
@@ -0,0 +1,176 @@
+package edu.uci.ics.asterix.runtime.aggregates.std;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARecordSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.AccessibleByteArrayEval;
+import edu.uci.ics.asterix.runtime.evaluators.common.ClosedRecordConstructorEvalFactory.ClosedRecordConstructorEval;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class GlobalAvgAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-global-avg",
+ 1, true);
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static byte SER_RECORD_TYPE_TAG = ATypeTag.RECORD.serialize();
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ List<IAType> unionList = new ArrayList<IAType>();
+ unionList.add(BuiltinType.ANULL);
+ unionList.add(BuiltinType.ADOUBLE);
+ final ARecordType recType = new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
+ new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT32 }, false);
+
+ return new IAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IAggregateFunction createAggregateFunction(final IDataOutputProvider provider)
+ throws AlgebricksException {
+
+ return new IAggregateFunction() {
+
+ private DataOutput out = provider.getDataOutput();
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(inputVal);
+ private double globalSum;
+ private int globalCount;
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+
+ private ArrayBackedValueStorage avgBytes = new ArrayBackedValueStorage();
+ private ByteArrayAccessibleOutputStream sumBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput sumBytesOutput = new DataOutputStream(sumBytes);
+ private ByteArrayAccessibleOutputStream countBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput countBytesOutput = new DataOutputStream(countBytes);
+ private IEvaluator evalSum = new AccessibleByteArrayEval(avgBytes.getDataOutput(), sumBytes);
+ private IEvaluator evalCount = new AccessibleByteArrayEval(avgBytes.getDataOutput(), countBytes);
+ private ClosedRecordConstructorEval recordEval = new ClosedRecordConstructorEval(recType,
+ new IEvaluator[] { evalSum, evalCount }, avgBytes, out);
+
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> intSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private boolean metNull;
+
+ @Override
+ public void init() {
+ globalSum = 0.0;
+ globalCount = 0;
+ metNull = false;
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ inputVal.reset();
+ eval.evaluate(tuple);
+ byte[] serBytes = inputVal.getBytes();
+ if (serBytes[0] == SER_NULL_TYPE_TAG)
+ metNull = true;
+ if (serBytes[0] != SER_RECORD_TYPE_TAG) {
+ throw new AlgebricksException("Global-Avg is not defined for values of type "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serBytes[0]));
+ }
+ int offset1 = ARecordSerializerDeserializer.getFieldOffsetById(serBytes, 0, 1, false);
+ if (offset1 == 0) // the sum is null
+ metNull = true;
+ else
+ globalSum += ADoubleSerializerDeserializer.getDouble(serBytes, offset1);
+ int offset2 = ARecordSerializerDeserializer.getFieldOffsetById(serBytes, 1, 1, false);
+ if (offset2 != 0) // the count is not null
+ globalCount += AInt32SerializerDeserializer.getInt(serBytes, offset2);
+
+ }
+
+ @Override
+ public void finish() throws AlgebricksException {
+ if (globalCount == 0) {
+ GlobalConfig.ASTERIX_LOGGER.fine("AVG aggregate ran over empty input.");
+ } else {
+ try {
+ if (metNull)
+ nullSerde.serialize(ANull.NULL, out);
+ else {
+ aDouble.setValue(globalSum / globalCount);
+ doubleSerde.serialize(aDouble, out);
+ }
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+ @Override
+ public void finishPartial() throws AlgebricksException {
+ if (globalCount == 0) {
+ GlobalConfig.ASTERIX_LOGGER.fine("AVG aggregate ran over empty input.");
+ } else {
+ try {
+ if (metNull) {
+ sumBytes.reset();
+ nullSerde.serialize(ANull.NULL, sumBytesOutput);
+ } else {
+ sumBytes.reset();
+ aDouble.setValue(globalSum);
+ doubleSerde.serialize(aDouble, sumBytesOutput);
+ }
+ countBytes.reset();
+ aInt32.setValue(globalCount);
+ intSerde.serialize(aInt32, countBytesOutput);
+ recordEval.evaluate(null);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/LocalAvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/LocalAvgAggregateDescriptor.java
new file mode 100644
index 0000000..50debf6
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/LocalAvgAggregateDescriptor.java
@@ -0,0 +1,197 @@
+package edu.uci.ics.asterix.runtime.aggregates.std;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.AccessibleByteArrayEval;
+import edu.uci.ics.asterix.runtime.evaluators.common.ClosedRecordConstructorEvalFactory.ClosedRecordConstructorEval;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class LocalAvgAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-local-avg",
+ 1, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+
+ return new IAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IAggregateFunction createAggregateFunction(final IDataOutputProvider provider)
+ throws AlgebricksException {
+
+ List<IAType> unionList = new ArrayList<IAType>();
+ unionList.add(BuiltinType.ANULL);
+ unionList.add(BuiltinType.ADOUBLE);
+ final ARecordType recType = new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
+ new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT32 }, false);
+
+ return new IAggregateFunction() {
+
+ private DataOutput out = provider.getDataOutput();
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(inputVal);
+ private double sum;
+ private int count;
+
+ private ArrayBackedValueStorage avgBytes = new ArrayBackedValueStorage();
+ private ByteArrayAccessibleOutputStream sumBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput sumBytesOutput = new DataOutputStream(sumBytes);
+ private ByteArrayAccessibleOutputStream countBytes = new ByteArrayAccessibleOutputStream();
+ private DataOutput countBytesOutput = new DataOutputStream(countBytes);
+ private IEvaluator evalSum = new AccessibleByteArrayEval(avgBytes.getDataOutput(), sumBytes);
+ private IEvaluator evalCount = new AccessibleByteArrayEval(avgBytes.getDataOutput(), countBytes);
+ private ClosedRecordConstructorEval recordEval = new ClosedRecordConstructorEval(recType,
+ new IEvaluator[] { evalSum, evalCount }, avgBytes, out);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private boolean metNull;
+
+ @Override
+ public void init() {
+ sum = 0.0;
+ count = 0;
+ metNull = false;
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ inputVal.reset();
+ eval.evaluate(tuple);
+ if (inputVal.getLength() > 0) {
+ ++count;
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(inputVal.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ byte val = AInt8SerializerDeserializer.getByte(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT16: {
+ short val = AInt16SerializerDeserializer.getShort(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT32: {
+ int val = AInt32SerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT64: {
+ long val = AInt64SerializerDeserializer.getLong(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case FLOAT: {
+ float val = AFloatSerializerDeserializer.getFloat(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case DOUBLE: {
+ double val = ADoubleSerializerDeserializer.getDouble(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case NULL: {
+ metNull = true;
+ break;
+ }
+ default: {
+ throw new NotImplementedException("Cannot compute LOCAL-AVG for values of type "
+ + typeTag);
+ }
+ }
+ inputVal.reset();
+ }
+ }
+
+ @Override
+ public void finish() throws AlgebricksException {
+ if (count == 0) {
+ if (GlobalConfig.DEBUG) {
+ GlobalConfig.ASTERIX_LOGGER.finest("AVG aggregate ran over empty input.");
+ }
+ } else {
+ try {
+ if (metNull) {
+ sumBytes.reset();
+ nullSerde.serialize(ANull.NULL, sumBytesOutput);
+ } else {
+ sumBytes.reset();
+ aDouble.setValue(sum);
+ doubleSerde.serialize(aDouble, sumBytesOutput);
+ }
+ countBytes.reset();
+ aInt32.setValue(count);
+ int32Serde.serialize(aInt32, countBytesOutput);
+ recordEval.evaluate(null);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+ @Override
+ public void finishPartial() throws AlgebricksException {
+ finish();
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java
new file mode 100644
index 0000000..cf4cb4c
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java
@@ -0,0 +1,206 @@
+package edu.uci.ics.asterix.runtime.aggregates.std;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class MaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-max", 1,
+ true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public IAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IAggregateFunction createAggregateFunction(final IDataOutputProvider provider)
+ throws AlgebricksException {
+
+ return new IAggregateFunction() {
+
+ private DataOutput out = provider.getDataOutput();
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(inputVal);
+ private boolean metInt8s, metInt16s, metInt32s, metInt64s, metFloats, metDoubles, metNull;
+
+ private short shortVal = Short.MIN_VALUE;
+ private int intVal = Integer.MIN_VALUE;
+ private long longVal = Long.MIN_VALUE;
+ private float floatVal = Float.MIN_VALUE;
+ private double doubleVal = Double.MIN_VALUE;
+
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private ISerializerDeserializer serde;
+
+ @Override
+ public void init() {
+ shortVal = Short.MIN_VALUE;
+ intVal = Integer.MIN_VALUE;
+ longVal = Long.MIN_VALUE;
+ floatVal = Float.MIN_VALUE;
+ doubleVal = Double.MIN_VALUE;
+
+ metInt8s = false;
+ metInt16s = false;
+ metInt32s = false;
+ metInt64s = false;
+ metFloats = false;
+ metDoubles = false;
+ metNull = false;
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ inputVal.reset();
+ eval.evaluate(tuple);
+ if (inputVal.getLength() > 0) {
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(inputVal.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ metInt8s = true;
+ throw new NotImplementedException("no implementation for int8's comparator");
+ }
+ case INT16: {
+ metInt16s = true;
+ short val = AInt16SerializerDeserializer.getShort(inputVal.getBytes(), 1);
+ if (val > shortVal)
+ shortVal = val;
+ throw new NotImplementedException("no implementation for int16's comparator");
+ }
+ case INT32: {
+ metInt32s = true;
+ int val = AInt32SerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ if (val > intVal)
+ intVal = val;
+ break;
+ }
+ case INT64: {
+ metInt64s = true;
+ long val = AInt64SerializerDeserializer.getLong(inputVal.getBytes(), 1);
+ if (val > longVal)
+ longVal = val;
+ break;
+ }
+ case FLOAT: {
+ metFloats = true;
+ float val = AFloatSerializerDeserializer.getFloat(inputVal.getBytes(), 1);
+ if (val > floatVal)
+ floatVal = val;
+ break;
+ }
+ case DOUBLE: {
+ metDoubles = true;
+ double val = ADoubleSerializerDeserializer.getDouble(inputVal.getBytes(), 1);
+ if (val > doubleVal)
+ doubleVal = val;
+ break;
+ }
+ case NULL: {
+ metNull = true;
+ break;
+ }
+ default: {
+ throw new NotImplementedException("Cannot compute SUM for values of type "
+ + typeTag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void finish() throws AlgebricksException {
+ try {
+ if (metNull) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ } else if (metDoubles) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ aDouble.setValue(doubleVal);
+ serde.serialize(aDouble, out);
+ } else if (metFloats) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ aFloat.setValue(floatVal);
+ serde.serialize(aFloat, out);
+ } else if (metInt64s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ aInt64.setValue(longVal);
+ serde.serialize(aInt64, out);
+ } else if (metInt32s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ aInt32.setValue(intVal);
+ serde.serialize(aInt32, out);
+ } else if (metInt16s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ aInt16.setValue(shortVal);
+ serde.serialize(aInt16, out);
+ } else if (metInt8s) {
+ throw new NotImplementedException("no implementation for int8's comparator");
+ } else {
+ GlobalConfig.ASTERIX_LOGGER.fine("SUM aggregate ran over empty input.");
+ }
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+
+ }
+
+ @Override
+ public void finishPartial() throws AlgebricksException {
+ finish();
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MinAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MinAggregateDescriptor.java
new file mode 100644
index 0000000..8ef204b
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/MinAggregateDescriptor.java
@@ -0,0 +1,206 @@
+package edu.uci.ics.asterix.runtime.aggregates.std;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class MinAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-min", 1,
+ true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public IAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IAggregateFunction createAggregateFunction(final IDataOutputProvider provider)
+ throws AlgebricksException {
+
+ return new IAggregateFunction() {
+
+ private DataOutput out = provider.getDataOutput();
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(inputVal);
+ private boolean metInt8s, metInt16s, metInt32s, metInt64s, metFloats, metDoubles, metNull;
+
+ private short shortVal = Short.MAX_VALUE;
+ private int intVal = Integer.MAX_VALUE;
+ private long longVal = Long.MAX_VALUE;
+ private float floatVal = Float.MAX_VALUE;
+ private double doubleVal = Double.MAX_VALUE;
+
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private ISerializerDeserializer serde;
+
+ @Override
+ public void init() {
+ shortVal = Short.MAX_VALUE;
+ intVal = Integer.MAX_VALUE;
+ longVal = Long.MAX_VALUE;
+ floatVal = Float.MAX_VALUE;
+ doubleVal = Double.MAX_VALUE;
+
+ metInt8s = false;
+ metInt16s = false;
+ metInt32s = false;
+ metInt64s = false;
+ metFloats = false;
+ metDoubles = false;
+ metNull = false;
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ inputVal.reset();
+ eval.evaluate(tuple);
+ if (inputVal.getLength() > 0) {
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(inputVal.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ metInt8s = true;
+ throw new NotImplementedException("no implementation for int8's comparator");
+ }
+ case INT16: {
+ metInt16s = true;
+ short val = AInt16SerializerDeserializer.getShort(inputVal.getBytes(), 1);
+ if (val < shortVal)
+ shortVal = val;
+ throw new NotImplementedException("no implementation for int16's comparator");
+ }
+ case INT32: {
+ metInt32s = true;
+ int val = AInt32SerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ if (val < intVal)
+ intVal = val;
+ break;
+ }
+ case INT64: {
+ metInt64s = true;
+ long val = AInt64SerializerDeserializer.getLong(inputVal.getBytes(), 1);
+ if (val < longVal)
+ longVal = val;
+ break;
+ }
+ case FLOAT: {
+ metFloats = true;
+ float val = AFloatSerializerDeserializer.getFloat(inputVal.getBytes(), 1);
+ if (val < floatVal)
+ floatVal = val;
+ break;
+ }
+ case DOUBLE: {
+ metDoubles = true;
+ double val = ADoubleSerializerDeserializer.getDouble(inputVal.getBytes(), 1);
+ if (val < doubleVal)
+ doubleVal = val;
+ break;
+ }
+ case NULL: {
+ metNull = true;
+ break;
+ }
+ default: {
+ throw new NotImplementedException("Cannot compute SUM for values of type "
+ + typeTag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void finish() throws AlgebricksException {
+ try {
+ if (metNull) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ } else if (metDoubles) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ aDouble.setValue(doubleVal);
+ serde.serialize(aDouble, out);
+ } else if (metFloats) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ aFloat.setValue(floatVal);
+ serde.serialize(aFloat, out);
+ } else if (metInt64s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ aInt64.setValue(longVal);
+ serde.serialize(aInt64, out);
+ } else if (metInt32s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ aInt32.setValue(intVal);
+ serde.serialize(aInt32, out);
+ } else if (metInt16s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ aInt16.setValue(shortVal);
+ serde.serialize(aInt16, out);
+ } else if (metInt8s) {
+ throw new NotImplementedException("no implementation for int8's comparator");
+ } else {
+ GlobalConfig.ASTERIX_LOGGER.fine("SUM aggregate ran over empty input.");
+ }
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+
+ }
+
+ @Override
+ public void finishPartial() throws AlgebricksException {
+ finish();
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/SumAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/SumAggregateDescriptor.java
new file mode 100644
index 0000000..e60c4e9
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/SumAggregateDescriptor.java
@@ -0,0 +1,199 @@
+package edu.uci.ics.asterix.runtime.aggregates.std;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SumAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-sum", 1,
+ true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public IAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IAggregateFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IAggregateFunction createAggregateFunction(final IDataOutputProvider provider)
+ throws AlgebricksException {
+
+ return new IAggregateFunction() {
+
+ private DataOutput out = provider.getDataOutput();
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(inputVal);
+ private boolean metInt8s, metInt16s, metInt32s, metInt64s, metFloats, metDoubles, metNull;
+ private double sum;
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ private ISerializerDeserializer serde;
+
+ @Override
+ public void init() {
+ metInt8s = false;
+ metInt16s = false;
+ metInt32s = false;
+ metInt64s = false;
+ metFloats = false;
+ metDoubles = false;
+ metNull = false;
+ sum = 0.0;
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ inputVal.reset();
+ eval.evaluate(tuple);
+ if (inputVal.getLength() > 0) {
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(inputVal.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ metInt8s = true;
+ byte val = AInt8SerializerDeserializer.getByte(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT16: {
+ metInt16s = true;
+ short val = AInt16SerializerDeserializer.getShort(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT32: {
+ metInt32s = true;
+ int val = AInt32SerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case INT64: {
+ metInt64s = true;
+ long val = AInt64SerializerDeserializer.getLong(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case FLOAT: {
+ metFloats = true;
+ float val = AFloatSerializerDeserializer.getFloat(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case DOUBLE: {
+ metDoubles = true;
+ double val = ADoubleSerializerDeserializer.getDouble(inputVal.getBytes(), 1);
+ sum += val;
+ break;
+ }
+ case NULL: {
+ metNull = true;
+ break;
+ }
+ default: {
+ throw new NotImplementedException("Cannot compute SUM for values of type "
+ + typeTag);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void finish() throws AlgebricksException {
+ try {
+ if (metNull) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ } else if (metDoubles) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ aDouble.setValue(sum);
+ serde.serialize(aDouble, out);
+ } else if (metFloats) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ aFloat.setValue((float) sum);
+ serde.serialize(aFloat, out);
+ } else if (metInt64s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ aInt64.setValue((long) sum);
+ serde.serialize(aInt64, out);
+ } else if (metInt32s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ aInt32.setValue((int) sum);
+ serde.serialize(aInt32, out);
+ } else if (metInt16s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ aInt16.setValue((short) sum);
+ serde.serialize(aInt16, out);
+ } else if (metInt8s) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ aInt8.setValue((byte) sum);
+ serde.serialize(aInt8, out);
+ } else {
+ GlobalConfig.ASTERIX_LOGGER.fine("SUM aggregate ran over empty input.");
+ }
+
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+
+ }
+
+ @Override
+ public void finishPartial() throws AlgebricksException {
+ finish();
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/stream/NonEmptyStreamAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/stream/NonEmptyStreamAggregateDescriptor.java
new file mode 100644
index 0000000..0200a47
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/stream/NonEmptyStreamAggregateDescriptor.java
@@ -0,0 +1,82 @@
+package edu.uci.ics.asterix.runtime.aggregates.stream;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class NonEmptyStreamAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "non-empty-stream", 0, true);
+
+ @Override
+ public IAggregateFunctionFactory createAggregateFunctionFactory(IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IAggregateFunctionFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IAggregateFunction createAggregateFunction(final IDataOutputProvider provider)
+ throws AlgebricksException {
+
+ return new IAggregateFunction() {
+
+ private DataOutput out = provider.getDataOutput();
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+
+ boolean res = false;
+
+ @Override
+ public void init() throws AlgebricksException {
+ res = false;
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ res = true;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void finish() throws AlgebricksException {
+ ABoolean b = res ? ABoolean.TRUE : ABoolean.FALSE;
+ try {
+ serde.serialize(b, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void finishPartial() throws AlgebricksException {
+ finish();
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IAggregateFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IAggregateFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..afa2312
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IAggregateFunctionDynamicDescriptor.java
@@ -0,0 +1,11 @@
+package edu.uci.ics.asterix.runtime.base;
+
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+
+public interface IAggregateFunctionDynamicDescriptor extends IFunctionDescriptor {
+ public IAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IRunningAggregateFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IRunningAggregateFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..ff01c60
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IRunningAggregateFunctionDynamicDescriptor.java
@@ -0,0 +1,12 @@
+package edu.uci.ics.asterix.runtime.base;
+
+
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IRunningAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+
+public interface IRunningAggregateFunctionDynamicDescriptor extends IFunctionDescriptor {
+ public IRunningAggregateFunctionFactory createRunningAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IScalarFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IScalarFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..ed5c0aee2
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IScalarFunctionDynamicDescriptor.java
@@ -0,0 +1,10 @@
+package edu.uci.ics.asterix.runtime.base;
+
+
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+
+public interface IScalarFunctionDynamicDescriptor extends IFunctionDescriptor {
+ public IEvaluatorFactory createEvaluatorFactory(IEvaluatorFactory[] args) throws AlgebricksException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/ISerializableAggregateFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/ISerializableAggregateFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..82e0e29
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/ISerializableAggregateFunctionDynamicDescriptor.java
@@ -0,0 +1,11 @@
+package edu.uci.ics.asterix.runtime.base;
+
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.ISerializableAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+
+public interface ISerializableAggregateFunctionDynamicDescriptor extends IFunctionDescriptor {
+ public ISerializableAggregateFunctionFactory createAggregateFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IUnnestingFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IUnnestingFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..85b6fe1
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/base/IUnnestingFunctionDynamicDescriptor.java
@@ -0,0 +1,11 @@
+package edu.uci.ics.asterix.runtime.base;
+
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IUnnestingFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+
+public interface IUnnestingFunctionDynamicDescriptor extends IFunctionDescriptor {
+ public IUnnestingFunctionFactory createUnnestingFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/base/AbstractScalarFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/base/AbstractScalarFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..06aa928
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/base/AbstractScalarFunctionDynamicDescriptor.java
@@ -0,0 +1,15 @@
+package edu.uci.ics.asterix.runtime.evaluators.base;
+
+import edu.uci.ics.asterix.common.functions.FunctionDescriptorTag;
+import edu.uci.ics.asterix.runtime.base.IScalarFunctionDynamicDescriptor;
+
+public abstract class AbstractScalarFunctionDynamicDescriptor implements IScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public FunctionDescriptorTag getFunctionDescriptorTag() {
+ return FunctionDescriptorTag.SCALAR;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AbstractAsterixListIterator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AbstractAsterixListIterator.java
new file mode 100644
index 0000000..0b9aca8
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AbstractAsterixListIterator.java
@@ -0,0 +1,93 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.fuzzyjoin.similarity.IListIterator;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+
+public abstract class AbstractAsterixListIterator implements IListIterator {
+
+ protected byte[] data;
+ protected int count = 0;
+ protected int pos = -1;
+ protected int size = -1;
+ protected int startOff = -1;
+ protected IBinaryComparator cmp;
+
+ @Override
+ public int compare(IListIterator cmpIter) {
+ return cmp.compare(data, pos, -1, cmpIter.getData(), cmpIter.getPos(), -1);
+ }
+
+ @Override
+ public boolean hasNext() {
+ return count < size;
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public byte[] getData() {
+ return data;
+ }
+
+ @Override
+ public int getPos() {
+ return pos;
+ }
+
+ @Override
+ public void next() {
+ try {
+ pos = getItemOffset(data, startOff, ++count);
+ } catch (AsterixException e) {
+ throw new AsterixRuntimeException(e);
+ }
+ }
+
+ @Override
+ public void reset() {
+ count = 0;
+ try {
+ pos = getItemOffset(data, startOff, count);
+ } catch (AsterixException e) {
+ throw new AsterixRuntimeException(e);
+ }
+ }
+
+ public void reset(byte[] data, int startOff) {
+ this.data = data;
+ this.startOff = startOff;
+ size = getNumberOfItems(data, startOff);
+ ATypeTag tag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(data[startOff + 1]);
+ switch (tag) {
+ case INT32: {
+ cmp = AqlBinaryComparatorFactoryProvider.INTEGER_POINTABLE_INSTANCE.createBinaryComparator();
+ break;
+ }
+ case FLOAT: {
+ cmp = AqlBinaryComparatorFactoryProvider.FLOAT_POINTABLE_INSTANCE.createBinaryComparator();
+ break;
+ }
+ case DOUBLE: {
+ cmp = AqlBinaryComparatorFactoryProvider.DOUBLE_POINTABLE_INSTANCE.createBinaryComparator();
+ break;
+ }
+ case STRING: {
+ cmp = AqlBinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE.createBinaryComparator();
+ break;
+ }
+ }
+ reset();
+ }
+
+ protected abstract int getItemOffset(byte[] serOrderedList, int offset, int itemIndex) throws AsterixException;
+
+ protected abstract int getNumberOfItems(byte[] serOrderedList, int offset);
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AccessibleByteArrayEval.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AccessibleByteArrayEval.java
new file mode 100644
index 0000000..4a769ba
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AccessibleByteArrayEval.java
@@ -0,0 +1,54 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AccessibleByteArrayEval implements IEvaluator {
+
+ private DataOutput out;
+ private ByteArrayAccessibleOutputStream baaos;
+ private DataOutput dataOutput;
+
+ public AccessibleByteArrayEval(DataOutput out) {
+ this.out = out;
+ this.baaos = new ByteArrayAccessibleOutputStream();
+ this.dataOutput = new DataOutputStream(baaos);
+ }
+
+ public AccessibleByteArrayEval(DataOutput out, ByteArrayAccessibleOutputStream baaos) {
+ this.out = out;
+ this.baaos = baaos;
+ this.dataOutput = new DataOutputStream(baaos);
+ }
+
+ public DataOutput getDataOutput() {
+ return dataOutput;
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ out.write(baaos.getByteArray(), 0, baaos.size());
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ public void setBaaos(ByteArrayAccessibleOutputStream baaos) {
+ this.baaos = baaos;
+ }
+
+ public ByteArrayAccessibleOutputStream getBaaos() {
+ return baaos;
+ }
+
+ public void reset() {
+ baaos.reset();
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixOrderedListIterator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixOrderedListIterator.java
new file mode 100644
index 0000000..d3714c1
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixOrderedListIterator.java
@@ -0,0 +1,17 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+
+public final class AsterixOrderedListIterator extends AbstractAsterixListIterator {
+
+ @Override
+ protected int getItemOffset(byte[] serOrderedList, int offset, int itemIndex) throws AsterixException {
+ return AOrderedListSerializerDeserializer.getItemOffset(serOrderedList, offset, itemIndex);
+ }
+
+ @Override
+ protected int getNumberOfItems(byte[] serOrderedList, int offset) {
+ return AOrderedListSerializerDeserializer.getNumberOfItems(serOrderedList, offset);
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixUnorderedListIterator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixUnorderedListIterator.java
new file mode 100644
index 0000000..de7742b
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixUnorderedListIterator.java
@@ -0,0 +1,17 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AUnorderedListSerializerDeserializer;
+
+public final class AsterixUnorderedListIterator extends AbstractAsterixListIterator {
+
+ @Override
+ protected int getItemOffset(byte[] serOrderedList, int offset, int itemIndex) throws AsterixException {
+ return AUnorderedListSerializerDeserializer.getItemOffset(serOrderedList, offset, itemIndex);
+ }
+
+ @Override
+ protected int getNumberOfItems(byte[] serOrderedList, int offset) {
+ return AUnorderedListSerializerDeserializer.getNumberOfItems(serOrderedList, offset);
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/ClosedRecordConstructorEvalFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/ClosedRecordConstructorEvalFactory.java
new file mode 100644
index 0000000..324fd7a
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/ClosedRecordConstructorEvalFactory.java
@@ -0,0 +1,81 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.IARecordBuilder;
+import edu.uci.ics.asterix.builders.RecordBuilder;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ClosedRecordConstructorEvalFactory implements IEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ private IEvaluatorFactory[] args;
+ private ARecordType recType;
+
+ public ClosedRecordConstructorEvalFactory(IEvaluatorFactory[] args, ARecordType recType) {
+ this.args = args;
+ this.recType = recType;
+ }
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ int n = args.length / 2;
+ IEvaluator[] evalFields = new IEvaluator[n];
+ ArrayBackedValueStorage fieldValueBuffer = new ArrayBackedValueStorage();
+ for (int i = 0; i < n; i++) {
+ evalFields[i] = args[2 * i + 1].createEvaluator(fieldValueBuffer);
+ }
+ DataOutput out = output.getDataOutput();
+ return new ClosedRecordConstructorEval(recType, evalFields, fieldValueBuffer, out);
+ }
+
+ public static class ClosedRecordConstructorEval implements IEvaluator {
+
+ private IEvaluator[] evalFields;
+ private DataOutput out;
+ private IARecordBuilder recBuilder = new RecordBuilder();
+ private ARecordType recType;
+ private ArrayBackedValueStorage fieldValueBuffer = new ArrayBackedValueStorage();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private boolean first = true;
+
+ public ClosedRecordConstructorEval(ARecordType recType, IEvaluator[] evalFields,
+ ArrayBackedValueStorage fieldValueBuffer, DataOutput out) {
+ this.evalFields = evalFields;
+ this.fieldValueBuffer = fieldValueBuffer;
+ this.out = out;
+ this.recType = recType;
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ if (first) {
+ first = false;
+ recBuilder.reset(this.recType);
+ }
+ recBuilder.init();
+ for (int i = 0; i < evalFields.length; i++) {
+ fieldValueBuffer.reset();
+ evalFields[i].evaluate(tuple);
+ if (fieldValueBuffer.getBytes()[0] != SER_NULL_TYPE_TAG) {
+ recBuilder.addField(i, fieldValueBuffer);
+ }
+ }
+ recBuilder.write(out, true);
+ } catch (IOException ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/CreateMBREvalFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/CreateMBREvalFactory.java
new file mode 100644
index 0000000..a83cf68
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/CreateMBREvalFactory.java
@@ -0,0 +1,304 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.Coordinate;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ACircleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ALineSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APolygonSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARectangleSerializerDeserializer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class CreateMBREvalFactory implements IEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ private IEvaluatorFactory recordEvalFactory;
+ private IEvaluatorFactory dimensionEvalFactory;
+ private IEvaluatorFactory coordinateEvalFactory;
+
+ public CreateMBREvalFactory(IEvaluatorFactory recordEvalFactory, IEvaluatorFactory dimensionEvalFactory,
+ IEvaluatorFactory coordinateEvalFactory) {
+ this.recordEvalFactory = recordEvalFactory;
+ this.dimensionEvalFactory = dimensionEvalFactory;
+ this.coordinateEvalFactory = coordinateEvalFactory;
+ }
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput2 = new ArrayBackedValueStorage();
+
+ private IEvaluator eval0 = recordEvalFactory.createEvaluator(outInput0);
+ private IEvaluator eval1 = dimensionEvalFactory.createEvaluator(outInput1);
+ private IEvaluator eval2 = coordinateEvalFactory.createEvaluator(outInput2);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+ outInput2.reset();
+ eval2.evaluate(tuple);
+
+ try {
+
+ int dimension = AInt32SerializerDeserializer.getInt(outInput1.getBytes(), 1);
+ int coordinate = AInt32SerializerDeserializer.getInt(outInput2.getBytes(), 1);
+ double value;
+ if (dimension == 2) {
+ ATypeTag tag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(outInput0.getBytes()[0]);
+ switch (tag) {
+ case POINT:
+ switch (coordinate) {
+ case 0: // 0 is for min x, 1 is for min y, 2
+ // for
+ // max x, and 3 for max y
+ case 2: {
+ double x = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
+
+ value = x;
+ }
+ break;
+ case 1:
+ case 3: {
+ double y = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));
+
+ value = y;
+ }
+ break;
+ default: {
+ throw new NotImplementedException(coordinate
+ + " is not a valid coordinate option");
+ }
+ }
+ break;
+ case LINE:
+ value = Double.MAX_VALUE;
+ switch (coordinate) {
+ case 0: {
+ value = Double.MAX_VALUE;
+ double startX = ADoubleSerializerDeserializer
+ .getDouble(outInput0.getBytes(), ALineSerializerDeserializer
+ .getStartPointCoordinateOffset(Coordinate.X));
+ double endX = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.X));
+
+ value = Math.min(Math.min(startX, endX), value);
+ }
+ break;
+ case 1: {
+ value = Double.MAX_VALUE;
+ double startY = ADoubleSerializerDeserializer
+ .getDouble(outInput0.getBytes(), ALineSerializerDeserializer
+ .getStartPointCoordinateOffset(Coordinate.Y));
+ double endY = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.Y));
+
+ value = Math.min(Math.min(startY, endY), value);
+ }
+ break;
+ case 2: {
+ value = Double.MIN_VALUE;
+ double startX = ADoubleSerializerDeserializer
+ .getDouble(outInput0.getBytes(), ALineSerializerDeserializer
+ .getStartPointCoordinateOffset(Coordinate.X));
+ double endX = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.X));
+
+ value = Math.max(Math.min(startX, endX), value);
+ }
+ break;
+ case 3: {
+ value = Double.MIN_VALUE;
+ double startY = ADoubleSerializerDeserializer
+ .getDouble(outInput0.getBytes(), ALineSerializerDeserializer
+ .getStartPointCoordinateOffset(Coordinate.Y));
+ double endY = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.Y));
+
+ value = Math.max(Math.min(startY, endY), value);
+ }
+ break;
+ default: {
+ throw new NotImplementedException(coordinate
+ + " is not a valid coordinate option");
+ }
+ }
+ break;
+ case POLYGON:
+ int numOfPoints = AInt16SerializerDeserializer.getShort(outInput0.getBytes(),
+ APolygonSerializerDeserializer.getNumberOfPointsOffset());
+ switch (coordinate) {
+ case 0: {
+ value = Double.MAX_VALUE;
+ for (int i = 0; i < numOfPoints; i++) {
+ double x = ADoubleSerializerDeserializer
+ .getDouble(outInput0.getBytes(), APolygonSerializerDeserializer
+ .getCoordinateOffset(i, Coordinate.X));
+ value = Math.min(x, value);
+ }
+ }
+ break;
+ case 1: {
+ value = Double.MAX_VALUE;
+ for (int i = 0; i < numOfPoints; i++) {
+ double y = ADoubleSerializerDeserializer
+ .getDouble(outInput0.getBytes(), APolygonSerializerDeserializer
+ .getCoordinateOffset(i, Coordinate.Y));
+ value = Math.min(y, value);
+ }
+ }
+ break;
+ case 2: {
+ value = Double.MIN_VALUE;
+ for (int i = 0; i < numOfPoints; i++) {
+ double x = ADoubleSerializerDeserializer
+ .getDouble(outInput0.getBytes(), APolygonSerializerDeserializer
+ .getCoordinateOffset(i, Coordinate.X));
+ value = Math.max(x, value);
+ }
+ }
+ break;
+ case 3: {
+ value = Double.MIN_VALUE;
+ for (int i = 0; i < numOfPoints; i++) {
+ double y = ADoubleSerializerDeserializer
+ .getDouble(outInput0.getBytes(), APolygonSerializerDeserializer
+ .getCoordinateOffset(i, Coordinate.Y));
+ value = Math.max(y, value);
+ }
+ }
+ break;
+ default: {
+ throw new NotImplementedException(coordinate
+ + " is not a valid coordinate option");
+ }
+ }
+ break;
+ case CIRCLE:
+ switch (coordinate) {
+ case 0: {
+ double x = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ACircleSerializerDeserializer
+ .getCenterPointCoordinateOffset(Coordinate.X));
+ double radius = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ACircleSerializerDeserializer
+ .getCenterPointCoordinateOffset(Coordinate.X));
+
+ value = x - radius;
+ }
+ break;
+ case 1: {
+ double y = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ACircleSerializerDeserializer
+ .getCenterPointCoordinateOffset(Coordinate.Y));
+ double radius = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ACircleSerializerDeserializer
+ .getCenterPointCoordinateOffset(Coordinate.Y));
+
+ value = y - radius;
+ }
+ break;
+ case 2: {
+ double x = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ACircleSerializerDeserializer
+ .getCenterPointCoordinateOffset(Coordinate.X));
+ double radius = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ACircleSerializerDeserializer
+ .getCenterPointCoordinateOffset(Coordinate.X));
+
+ value = x + radius;
+ }
+ break;
+ case 3: {
+ double y = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ACircleSerializerDeserializer
+ .getCenterPointCoordinateOffset(Coordinate.Y));
+ double radius = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ACircleSerializerDeserializer
+ .getCenterPointCoordinateOffset(Coordinate.Y));
+
+ value = y + radius;
+ }
+ break;
+ default: {
+ throw new NotImplementedException(coordinate
+ + " is not a valid coordinate option");
+ }
+ }
+ break;
+ case RECTANGLE:
+ value = Double.MAX_VALUE;
+ switch (coordinate) {
+ case 0: {
+ value = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ARectangleSerializerDeserializer
+ .getBottomLeftCoordinateOffset(Coordinate.X));
+ }
+ break;
+ case 1: {
+ value = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ARectangleSerializerDeserializer
+ .getBottomLeftCoordinateOffset(Coordinate.Y));
+ }
+ break;
+ case 2: {
+ value = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ARectangleSerializerDeserializer
+ .getUpperRightCoordinateOffset(Coordinate.X));
+ }
+ break;
+ case 3: {
+ value = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ ARectangleSerializerDeserializer
+ .getUpperRightCoordinateOffset(Coordinate.Y));
+ }
+ break;
+ default: {
+ throw new NotImplementedException(coordinate
+ + " is not a valid coordinate option");
+ }
+ }
+ break;
+ default:
+ throw new NotImplementedException(
+ "create-mbr is only implemented for POINT, LINE, POLYGON, CIRCLE and RECTANGLE.");
+
+ }
+ } else {
+ throw new NotImplementedException(dimension + "D is not supported");
+ }
+ out.writeByte(ATypeTag.DOUBLE.serialize());
+ out.writeDouble(value);
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/DoubleArray.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/DoubleArray.java
new file mode 100644
index 0000000..f1fae0d
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/DoubleArray.java
@@ -0,0 +1,61 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.util.Arrays;
+
+public class DoubleArray {
+ private static final int SIZE = 1;
+
+ private double[] data;
+ private int length;
+
+ public DoubleArray() {
+ data = new double[SIZE];
+ length = 0;
+ }
+
+ public void add(double d) {
+ if (length == data.length) {
+ data = Arrays.copyOf(data, data.length << 1);
+ }
+ data[length++] = d;
+ }
+
+ public double[] get() {
+ return data;
+ }
+
+ public double get(int i) {
+ return data[i];
+ }
+
+ public int length() {
+ return length;
+ }
+
+ public void reset() {
+ length = 0;
+ }
+
+ public void sort() {
+ sort(0, length);
+ }
+
+ public void sort(int start, int end) {
+ Arrays.sort(data, start, end);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder out = new StringBuilder();
+ out.append('[');
+ for (int i = 0; i < length; ++i) {
+ out.append(data[i]);
+ if (i < length - 1) {
+ out.append(',');
+ out.append(' ');
+ }
+ }
+ out.append(']');
+ return out.toString();
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/EditDistanceEvaluator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/EditDistanceEvaluator.java
new file mode 100644
index 0000000..05194dd
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/EditDistanceEvaluator.java
@@ -0,0 +1,134 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityMetricEditDistance;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class EditDistanceEvaluator implements IEvaluator {
+
+ // assuming type indicator in serde format
+ protected final int typeIndicatorSize = 1;
+
+ protected final DataOutput out;
+ protected final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ protected final IEvaluator firstStringEval;
+ protected final IEvaluator secondStringEval;
+ protected final SimilarityMetricEditDistance ed = new SimilarityMetricEditDistance();
+ protected final AsterixOrderedListIterator firstOrdListIter = new AsterixOrderedListIterator();
+ protected final AsterixOrderedListIterator secondOrdListIter = new AsterixOrderedListIterator();
+ protected int editDistance = 0;
+ protected final AMutableInt32 aInt32 = new AMutableInt32(-1);
+ @SuppressWarnings("unchecked")
+ protected final ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ protected ATypeTag itemTypeTag;
+
+ protected int firstStart = -1;
+ protected int secondStart = -1;
+ protected ATypeTag firstTypeTag;
+ protected ATypeTag secondTypeTag;
+
+ public EditDistanceEvaluator(IEvaluatorFactory[] args, IDataOutputProvider output) throws AlgebricksException {
+ out = output.getDataOutput();
+ firstStringEval = args[0].createEvaluator(argOut);
+ secondStringEval = args[1].createEvaluator(argOut);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ runArgEvals(tuple);
+
+ if (!checkArgTypes(firstTypeTag, secondTypeTag))
+ return;
+
+ itemTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[firstStart + 1]);
+ if (itemTypeTag == ATypeTag.ANY)
+ throw new AlgebricksException("\n Edit Distance can only be called on homogenous lists");
+
+ itemTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[secondStart + 1]);
+ if (itemTypeTag == ATypeTag.ANY)
+ throw new AlgebricksException("\n Edit Distance can only be called on homogenous lists");
+
+ editDistance = computeResult(argOut.getBytes(), firstStart, secondStart, firstTypeTag);
+
+ try {
+ writeResult(editDistance);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ protected void runArgEvals(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+
+ firstStart = argOut.getLength();
+ firstStringEval.evaluate(tuple);
+ secondStart = argOut.getLength();
+ secondStringEval.evaluate(tuple);
+
+ firstTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[firstStart]);
+ secondTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[secondStart]);
+ }
+
+ protected int computeResult(byte[] bytes, int firstStart, int secondStart, ATypeTag argType)
+ throws AlgebricksException {
+ switch (argType) {
+
+ case STRING: {
+ return ed
+ .UTF8StringEditDistance(bytes, firstStart + typeIndicatorSize, secondStart + typeIndicatorSize);
+ }
+
+ case ORDEREDLIST: {
+ firstOrdListIter.reset(bytes, firstStart);
+ secondOrdListIter.reset(bytes, secondStart);
+ return (int) ed.getSimilarity(firstOrdListIter, secondOrdListIter);
+ }
+
+ default: {
+ throw new AlgebricksException("Invalid type " + argType
+ + " passed as argument to edit distance function.");
+ }
+
+ }
+ }
+
+ protected boolean checkArgTypes(ATypeTag typeTag1, ATypeTag typeTag2) throws AlgebricksException {
+ // edit distance between null and anything else is 0
+ if (typeTag1 == ATypeTag.NULL || typeTag2 == ATypeTag.NULL) {
+ try {
+ writeResult(0);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ return false;
+ }
+
+ if (typeTag1 != typeTag2) {
+ throw new AlgebricksException("Incompatible argument types given in edit distance: " + typeTag1 + " "
+ + typeTag2);
+ }
+
+ return true;
+ }
+
+ protected void writeResult(int ed) throws IOException {
+ aInt32.setValue(ed);
+ int32Serde.serialize(aInt32, out);
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/FieldAccessByIndexEvalFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/FieldAccessByIndexEvalFactory.java
new file mode 100644
index 0000000..acbe9a2
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/FieldAccessByIndexEvalFactory.java
@@ -0,0 +1,127 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARecordSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class FieldAccessByIndexEvalFactory implements IEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ private IEvaluatorFactory recordEvalFactory;
+ private IEvaluatorFactory fieldIndexEvalFactory;
+ private int nullBitmapSize;
+ private ARecordType recordType;
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static byte SER_RECORD_TYPE_TAG = ATypeTag.RECORD.serialize();
+
+ public FieldAccessByIndexEvalFactory(IEvaluatorFactory recordEvalFactory, IEvaluatorFactory fieldIndexEvalFactory,
+ ARecordType recordType) {
+ this.recordEvalFactory = recordEvalFactory;
+ this.fieldIndexEvalFactory = fieldIndexEvalFactory;
+ this.recordType = recordType;
+ if (NonTaggedFormatUtil.hasNullableField(recordType))
+ this.nullBitmapSize = (int) Math.ceil(recordType.getFieldNames().length / 8.0);
+ else
+ this.nullBitmapSize = 0;
+
+ }
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private IEvaluator eval0 = recordEvalFactory.createEvaluator(outInput0);
+ private IEvaluator eval1 = fieldIndexEvalFactory.createEvaluator(outInput1);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private int fieldIndex;
+ private int fieldValueOffset;
+ private int fieldValueLength;
+ private IAType fieldValueType;
+ private ATypeTag fieldValueTypeTag = ATypeTag.NULL;
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+ byte[] serRecord = outInput0.getBytes();
+
+ if (serRecord[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (serRecord[0] != SER_RECORD_TYPE_TAG) {
+ throw new AlgebricksException("Field accessor is not defined for values of type "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serRecord[0]));
+ }
+
+ fieldIndex = IntegerSerializerDeserializer.getInt(outInput1.getBytes(), 1);
+ fieldValueOffset = ARecordSerializerDeserializer.getFieldOffsetById(serRecord, fieldIndex,
+ nullBitmapSize, recordType.isOpen());
+
+ if (fieldValueOffset == 0) {
+ // the field is null, we checked the null bit map
+ out.writeByte(SER_NULL_TYPE_TAG);
+ return;
+ }
+
+ fieldValueType = recordType.getFieldTypes()[fieldIndex];
+ if (fieldValueType.getTypeTag().equals(ATypeTag.UNION)) {
+ if (NonTaggedFormatUtil.isOptionalField((AUnionType) fieldValueType)) {
+ fieldValueTypeTag = ((AUnionType) fieldValueType).getUnionList()
+ .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST).getTypeTag();
+ fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(serRecord, fieldValueOffset,
+ fieldValueTypeTag, false);
+ out.writeByte(fieldValueTypeTag.serialize());
+ } else {
+ // union .. the general case
+ throw new NotImplementedException();
+ }
+ } else {
+ fieldValueTypeTag = fieldValueType.getTypeTag();
+ fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(serRecord, fieldValueOffset,
+ fieldValueTypeTag, false);
+ out.writeByte(fieldValueTypeTag.serialize());
+ }
+ out.write(serRecord, fieldValueOffset, fieldValueLength);
+
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/FunctionManagerImpl.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/FunctionManagerImpl.java
new file mode 100644
index 0000000..99fcc00
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/FunctionManagerImpl.java
@@ -0,0 +1,43 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionManager;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+
+public class FunctionManagerImpl implements IFunctionManager {
+ private final Map<FunctionIdentifier, IFunctionDescriptor> functions;
+
+ public FunctionManagerImpl() {
+ functions = new HashMap<FunctionIdentifier, IFunctionDescriptor>();
+ }
+
+ @Override
+ public synchronized IFunctionDescriptor lookupFunction(FunctionIdentifier fid) throws AlgebricksException {
+ return functions.get(fid);
+ }
+
+ @Override
+ public synchronized void registerFunction(IFunctionDescriptor descriptor) throws AlgebricksException {
+ functions.put(descriptor.getIdentifier(), descriptor);
+ }
+
+ @Override
+ public synchronized void unregisterFunction(IFunctionDescriptor descriptor) throws AlgebricksException {
+ FunctionIdentifier fid = descriptor.getIdentifier();
+ IFunctionDescriptor desc = functions.get(fid);
+ if (descriptor == desc) {
+ functions.remove(fid);
+ }
+ }
+
+ @Override
+ public synchronized Iterator<IFunctionDescriptor> iterator() {
+ return new ArrayList<IFunctionDescriptor>(functions.values()).iterator();
+ }
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/GramTokensEvaluator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/GramTokensEvaluator.java
new file mode 100644
index 0000000..0fb473d
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/GramTokensEvaluator.java
@@ -0,0 +1,84 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.IAOrderedListBuilder;
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.fuzzyjoin.IntArray;
+import edu.uci.ics.fuzzyjoin.tokenizer.IBinaryTokenizer;
+import edu.uci.ics.fuzzyjoin.tokenizer.IToken;
+import edu.uci.ics.fuzzyjoin.tokenizer.NGramUTF8StringBinaryTokenizer;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.BooleanSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class GramTokensEvaluator implements IEvaluator {
+
+ // assuming type indicator in serde format
+ private final int typeIndicatorSize = 1;
+
+ protected final DataOutput out;
+ protected final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ protected final IEvaluator stringEval;
+ protected final IEvaluator gramLengthEval;
+ protected final IEvaluator prePostEval;
+
+ private final NGramUTF8StringBinaryTokenizer tokenizer;
+
+ protected final IntArray itemOffsets = new IntArray();
+ protected final ArrayBackedValueStorage tokenBuffer = new ArrayBackedValueStorage();
+
+ private IAOrderedListBuilder listBuilder = new OrderedListBuilder();
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private BuiltinType itemType;
+
+ public GramTokensEvaluator(IEvaluatorFactory[] args, IDataOutputProvider output, IBinaryTokenizer tokenizer,
+ BuiltinType itemType) throws AlgebricksException {
+ out = output.getDataOutput();
+ stringEval = args[0].createEvaluator(argOut);
+ gramLengthEval = args[1].createEvaluator(argOut);
+ prePostEval = args[2].createEvaluator(argOut);
+ this.tokenizer = (NGramUTF8StringBinaryTokenizer) tokenizer;
+ this.itemType = itemType;
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+ stringEval.evaluate(tuple);
+ int gramLengthOff = argOut.getLength();
+ gramLengthEval.evaluate(tuple);
+ int prePostOff = argOut.getLength();
+ prePostEval.evaluate(tuple);
+
+ byte[] bytes = argOut.getBytes();
+ int gramLength = IntegerSerializerDeserializer.getInt(bytes, gramLengthOff + typeIndicatorSize);
+ tokenizer.setGramlength(gramLength);
+ boolean prePost = BooleanSerializerDeserializer.getBoolean(bytes, prePostOff + typeIndicatorSize);
+ tokenizer.setPrePost(prePost);
+ tokenizer.reset(bytes, 0, gramLengthOff);
+ tokenBuffer.reset();
+
+ try {
+ listBuilder.reset(new AOrderedListType(itemType, null));
+ while (tokenizer.hasNext()) {
+ inputVal.reset();
+ tokenizer.next();
+ IToken token = tokenizer.getToken();
+ token.serializeToken(inputVal.getDataOutput());
+ listBuilder.addItem(inputVal);
+ }
+ listBuilder.write(out, true);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityFiltersCache.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityFiltersCache.java
new file mode 100644
index 0000000..7b25c6e
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityFiltersCache.java
@@ -0,0 +1,39 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataInputStream;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityFilters;
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityFiltersFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.util.ByteBufferInputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
+
+public class SimilarityFiltersCache {
+
+ private final ByteBufferInputStream bbis = new ByteBufferInputStream();
+ private final DataInputStream dis = new DataInputStream(bbis);
+
+ private float similarityThresholdCached = 0;
+ private byte[] similarityNameBytesCached = null;
+ private SimilarityFilters similarityFiltersCached = null;
+
+ public SimilarityFilters get(float similarityThreshold, byte[] similarityNameBytes) throws AlgebricksException {
+ if (similarityThreshold != similarityThresholdCached || similarityNameBytesCached == null
+ || !Arrays.equals(similarityNameBytes, similarityNameBytesCached)) {
+ bbis.setByteBuffer(ByteBuffer.wrap(similarityNameBytes), 1);
+ String similarityName;
+ try {
+ similarityName = UTF8StringSerializerDeserializer.INSTANCE.deserialize(dis);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ similarityNameBytesCached = Arrays.copyOf(similarityNameBytes, similarityNameBytes.length);
+ similarityFiltersCached = SimilarityFiltersFactory
+ .getSimilarityFilters(similarityName, similarityThreshold);
+ }
+ return similarityFiltersCached;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardEvaluator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardEvaluator.java
new file mode 100644
index 0000000..dee26fb
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardEvaluator.java
@@ -0,0 +1,147 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AFloat;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityMetricJaccard;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+// assumes that both arguments are sorted by the same ordering
+
+public class SimilarityJaccardEvaluator implements IEvaluator {
+
+ // assuming type indicator in serde format
+ protected final int typeIndicatorSize = 1;
+
+ protected final DataOutput out;
+ protected final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ protected final IEvaluator firstOrdListEval;
+ protected final IEvaluator secondOrdListEval;
+
+ protected final AsterixOrderedListIterator fstOrdListIter = new AsterixOrderedListIterator();
+ protected final AsterixOrderedListIterator sndOrdListIter = new AsterixOrderedListIterator();
+ protected final AsterixUnorderedListIterator fstUnordListIter = new AsterixUnorderedListIterator();
+ protected final AsterixUnorderedListIterator sndUnordListIter = new AsterixUnorderedListIterator();
+
+ protected AbstractAsterixListIterator firstListIter;
+ protected AbstractAsterixListIterator secondListIter;
+
+ protected final SimilarityMetricJaccard jaccard = new SimilarityMetricJaccard();
+ protected final AMutableFloat aFloat = new AMutableFloat(0);
+ @SuppressWarnings("unchecked")
+ protected final ISerializerDeserializer<AFloat> floatSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+
+ protected ATypeTag itemTypeTag;
+
+ protected ATypeTag firstTypeTag;
+ protected ATypeTag secondTypeTag;
+ protected int firstStart = -1;
+ protected int secondStart = -1;
+ protected float jaccSim = 0.0f;
+
+ public SimilarityJaccardEvaluator(IEvaluatorFactory[] args, IDataOutputProvider output) throws AlgebricksException {
+ out = output.getDataOutput();
+ firstOrdListEval = args[0].createEvaluator(argOut);
+ secondOrdListEval = args[1].createEvaluator(argOut);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ runArgEvals(tuple);
+ if (!checkArgTypes(firstTypeTag, secondTypeTag))
+ return;
+ jaccSim = computeResult(argOut.getBytes(), firstStart, secondStart, firstTypeTag);
+ try {
+ writeResult(jaccSim);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ protected void runArgEvals(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+
+ firstStart = argOut.getLength();
+ firstOrdListEval.evaluate(tuple);
+ secondStart = argOut.getLength();
+ secondOrdListEval.evaluate(tuple);
+
+ firstTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[firstStart]);
+ secondTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[secondStart]);
+ }
+
+ protected float computeResult(byte[] bytes, int firstStart, int secondStart, ATypeTag argType)
+ throws AlgebricksException {
+ firstListIter.reset(bytes, firstStart);
+ secondListIter.reset(bytes, secondStart);
+ // Check for special case where one of the lists is empty, since list
+ // types won't match.
+ if (firstListIter.size() == 0 || secondListIter.size() == 0) {
+ try {
+ writeResult(0.0f);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ if (firstTypeTag == ATypeTag.ANY || secondTypeTag == ATypeTag.ANY)
+ throw new AlgebricksException("\n Jaccard can only be called on homogenous lists");
+ return jaccard.getSimilarity(firstListIter, secondListIter);
+ }
+
+ protected boolean checkArgTypes(ATypeTag typeTag1, ATypeTag typeTag2) throws AlgebricksException {
+ // jaccard between null and anything else is 0
+ if (typeTag1 == ATypeTag.NULL || typeTag2 == ATypeTag.NULL) {
+ try {
+ writeResult(0.0f);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ return false;
+ }
+ switch (typeTag1) {
+ case ORDEREDLIST: {
+ firstListIter = fstOrdListIter;
+ break;
+ }
+ case UNORDEREDLIST: {
+ firstListIter = fstUnordListIter;
+ break;
+ }
+ default: {
+ throw new AlgebricksException("Invalid types " + typeTag1 + " given as arguments to jaccard.");
+ }
+ }
+ switch (typeTag2) {
+ case ORDEREDLIST: {
+ secondListIter = sndOrdListIter;
+ break;
+ }
+ case UNORDEREDLIST: {
+ secondListIter = sndUnordListIter;
+ break;
+ }
+ default: {
+ throw new AlgebricksException("Invalid types " + typeTag2 + " given as arguments to jaccard.");
+ }
+ }
+ return true;
+ }
+
+ protected void writeResult(float jacc) throws IOException {
+ aFloat.setValue(jacc);
+ floatSerde.serialize(aFloat, out);
+ }
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardPrefixEvaluator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardPrefixEvaluator.java
new file mode 100644
index 0000000..93954af
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardPrefixEvaluator.java
@@ -0,0 +1,219 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AUnorderedListSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AFloat;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.fuzzyjoin.IntArray;
+import edu.uci.ics.fuzzyjoin.similarity.PartialIntersect;
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityFiltersJaccard;
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityMetric;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class SimilarityJaccardPrefixEvaluator implements IEvaluator {
+ // assuming type indicator in serde format
+ protected final int typeIndicatorSize = 1;
+
+ protected final DataOutput out;
+ protected final ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ protected final IEvaluator evalLen1;
+ protected final IEvaluator evalTokens1;
+ protected final IEvaluator evalLen2;
+ protected final IEvaluator evalTokens2;
+ protected final IEvaluator evalTokenPrefix;
+ protected final IEvaluator evalThreshold;
+
+ protected float similarityThresholdCache;
+ protected SimilarityFiltersJaccard similarityFilters;
+
+ private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+ private final static byte SER_UNORDEREDLIST_TYPE_TAG = ATypeTag.UNORDEREDLIST.serialize();
+
+ protected final IntArray tokens1 = new IntArray();
+ protected final IntArray tokens2 = new IntArray();
+ protected final PartialIntersect parInter = new PartialIntersect();
+
+ protected float sim = 0.0f;
+
+ // result
+ protected final AMutableFloat res = new AMutableFloat(0);
+ @SuppressWarnings("unchecked")
+ protected final ISerializerDeserializer<AFloat> reusSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+
+ public SimilarityJaccardPrefixEvaluator(IEvaluatorFactory[] args, IDataOutputProvider output)
+ throws AlgebricksException {
+ out = output.getDataOutput();
+ evalLen1 = args[0].createEvaluator(inputVal);
+ evalTokens1 = args[1].createEvaluator(inputVal);
+ evalLen2 = args[2].createEvaluator(inputVal);
+ evalTokens2 = args[3].createEvaluator(inputVal);
+ evalTokenPrefix = args[4].createEvaluator(inputVal);
+ evalThreshold = args[5].createEvaluator(inputVal);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ // similarity threshold
+ sim = 0;
+ inputVal.reset();
+ evalThreshold.evaluate(tuple);
+ float similarityThreshold = AFloatSerializerDeserializer.getFloat(inputVal.getBytes(), 1);
+
+ if (similarityThreshold != similarityThresholdCache || similarityFilters == null) {
+ similarityFilters = new SimilarityFiltersJaccard(similarityThreshold);
+ similarityThresholdCache = similarityThreshold;
+ }
+
+ inputVal.reset();
+ evalLen1.evaluate(tuple);
+ int length1 = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ inputVal.reset();
+ evalLen2.evaluate(tuple);
+ int length2 = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ //
+ // -- - length filter - --
+ //
+ if (similarityFilters.passLengthFilter(length1, length2)) {
+
+ // -- - tokens1 - --
+ int i;
+ tokens1.reset();
+ inputVal.reset();
+ evalTokens1.evaluate(tuple);
+
+ byte[] serList = inputVal.getBytes();
+ if (serList[0] != SER_ORDEREDLIST_TYPE_TAG && serList[0] != SER_UNORDEREDLIST_TYPE_TAG) {
+ throw new AlgebricksException("Scan collection is not defined for values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[0]));
+ }
+
+ int lengthTokens1;
+ if (serList[0] == SER_ORDEREDLIST_TYPE_TAG) {
+ lengthTokens1 = AOrderedListSerializerDeserializer.getNumberOfItems(inputVal.getBytes());
+ // read tokens
+ for (i = 0; i < lengthTokens1; i++) {
+ int itemOffset;
+ try {
+ itemOffset = AOrderedListSerializerDeserializer.getItemOffset(serList, i);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ tokens1.add(IntegerSerializerDeserializer.getInt(serList, itemOffset));
+ }
+ } else {
+ lengthTokens1 = AUnorderedListSerializerDeserializer.getNumberOfItems(inputVal.getBytes());
+ // read tokens
+ for (i = 0; i < lengthTokens1; i++) {
+ int itemOffset;
+ try {
+ itemOffset = AUnorderedListSerializerDeserializer.getItemOffset(serList, i);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ tokens1.add(IntegerSerializerDeserializer.getInt(serList, itemOffset));
+ }
+ }
+ // pad tokens
+ for (; i < length1; i++) {
+ tokens1.add(Integer.MAX_VALUE);
+ }
+
+ // -- - tokens2 - --
+ tokens2.reset();
+ inputVal.reset();
+ evalTokens2.evaluate(tuple);
+
+ serList = inputVal.getBytes();
+ if (serList[0] != SER_ORDEREDLIST_TYPE_TAG && serList[0] != SER_UNORDEREDLIST_TYPE_TAG) {
+ throw new AlgebricksException("Scan collection is not defined for values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[0]));
+ }
+
+ int lengthTokens2;
+ if (serList[0] == SER_ORDEREDLIST_TYPE_TAG) {
+ lengthTokens2 = AOrderedListSerializerDeserializer.getNumberOfItems(inputVal.getBytes());
+ // read tokens
+ for (i = 0; i < lengthTokens2; i++) {
+ int itemOffset;
+ try {
+ itemOffset = AOrderedListSerializerDeserializer.getItemOffset(serList, i);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ tokens2.add(IntegerSerializerDeserializer.getInt(serList, itemOffset));
+ }
+ } else {
+ lengthTokens2 = AUnorderedListSerializerDeserializer.getNumberOfItems(inputVal.getBytes());
+ // read tokens
+ for (i = 0; i < lengthTokens2; i++) {
+ int itemOffset;
+ try {
+ itemOffset = AUnorderedListSerializerDeserializer.getItemOffset(serList, i);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ tokens2.add(IntegerSerializerDeserializer.getInt(serList, itemOffset));
+ }
+ }
+ // pad tokens
+ for (; i < length2; i++) {
+ tokens2.add(Integer.MAX_VALUE);
+ }
+
+ // -- - token prefix - --
+ inputVal.reset();
+ evalTokenPrefix.evaluate(tuple);
+ int tokenPrefix = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ //
+ // -- - position filter - --
+ //
+ SimilarityMetric.getPartialIntersectSize(tokens1.get(), 0, tokens1.length(), tokens2.get(), 0,
+ tokens2.length(), tokenPrefix, parInter);
+ if (similarityFilters.passPositionFilter(parInter.intersectSize, parInter.posXStop, length1,
+ parInter.posYStop, length2)) {
+
+ //
+ // -- - suffix filter - --
+ //
+ if (similarityFilters.passSuffixFilter(tokens1.get(), 0, tokens1.length(), parInter.posXStart,
+ tokens2.get(), 0, tokens2.length(), parInter.posYStart)) {
+
+ sim = similarityFilters.passSimilarityFilter(tokens1.get(), 0, tokens1.length(),
+ parInter.posXStop + 1, tokens2.get(), 0, tokens2.length(), parInter.posYStop + 1,
+ parInter.intersectSize);
+ }
+ }
+ }
+
+ try {
+ writeResult();
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ public void writeResult() throws AlgebricksException, IOException {
+ res.setValue(sim);
+ reusSerde.serialize(res, out);
+ }
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SpatialUtils.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SpatialUtils.java
new file mode 100644
index 0000000..0f421bb
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SpatialUtils.java
@@ -0,0 +1,161 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.Coordinate;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APolygonSerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+
+public class SpatialUtils {
+ private double xAxis;
+ private double yAxis;
+ private double minProjection;
+ private double maxProjection;
+ private static final double doubleEpsilon = computeDoubleEpsilon();
+ private static final double pi = 3.14159265;
+
+ public SpatialUtils() {
+ }
+
+ private static double computeDoubleEpsilon() {
+ double doubleEpsilon = 1.0;
+
+ do {
+ doubleEpsilon /= 2.0;
+ } while (1.0 + (doubleEpsilon / 2.0) != 1.0);
+ return doubleEpsilon;
+ }
+
+ public static double doubleEpsilon() {
+ return doubleEpsilon;
+ }
+
+ public double getMinProjection() {
+ return minProjection;
+ }
+
+ public void setMinProjection(double minProjection) {
+ this.minProjection = minProjection;
+ }
+
+ public double getMaxProjection() {
+ return maxProjection;
+ }
+
+ public void setMaxProjection(double maxProjection) {
+ this.maxProjection = maxProjection;
+ }
+
+ public double getXAxis() {
+ return xAxis;
+ }
+
+ public void setXAxis(double xAxis) {
+ this.xAxis = xAxis;
+ }
+
+ public double getYAxis() {
+ return yAxis;
+ }
+
+ public void setYAxis(double yAxis) {
+ this.yAxis = yAxis;
+ }
+
+ public final static double pi() {
+ return pi;
+ }
+
+ public final static double dotProduct(double x1, double y1, double x2, double y2) {
+ return x1 * x2 + y1 * y2;
+ }
+
+ public final static double crossProduct(double x1, double y1, double x2, double y2) {
+ return x1 * y2 - y1 * x2;
+ }
+
+ // Warning: The caller is responsible of taking the absolute value
+ public final static double polygonArea(byte[] bytes, int numOfPoints) throws HyracksDataException {
+ double area = 0.0;
+ for (int i = 0; i < numOfPoints; i++) {
+
+ double x1 = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(i, Coordinate.X));
+ double y1 = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(i, Coordinate.Y));
+ double x2;
+ double y2;
+ if (i + 1 == numOfPoints) {
+ x2 = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(0, Coordinate.X));
+ y2 = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(0, Coordinate.Y));
+ } else {
+ x2 = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(i + 1, Coordinate.X));
+ y2 = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(i + 1, Coordinate.Y));
+ }
+ area += (x1 * y2) - (x2 * y1);
+ }
+ return area * 0.5;
+ }
+
+ public void projectPolygon(DoubleArray trianglesX, DoubleArray trianglesY, int triangleId, double xAxis,
+ double yAxis) throws HyracksDataException {
+ double temp, min, max;
+ min = max = getTriangleXCoordinate(trianglesX, triangleId, 0) * xAxis
+ + getTriangleYCoordinate(trianglesY, triangleId, 0) * yAxis;
+
+ for (int i = 1; i < 3; i++) {
+ temp = getTriangleXCoordinate(trianglesX, triangleId, i) * xAxis
+ + getTriangleYCoordinate(trianglesY, triangleId, i) * yAxis;
+
+ if (temp > max)
+ max = temp;
+ else if (temp < min)
+ min = temp;
+ }
+ setMinProjection(min);
+ setMaxProjection(max);
+ }
+
+ public void findNormals(DoubleArray trianglesX, DoubleArray trianglesY, int triangleId, int side)
+ throws HyracksDataException {
+ double x, y;
+ if (side == 0) {
+ x = getTriangleYCoordinate(trianglesY, triangleId, 2)
+ - getTriangleYCoordinate(trianglesY, triangleId, side);
+
+ y = getTriangleXCoordinate(trianglesX, triangleId, side)
+ - getTriangleXCoordinate(trianglesX, triangleId, 2);
+
+ } else {
+ x = getTriangleYCoordinate(trianglesY, triangleId, side - 1)
+ - getTriangleYCoordinate(trianglesY, triangleId, side);
+
+ y = getTriangleXCoordinate(trianglesX, triangleId, side)
+ - getTriangleXCoordinate(trianglesX, triangleId, side - 1);
+ }
+ double temp = Math.sqrt(dotProduct(x, y, x, y));
+ x /= temp;
+ y /= temp;
+ setXAxis(x);
+ setYAxis(y);
+ }
+
+ public static double getTriangleXCoordinate(DoubleArray trianglesX, int triangleId, int point) {
+ return trianglesX.get(triangleId * 3 + point);
+ }
+
+ public static double getTriangleYCoordinate(DoubleArray trianglesY, int triangleId, int point) {
+ return trianglesY.get(triangleId * 3 + point);
+ }
+
+ public static void setTriangleXCoordinate(DoubleArray trianglesX, int triangleId, int point, double value) {
+ trianglesX.get()[triangleId * 3 + point] = value;
+ }
+
+ public static void setTriangleYCoordinate(DoubleArray trianglesY, int triangleId, int point, double value) {
+ trianglesY.get()[triangleId * 3 + point] = value;
+ }
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/WordTokensEvaluator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/WordTokensEvaluator.java
new file mode 100644
index 0000000..d17f569
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/WordTokensEvaluator.java
@@ -0,0 +1,64 @@
+package edu.uci.ics.asterix.runtime.evaluators.common;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.IAOrderedListBuilder;
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.fuzzyjoin.IntArray;
+import edu.uci.ics.fuzzyjoin.tokenizer.IBinaryTokenizer;
+import edu.uci.ics.fuzzyjoin.tokenizer.IToken;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class WordTokensEvaluator implements IEvaluator {
+ protected final DataOutput out;
+ protected final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ protected final IEvaluator stringEval;
+
+ protected final IBinaryTokenizer tokenizer;
+
+ protected final IntArray itemOffsets = new IntArray();
+ protected final ArrayBackedValueStorage tokenBuffer = new ArrayBackedValueStorage();
+
+ private IAOrderedListBuilder listBuilder = new OrderedListBuilder();
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private BuiltinType itemType;
+
+ public WordTokensEvaluator(IEvaluatorFactory[] args, IDataOutputProvider output, IBinaryTokenizer tokenizer,
+ BuiltinType itemType) throws AlgebricksException {
+ out = output.getDataOutput();
+ stringEval = args[0].createEvaluator(argOut);
+ this.tokenizer = tokenizer;
+ this.itemType = itemType;
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+ stringEval.evaluate(tuple);
+ byte[] bytes = argOut.getBytes();
+ tokenizer.reset(bytes, 0, argOut.getLength());
+ tokenBuffer.reset();
+
+ try {
+ listBuilder.reset(new AOrderedListType(itemType, null));
+ while (tokenizer.hasNext()) {
+ inputVal.reset();
+ tokenizer.next();
+ IToken token = tokenizer.getToken();
+ token.serializeToken(inputVal.getDataOutput());
+ listBuilder.addItem(inputVal);
+ }
+ listBuilder.write(out, true);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/AbstractComparisonEvaluator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/AbstractComparisonEvaluator.java
new file mode 100644
index 0000000..798853e
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/AbstractComparisonEvaluator.java
@@ -0,0 +1,426 @@
+package edu.uci.ics.asterix.runtime.evaluators.comparisons;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.ADateTimeAscBinaryComparatorFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.FloatSerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public abstract class AbstractComparisonEvaluator implements IEvaluator {
+
+ protected enum ComparisonResult {
+ LESS_THAN,
+ EQUAL,
+ GREATER_THAN,
+ UNKNOWN
+ };
+
+ protected DataOutput out;
+ protected ArrayBackedValueStorage outLeft = new ArrayBackedValueStorage();
+ protected ArrayBackedValueStorage outRight = new ArrayBackedValueStorage();
+ protected IEvaluator evalLeft;
+ protected IEvaluator evalRight;
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<ABoolean> serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ protected IBinaryComparator strBinaryComp = AqlBinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE
+ .createBinaryComparator();
+ protected IBinaryComparator dateTimeBinaryComp = ADateTimeAscBinaryComparatorFactory.INSTANCE
+ .createBinaryComparator();
+
+ public AbstractComparisonEvaluator(DataOutput out, IEvaluatorFactory evalLeftFactory,
+ IEvaluatorFactory evalRightFactory) throws AlgebricksException {
+ this.out = out;
+ this.evalLeft = evalLeftFactory.createEvaluator(outLeft);
+ this.evalRight = evalRightFactory.createEvaluator(outRight);
+ }
+
+ protected void evalInputs(IFrameTupleReference tuple) throws AlgebricksException {
+ outLeft.reset();
+ evalLeft.evaluate(tuple);
+ outRight.reset();
+ evalRight.evaluate(tuple);
+ }
+
+ protected ComparisonResult compareResults() throws AlgebricksException {
+ boolean isLeftNull = false;
+ boolean isRightNull = false;
+ ATypeTag typeTag1 = null;
+ ATypeTag typeTag2 = null;
+
+ if (outLeft.getLength() == 0) {
+ isLeftNull = true;
+ } else {
+ typeTag1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(outLeft.getBytes()[0]);
+ if (typeTag1 == ATypeTag.NULL) {
+ isLeftNull = true;
+ }
+ }
+ if (outRight.getLength() == 0) {
+ isRightNull = true;
+ } else {
+ typeTag2 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(outRight.getBytes()[0]);
+ if (typeTag2 == ATypeTag.NULL) {
+ isRightNull = true;
+ }
+ }
+
+ if (isLeftNull || isRightNull)
+ return ComparisonResult.UNKNOWN;
+
+ switch (typeTag1) {
+ case INT8: {
+ return compareInt8WithArg(typeTag2);
+ }
+ case INT16: {
+ return compareInt16WithArg(typeTag2);
+ }
+ case INT32: {
+ return compareInt32WithArg(typeTag2);
+ }
+ case INT64: {
+ return compareInt64WithArg(typeTag2);
+ }
+ case FLOAT: {
+ return compareFloatWithArg(typeTag2);
+ }
+ case DOUBLE: {
+ return compareDoubleWithArg(typeTag2);
+ }
+ case STRING: {
+ return compareStringWithArg(typeTag2);
+ }
+ case BOOLEAN: {
+ return compareBooleanWithArg(typeTag2);
+ }
+ case DATETIME: {
+ return compareDateTimeWithArg(typeTag2);
+ }
+ default: {
+ throw new AlgebricksException("Comparison is undefined between types " + typeTag1 + " and " + typeTag2
+ + " .");
+ }
+ }
+ }
+
+ private ComparisonResult compareDateTimeWithArg(ATypeTag typeTag2) throws AlgebricksException {
+ if (typeTag2 == ATypeTag.NULL) {
+ return ComparisonResult.GREATER_THAN;
+ } else if (typeTag2 == ATypeTag.DATETIME) {
+ int result = dateTimeBinaryComp.compare(outLeft.getBytes(), 1, outLeft.getLength() - 1,
+ outRight.getBytes(), 1, outRight.getLength() - 1);
+ if (result == 0)
+ return ComparisonResult.EQUAL;
+ else if (result < 0)
+ return ComparisonResult.LESS_THAN;
+ else
+ return ComparisonResult.GREATER_THAN;
+ }
+ throw new AlgebricksException("Comparison is undefined between types ADateTime and " + typeTag2 + " .");
+ }
+
+ private ComparisonResult compareBooleanWithArg(ATypeTag typeTag2) throws AlgebricksException {
+ if (typeTag2 == ATypeTag.BOOLEAN) {
+ byte b0 = outLeft.getBytes()[1];
+ byte b1 = outRight.getBytes()[1];
+ return compareByte(b0, b1);
+ }
+ throw new AlgebricksException("Comparison is undefined between types ABoolean and " + typeTag2 + " .");
+ }
+
+ private ComparisonResult compareStringWithArg(ATypeTag typeTag2) throws AlgebricksException {
+ if (typeTag2 == ATypeTag.STRING) {
+ int result = strBinaryComp.compare(outLeft.getBytes(), 1, outLeft.getLength() - 1, outRight.getBytes(), 1,
+ outRight.getLength() - 1);
+ if (result == 0)
+ return ComparisonResult.EQUAL;
+ else if (result < 0)
+ return ComparisonResult.LESS_THAN;
+ else
+ return ComparisonResult.GREATER_THAN;
+ }
+ throw new AlgebricksException("Comparison is undefined between types AString and " + typeTag2 + " .");
+ }
+
+ private ComparisonResult compareDoubleWithArg(ATypeTag typeTag2) throws AlgebricksException {
+ double s = ADoubleSerializerDeserializer.getDouble(outLeft.getBytes(), 1);
+ switch (typeTag2) {
+ case INT8: {
+ byte v2 = AInt8SerializerDeserializer.getByte(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ case INT16: {
+ short v2 = AInt16SerializerDeserializer.getShort(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ case INT32: {
+ int v2 = AInt32SerializerDeserializer.getInt(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ case INT64: {
+ long v2 = AInt64SerializerDeserializer.getLong(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ case FLOAT: {
+ float v2 = AFloatSerializerDeserializer.getFloat(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ case DOUBLE: {
+ double v2 = ADoubleSerializerDeserializer.getDouble(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ default: {
+ throw new AlgebricksException("Comparison is undefined between types ADouble and " + typeTag2 + " .");
+ }
+ }
+ }
+
+ private ComparisonResult compareFloatWithArg(ATypeTag typeTag2) throws AlgebricksException {
+ float s = FloatSerializerDeserializer.getFloat(outLeft.getBytes(), 1);
+ switch (typeTag2) {
+ case INT8: {
+ byte v2 = AInt8SerializerDeserializer.getByte(outRight.getBytes(), 1);
+ return compareFloat(s, v2);
+ }
+ case INT16: {
+ short v2 = AInt16SerializerDeserializer.getShort(outRight.getBytes(), 1);
+ return compareFloat(s, v2);
+ }
+ case INT32: {
+ int v2 = AInt32SerializerDeserializer.getInt(outRight.getBytes(), 1);
+ return compareFloat(s, v2);
+ }
+ case INT64: {
+ long v2 = AInt64SerializerDeserializer.getLong(outRight.getBytes(), 1);
+ return compareFloat(s, v2);
+ }
+ case FLOAT: {
+ float v2 = AFloatSerializerDeserializer.getFloat(outRight.getBytes(), 1);
+ return compareFloat(s, v2);
+ }
+ case DOUBLE: {
+ double v2 = ADoubleSerializerDeserializer.getDouble(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ default: {
+ throw new AlgebricksException("Comparison is undefined between types AFloat and " + typeTag2 + " .");
+ }
+ }
+ }
+
+ private ComparisonResult compareInt64WithArg(ATypeTag typeTag2) throws AlgebricksException {
+ long s = AInt64SerializerDeserializer.getLong(outLeft.getBytes(), 1);
+ switch (typeTag2) {
+ case INT8: {
+ byte v2 = AInt8SerializerDeserializer.getByte(outRight.getBytes(), 1);
+ return compareLong(s, v2);
+ }
+ case INT16: {
+ short v2 = AInt16SerializerDeserializer.getShort(outRight.getBytes(), 1);
+ return compareLong(s, v2);
+ }
+ case INT32: {
+ int v2 = AInt32SerializerDeserializer.getInt(outRight.getBytes(), 1);
+ return compareLong(s, v2);
+ }
+ case INT64: {
+ long v2 = AInt64SerializerDeserializer.getLong(outRight.getBytes(), 1);
+ return compareLong(s, v2);
+ }
+ case FLOAT: {
+ float v2 = AFloatSerializerDeserializer.getFloat(outRight.getBytes(), 1);
+ return compareFloat(s, v2);
+ }
+ case DOUBLE: {
+ double v2 = ADoubleSerializerDeserializer.getDouble(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ default: {
+ throw new AlgebricksException("Comparison is undefined between types AInt64 and " + typeTag2 + " .");
+ }
+ }
+ }
+
+ private ComparisonResult compareInt32WithArg(ATypeTag typeTag2) throws AlgebricksException {
+ int s = IntegerSerializerDeserializer.getInt(outLeft.getBytes(), 1);
+ switch (typeTag2) {
+ case INT8: {
+ byte v2 = AInt8SerializerDeserializer.getByte(outRight.getBytes(), 1);
+ return compareInt(s, v2);
+ }
+ case INT16: {
+ short v2 = AInt16SerializerDeserializer.getShort(outRight.getBytes(), 1);
+ return compareInt(s, v2);
+ }
+ case INT32: {
+ int v2 = AInt32SerializerDeserializer.getInt(outRight.getBytes(), 1);
+ return compareInt(s, v2);
+ }
+ case INT64: {
+ long v2 = AInt64SerializerDeserializer.getLong(outRight.getBytes(), 1);
+ return compareLong(s, v2);
+ }
+ case FLOAT: {
+ float v2 = AFloatSerializerDeserializer.getFloat(outRight.getBytes(), 1);
+ return compareFloat(s, v2);
+ }
+ case DOUBLE: {
+ double v2 = ADoubleSerializerDeserializer.getDouble(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ default: {
+ throw new AlgebricksException("Comparison is undefined between types AInt32 and " + typeTag2 + " .");
+ }
+ }
+ }
+
+ private ComparisonResult compareInt16WithArg(ATypeTag typeTag2) throws AlgebricksException {
+ short s = AInt16SerializerDeserializer.getShort(outLeft.getBytes(), 1);
+ switch (typeTag2) {
+ case INT8: {
+ byte v2 = AInt8SerializerDeserializer.getByte(outRight.getBytes(), 1);
+ return compareShort(s, v2);
+ }
+ case INT16: {
+ short v2 = AInt16SerializerDeserializer.getShort(outRight.getBytes(), 1);
+ return compareShort(s, v2);
+ }
+ case INT32: {
+ int v2 = AInt32SerializerDeserializer.getInt(outRight.getBytes(), 1);
+ return compareInt(s, v2);
+ }
+ case INT64: {
+ long v2 = AInt64SerializerDeserializer.getLong(outRight.getBytes(), 1);
+ return compareLong(s, v2);
+ }
+ case FLOAT: {
+ float v2 = AFloatSerializerDeserializer.getFloat(outRight.getBytes(), 1);
+ return compareFloat(s, v2);
+ }
+ case DOUBLE: {
+ double v2 = ADoubleSerializerDeserializer.getDouble(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ default: {
+ throw new AlgebricksException("Comparison is undefined between types AInt16 and " + typeTag2 + " .");
+ }
+ }
+ }
+
+ private ComparisonResult compareInt8WithArg(ATypeTag typeTag2) throws AlgebricksException {
+ byte s = AInt8SerializerDeserializer.getByte(outLeft.getBytes(), 1);
+ switch (typeTag2) {
+ case INT8: {
+ byte v2 = AInt8SerializerDeserializer.getByte(outRight.getBytes(), 1);
+ return compareByte(s, v2);
+ }
+ case INT16: {
+ short v2 = AInt16SerializerDeserializer.getShort(outRight.getBytes(), 1);
+ return compareShort(s, v2);
+ }
+ case INT32: {
+ int v2 = AInt32SerializerDeserializer.getInt(outRight.getBytes(), 1);
+ return compareInt(s, v2);
+ }
+ case INT64: {
+ long v2 = AInt64SerializerDeserializer.getLong(outRight.getBytes(), 1);
+ return compareLong(s, v2);
+ }
+ case FLOAT: {
+ float v2 = AFloatSerializerDeserializer.getFloat(outRight.getBytes(), 1);
+ return compareFloat(s, v2);
+ }
+ case DOUBLE: {
+ double v2 = ADoubleSerializerDeserializer.getDouble(outRight.getBytes(), 1);
+ return compareDouble(s, v2);
+ }
+ default: {
+ throw new AlgebricksException("Comparison is undefined between types AInt16 and " + typeTag2 + " .");
+ }
+ }
+ }
+
+ private final ComparisonResult compareByte(int v1, int v2) {
+ if (v1 == v2) {
+ return ComparisonResult.EQUAL;
+ } else if (v1 < v2) {
+ return ComparisonResult.LESS_THAN;
+ } else {
+ return ComparisonResult.GREATER_THAN;
+ }
+ }
+
+ private final ComparisonResult compareShort(int v1, int v2) {
+ if (v1 == v2) {
+ return ComparisonResult.EQUAL;
+ } else if (v1 < v2) {
+ return ComparisonResult.LESS_THAN;
+ } else {
+ return ComparisonResult.GREATER_THAN;
+ }
+ }
+
+ private final ComparisonResult compareInt(int v1, int v2) {
+ if (v1 == v2) {
+ return ComparisonResult.EQUAL;
+ } else if (v1 < v2) {
+ return ComparisonResult.LESS_THAN;
+ } else {
+ return ComparisonResult.GREATER_THAN;
+ }
+ }
+
+ private final ComparisonResult compareLong(long v1, long v2) {
+ if (v1 == v2) {
+ return ComparisonResult.EQUAL;
+ } else if (v1 < v2) {
+ return ComparisonResult.LESS_THAN;
+ } else {
+ return ComparisonResult.GREATER_THAN;
+ }
+ }
+
+ private final ComparisonResult compareFloat(float v1, float v2) {
+ if (v1 == v2) {
+ return ComparisonResult.EQUAL;
+ } else if (v1 < v2) {
+ return ComparisonResult.LESS_THAN;
+ } else {
+ return ComparisonResult.GREATER_THAN;
+ }
+ }
+
+ private final ComparisonResult compareDouble(double v1, double v2) {
+ if (v1 == v2) {
+ return ComparisonResult.EQUAL;
+ } else if (v1 < v2) {
+ return ComparisonResult.LESS_THAN;
+ } else {
+ return ComparisonResult.GREATER_THAN;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/ComparisonEvalFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/ComparisonEvalFactory.java
new file mode 100644
index 0000000..1e87b75
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/ComparisonEvalFactory.java
@@ -0,0 +1,229 @@
+package edu.uci.ics.asterix.runtime.evaluators.comparisons;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions.ComparisonKind;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ComparisonEvalFactory implements IEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ private IEvaluatorFactory evalLeftFactory;
+ private IEvaluatorFactory evalRightFactory;
+ private ComparisonKind comparisonKind;
+
+ public ComparisonEvalFactory(IEvaluatorFactory evalLeftFactory, IEvaluatorFactory evalRightFactory,
+ ComparisonKind comparisonKind) {
+ this.evalLeftFactory = evalLeftFactory;
+ this.evalRightFactory = evalRightFactory;
+ this.comparisonKind = comparisonKind;
+ }
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ DataOutput out = output.getDataOutput();
+ switch (comparisonKind) {
+ // Should we do any normalization?
+ case EQ: {
+ return new EqualityComparisonEvaluator(out, evalLeftFactory, evalRightFactory);
+ }
+ case GE: {
+ return new GreaterThanOrEqualComparisonEvaluator(out, evalLeftFactory, evalRightFactory);
+ }
+ case GT: {
+ return new GreaterThanComparisonEvaluator(out, evalLeftFactory, evalRightFactory);
+ }
+ case LE: {
+ return new LessThanOrEqualComparisonEvaluator(out, evalLeftFactory, evalRightFactory);
+ }
+ case LT: {
+ return new LessThanComparisonEvaluator(out, evalLeftFactory, evalRightFactory);
+ }
+ case NEQ: {
+ return new InequalityComparisonEvaluator(out, evalLeftFactory, evalRightFactory);
+ }
+ default: {
+ throw new IllegalStateException();
+ }
+ }
+ }
+
+ static class EqualityComparisonEvaluator extends AbstractComparisonEvaluator {
+ public EqualityComparisonEvaluator(DataOutput out, IEvaluatorFactory evalLeftFactory,
+ IEvaluatorFactory evalRightFactory) throws AlgebricksException {
+ super(out, evalLeftFactory, evalRightFactory);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ evalInputs(tuple);
+ ComparisonResult r = compareResults();
+ if (r == ComparisonResult.UNKNOWN) {
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ ABoolean b = (r == ComparisonResult.EQUAL) ? ABoolean.TRUE : ABoolean.FALSE;
+ try {
+ serde.serialize(b, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ }
+
+ static class InequalityComparisonEvaluator extends AbstractComparisonEvaluator {
+ public InequalityComparisonEvaluator(DataOutput out, IEvaluatorFactory evalLeftFactory,
+ IEvaluatorFactory evalRightFactory) throws AlgebricksException {
+ super(out, evalLeftFactory, evalRightFactory);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ evalInputs(tuple);
+ ComparisonResult r = compareResults();
+ if (r == ComparisonResult.UNKNOWN) {
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ ABoolean b = (r != ComparisonResult.EQUAL) ? ABoolean.TRUE : ABoolean.FALSE;
+ try {
+ serde.serialize(b, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ }
+
+ static class GreaterThanOrEqualComparisonEvaluator extends AbstractComparisonEvaluator {
+ public GreaterThanOrEqualComparisonEvaluator(DataOutput out, IEvaluatorFactory evalLeftFactory,
+ IEvaluatorFactory evalRightFactory) throws AlgebricksException {
+ super(out, evalLeftFactory, evalRightFactory);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ evalInputs(tuple);
+ ComparisonResult r = compareResults();
+ if (r == ComparisonResult.UNKNOWN) {
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ ABoolean b = (r == ComparisonResult.EQUAL || r == ComparisonResult.GREATER_THAN) ? ABoolean.TRUE
+ : ABoolean.FALSE;
+ try {
+ serde.serialize(b, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ }
+
+ static class GreaterThanComparisonEvaluator extends AbstractComparisonEvaluator {
+ public GreaterThanComparisonEvaluator(DataOutput out, IEvaluatorFactory evalLeftFactory,
+ IEvaluatorFactory evalRightFactory) throws AlgebricksException {
+ super(out, evalLeftFactory, evalRightFactory);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ evalInputs(tuple);
+ ComparisonResult r = compareResults();
+ if (r == ComparisonResult.UNKNOWN) {
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ ABoolean b = (r == ComparisonResult.GREATER_THAN) ? ABoolean.TRUE : ABoolean.FALSE;
+ try {
+ serde.serialize(b, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ }
+
+ static class LessThanOrEqualComparisonEvaluator extends AbstractComparisonEvaluator {
+ public LessThanOrEqualComparisonEvaluator(DataOutput out, IEvaluatorFactory evalLeftFactory,
+ IEvaluatorFactory evalRightFactory) throws AlgebricksException {
+ super(out, evalLeftFactory, evalRightFactory);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ evalInputs(tuple);
+ ComparisonResult r = compareResults();
+ if (r == ComparisonResult.UNKNOWN) {
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ ABoolean b = (r == ComparisonResult.EQUAL || r == ComparisonResult.LESS_THAN) ? ABoolean.TRUE
+ : ABoolean.FALSE;
+ try {
+ serde.serialize(b, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ }
+
+ static class LessThanComparisonEvaluator extends AbstractComparisonEvaluator {
+ public LessThanComparisonEvaluator(DataOutput out, IEvaluatorFactory evalLeftFactory,
+ IEvaluatorFactory evalRightFactory) throws AlgebricksException {
+ super(out, evalLeftFactory, evalRightFactory);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ evalInputs(tuple);
+ ComparisonResult r = compareResults();
+ if (r == ComparisonResult.UNKNOWN) {
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ ABoolean b = (r == ComparisonResult.LESS_THAN) ? ABoolean.TRUE : ABoolean.FALSE;
+ try {
+ serde.serialize(b, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ABooleanConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ABooleanConstructorDescriptor.java
new file mode 100644
index 0000000..4d3b9cd
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ABooleanConstructorDescriptor.java
@@ -0,0 +1,92 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ABooleanConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "boolean", 1,
+ false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of boolean";
+ private final byte[] TRUE = { 0, 4, 't', 'r', 'u', 'e' };
+ private final byte[] FALSE = { 0, 5, 'f', 'a', 'l', 's', 'e' };
+ IBinaryComparator utf8BinaryComparator = AqlBinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE
+ .createBinaryComparator();
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ if (utf8BinaryComparator.compare(serString, 1, outInput.getLength(), TRUE, 0, 6) == 0) {
+ booleanSerde.serialize(ABoolean.TRUE, out);
+ return;
+ } else if (utf8BinaryComparator
+ .compare(serString, 1, outInput.getLength(), FALSE, 0, 7) == 0) {
+ booleanSerde.serialize(ABoolean.FALSE, out);
+ return;
+ } else
+ throw new AlgebricksException(errorMessage);
+
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ACircleConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ACircleConstructorDescriptor.java
new file mode 100644
index 0000000..9aee67e
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ACircleConstructorDescriptor.java
@@ -0,0 +1,87 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ACircle;
+import edu.uci.ics.asterix.om.base.AMutableCircle;
+import edu.uci.ics.asterix.om.base.AMutablePoint;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ACircleConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "circle", 1, true);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of circle";
+ private AMutablePoint aPoint = new AMutablePoint(0, 0);
+ private AMutableCircle aCircle = new AMutableCircle(null, 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ACircle> circleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ACIRCLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ String s = new String(serString, 3, outInput.getLength() - 3, "UTF-8");
+ int commaIndex = s.indexOf(',');
+ int spaceIndex = s.indexOf(' ', commaIndex + 1);
+ aPoint.setValue(Double.parseDouble(s.substring(0, commaIndex)),
+ Double.parseDouble(s.substring(commaIndex + 1, spaceIndex)));
+ aCircle.setValue(aPoint, Double.parseDouble(s.substring(spaceIndex + 1, s.length())));
+ circleSerde.serialize(aCircle, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java
new file mode 100644
index 0000000..c2aaca8
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java
@@ -0,0 +1,141 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADate;
+import edu.uci.ics.asterix.om.base.AMutableDate;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ADateConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "date", 1, false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private int offset;
+ private short year, month, day, hour, minute, value;
+ private byte timezonePart = 0;
+ private boolean positive = true;
+ private String errorMessage = "This can not be an instance of date";
+ private AMutableDate aDate = new AMutableDate(0, 0, 0, 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADate> dateSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ offset = 3;
+
+ if (serString[offset] == '-') {
+ offset++;
+ positive = false;
+ }
+
+ if (serString[offset + 4] != '-' || serString[offset + 7] != '-')
+ throw new AlgebricksException(errorMessage);
+
+ year = getValue(serString, offset, 4);
+ month = getValue(serString, offset + 5, 2);
+ day = getValue(serString, offset + 8, 2);
+
+ if (year < 0 || year > 9999 || month < 0 || month > 12 || day < 0 || day > 31)
+ throw new AlgebricksException(errorMessage);
+
+ offset += 10;
+
+ if (outInput.getLength() > offset) {
+ if (serString[offset] == 'Z')
+ timezonePart = 0;
+ else {
+ if ((serString[offset] != '+' && serString[offset] != '-')
+ || (serString[offset + 3] != ':'))
+ throw new AlgebricksException(errorMessage);
+
+ hour = getValue(serString, offset + 1, 2);
+ minute = getValue(serString, offset + 4, 2);
+
+ if (hour < 0 || hour > 24 || (hour == 24 && minute != 0)
+ || (minute != 0 && minute != 15 && minute != 30 && minute != 45))
+ throw new AlgebricksException(errorMessage);
+
+ if (serString[offset] == '-')
+ timezonePart = (byte) -((hour * 4) + minute / 15);
+ else
+ timezonePart = (byte) ((hour * 4) + minute / 15);
+ }
+
+ }
+
+ if (!positive)
+ year *= -1;
+
+ aDate.setValue(year, month, day, timezonePart);
+ dateSerde.serialize(aDate, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+
+ private short getValue(byte[] b, int offset, int numberOfDigits) throws AlgebricksException {
+ value = 0;
+ for (int i = 0; i < numberOfDigits; i++) {
+ if ((b[offset] >= '0' && b[offset] <= '9'))
+ value = (short) (value * 10 + b[offset++] - '0');
+ else
+ throw new AlgebricksException(errorMessage);
+
+ }
+ return value;
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java
new file mode 100644
index 0000000..5b79309
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java
@@ -0,0 +1,169 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADateTime;
+import edu.uci.ics.asterix.om.base.AMutableDateTime;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ADateTimeConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "datetime", 1,
+ false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private int offset;
+ private short hour, minute, second, msecond, year, month, day, timezoneHour, timezoneMinute, value;
+ private byte timezonePart = 0;
+ private boolean positive = true;
+ private String errorMessage = "This can not be an instance of datetime";
+ private AMutableDateTime aDateTime = new AMutableDateTime(0, 0, 0, 0, 0, 0, 0, 0, 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADateTime> datetimeSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATETIME);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+
+ offset = 3;
+ if (serString[offset] == '-') {
+ offset++;
+ positive = false;
+ }
+
+ if (serString[offset + 4] != '-' || serString[offset + 7] != '-')
+ throw new AlgebricksException(errorMessage);
+
+ year = getValue(serString, offset, 4);
+ month = getValue(serString, offset + 5, 2);
+ day = getValue(serString, offset + 8, 2);
+
+ if (year < 0 || year > 9999 || month < 0 || month > 12 || day < 0 || day > 31)
+ throw new AlgebricksException(errorMessage);
+
+ if (!positive)
+ year *= -1;
+
+ if (serString[offset + 10] != 'T')
+ throw new AlgebricksException(errorMessage);
+
+ offset += 11;
+
+ if (serString[offset + 2] != ':' || serString[offset + 5] != ':')
+ throw new AlgebricksException(errorMessage);
+
+ hour = getValue(serString, offset, 2);
+ minute = getValue(serString, offset + 3, 2);
+ second = getValue(serString, offset + 6, 2);
+
+ msecond = 0;
+ if (serString[offset + 8] == ':') {
+ msecond = getValue(serString, offset + 9, 3);
+ if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
+ || msecond < 0 || msecond > 999
+ || (hour == 24 && (minute != 0 || second != 0 || msecond != 0)))
+ throw new AlgebricksException(errorMessage);
+ offset += 12;
+ } else {
+ if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
+ || (hour == 24 && (minute != 0 || second != 0)))
+ throw new AlgebricksException(errorMessage);
+ offset += 8;
+ }
+
+ if (outInput.getLength() > offset) {
+ if (serString[offset] == 'Z')
+ timezonePart = 0;
+ else {
+ if ((serString[offset] != '+' && serString[offset] != '-')
+ || (serString[offset + 3] != ':'))
+ throw new AlgebricksException(errorMessage);
+
+ timezoneHour = getValue(serString, offset + 1, 2);
+ timezoneMinute = getValue(serString, offset + 4, 2);
+
+ if (timezoneHour < 0
+ || timezoneHour > 24
+ || (timezoneHour == 24 && timezoneMinute != 0)
+ || (timezoneMinute != 0 && timezoneMinute != 15 && timezoneMinute != 30 && timezoneMinute != 45))
+ throw new AlgebricksException(errorMessage);
+
+ if (serString[offset] == '-')
+ timezonePart = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
+ else
+ timezonePart = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+ }
+
+ }
+
+ aDateTime.setValue(year, month, day, hour, minute, second, msecond, 0, timezonePart);
+ datetimeSerde.serialize(aDateTime, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+
+ private short getValue(byte[] b, int offset, int numberOfDigits) throws AlgebricksException {
+ value = 0;
+ for (int i = 0; i < numberOfDigits; i++) {
+ if ((b[offset] >= '0' && b[offset] <= '9'))
+ value = (short) (value * 10 + b[offset++] - '0');
+ else
+ throw new AlgebricksException(errorMessage);
+
+ }
+ return value;
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADoubleConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADoubleConstructorDescriptor.java
new file mode 100644
index 0000000..48a35e4
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADoubleConstructorDescriptor.java
@@ -0,0 +1,198 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ADoubleConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "double", 1,
+ false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of double";
+ private final byte[] POSITIVE_INF = { 0, 3, 'I', 'N', 'F' };
+ private final byte[] NEGATIVE_INF = { 0, 4, '-', 'I', 'N', 'F' };
+ private final byte[] NAN = { 0, 3, 'N', 'a', 'N' };
+ // private int offset = 3, value = 0, integerPart = 0,
+ // fractionPart = 0, exponentPart = 0,
+ // pointIndex = 0, eIndex = 1;
+ // double doubleValue = 0;
+ // boolean positiveInteger = true, positiveExponent = true,
+ // expectingInteger = true,
+ // expectingFraction = false, expectingExponent = false;
+ IBinaryComparator utf8BinaryComparator = AqlBinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE
+ .createBinaryComparator();
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+
+ if (utf8BinaryComparator
+ .compare(serString, 1, outInput.getLength(), POSITIVE_INF, 0, 5) == 0) {
+ aDouble.setValue(Double.POSITIVE_INFINITY);
+ } else if (utf8BinaryComparator.compare(serString, 1, outInput.getLength(),
+ NEGATIVE_INF, 0, 6) == 0) {
+ aDouble.setValue(Double.NEGATIVE_INFINITY);
+ } else if (utf8BinaryComparator.compare(serString, 1, outInput.getLength(), NAN, 0, 5) == 0) {
+ aDouble.setValue(Double.NaN);
+ } else
+ // out.writeDouble(parseDouble(serString));
+ aDouble.setValue(Double.parseDouble(new String(serString, 3,
+ outInput.getLength() - 3, "UTF-8")));
+ doubleSerde.serialize(aDouble, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+
+ // private double parseDouble(byte[] serString) throws
+ // AlgebricksException {
+ //
+ // if (serString[offset] == '+')
+ // offset++;
+ // else if (serString[offset] == '-') {
+ // offset++;
+ // positiveInteger = false;
+ // }
+ //
+ // if ((serString[offset] == '.') || (serString[offset] ==
+ // 'e') || (serString[offset] == 'E')
+ // || (serString[outInput.getLength() - 1] == '.')
+ // || (serString[outInput.getLength() - 1] == 'E')
+ // || (serString[outInput.getLength() - 1] == 'e'))
+ // throw new AlgebricksException(errorMessage);
+ //
+ // for (; offset < outInput.getLength(); offset++) {
+ // if (serString[offset] >= '0' && serString[offset] <= '9')
+ // {
+ // value = value * 10 + serString[offset] - '0';
+ // } else
+ // switch (serString[offset]) {
+ // case '.':
+ // if (expectingInteger) {
+ // if (serString[offset + 1] < '0' || serString[offset + 1]
+ // > '9')
+ // throw new AlgebricksException(errorMessage);
+ // expectingInteger = false;
+ // expectingFraction = true;
+ // integerPart = value;
+ // value = 0;
+ // pointIndex = offset;
+ // eIndex = outInput.getLength();
+ // } else
+ // throw new AlgebricksException(errorMessage);
+ // break;
+ // case 'e':
+ // case 'E':
+ // if (expectingInteger) {
+ // expectingInteger = false;
+ // integerPart = value;
+ // pointIndex = offset - 1;
+ // eIndex = offset;
+ // value = 0;
+ // expectingExponent = true;
+ // } else if (expectingFraction) {
+ //
+ // expectingFraction = false;
+ // fractionPart = value;
+ // eIndex = offset;
+ // value = 0;
+ // expectingExponent = true;
+ // } else
+ // throw new AlgebricksException();
+ //
+ // if (serString[offset + 1] == '+')
+ // offset++;
+ // else if (serString[offset + 1] == '-') {
+ // offset++;
+ // positiveExponent = false;
+ // } else if (serString[offset + 1] < '0' ||
+ // serString[offset + 1] > '9')
+ // throw new AlgebricksException(errorMessage);
+ // break;
+ // default:
+ // throw new AlgebricksException(errorMessage);
+ // }
+ // }
+ //
+ // if (expectingInteger)
+ // integerPart = value;
+ // else if (expectingFraction)
+ // fractionPart = value;
+ // else if (expectingExponent)
+ // exponentPart = value * (positiveExponent ? 1 : -1);
+ //
+ // doubleValue = (float) (integerPart + (fractionPart * (1 /
+ // Math.pow(10, eIndex - pointIndex - 1))));
+ // doubleValue *= (float) Math.pow(10.0, exponentPart);
+ // if (integerPart != 0
+ // && (doubleValue == Float.POSITIVE_INFINITY || doubleValue
+ // == Float.NEGATIVE_INFINITY || doubleValue == 0))
+ // throw new AlgebricksException(errorMessage);
+ //
+ // if (doubleValue > 0 && !positiveInteger)
+ // doubleValue *= -1;
+ //
+ // return doubleValue;
+ // }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADurationConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADurationConstructorDescriptor.java
new file mode 100644
index 0000000..f014ad6
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADurationConstructorDescriptor.java
@@ -0,0 +1,190 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADuration;
+import edu.uci.ics.asterix.om.base.AMutableDuration;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ADurationConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "duration", 1,
+ false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private int offset;
+ private int value = 0, hour = 0, minute = 0, second = 0, year = 0, month = 0, day = 0;
+ private boolean isYear = true, isMonth = true, isDay = true, isHour = true, isMinute = true,
+ isSecond = true, isTime = false, timeItem = true, positive = true;
+ private String errorMessage = "This can not be an instance of duration";
+ private AMutableDuration aDuration = new AMutableDuration(0, 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADuration> durationSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADURATION);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ offset = 3;
+ if (serString[offset] == '-') {
+ offset++;
+ positive = false;
+ }
+ if (serString[offset++] != 'D')
+ throw new AlgebricksException(errorMessage);
+
+ for (; offset < outInput.getLength(); offset++) {
+ if (serString[offset] >= '0' && serString[offset] <= '9')
+ value = value * 10 + serString[offset] - '0';
+ else {
+ switch (serString[offset]) {
+ case 'Y':
+ if (isYear) {
+ year = value;
+ isYear = false;
+ } else
+ throw new AlgebricksException(errorMessage);
+ break;
+ case 'M':
+ if (!isTime) {
+ if (isMonth) {
+ if (value < 0 || value > 11)
+ throw new AlgebricksException(errorMessage);
+ else {
+ month = value;
+ isMonth = false;
+ }
+ } else
+ throw new AlgebricksException(errorMessage);
+ } else if (isMinute) {
+ if (value < 0 || value > 59)
+ throw new AlgebricksException(errorMessage);
+ else {
+ minute = value;
+ isMinute = false;
+ timeItem = false;
+ }
+ } else
+ throw new AlgebricksException(errorMessage);
+ break;
+ case 'D':
+ if (isDay) {
+ if (value < 0 || value > 30)
+ throw new AlgebricksException(errorMessage);
+ else {
+ day = value;
+ isDay = false;
+ }
+ } else
+ throw new AlgebricksException(errorMessage);
+ break;
+ case 'T':
+ if (!isTime) {
+ isTime = true;
+ timeItem = true;
+ } else
+ throw new AlgebricksException(errorMessage);
+ break;
+
+ case 'H':
+ if (isHour) {
+ if (value < 0 || value > 23)
+ throw new AlgebricksException(errorMessage);
+ else {
+ hour = value;
+ isHour = false;
+ timeItem = false;
+ }
+ } else
+ throw new AlgebricksException(errorMessage);
+ break;
+ case 'S':
+ if (isSecond) {
+ if (value < 0 || value > 59)
+ throw new AlgebricksException(errorMessage);
+ else {
+ second = value;
+ isSecond = false;
+ timeItem = false;
+ }
+ } else
+ throw new AlgebricksException(errorMessage);
+ break;
+ default:
+ throw new AlgebricksException(errorMessage);
+
+ }
+ value = 0;
+ }
+ }
+
+ if (isTime && timeItem)
+ throw new AlgebricksException(errorMessage);
+
+ if (isYear && isMonth && isDay && !isTime)
+ throw new AlgebricksException(errorMessage);
+
+ if (positive)
+ aDuration.setValue(year * 12 + month, day * 24 * 3600 + 3600 * hour + 60 * minute
+ + second);
+ else
+ aDuration.setValue(-1 * (year * 12 + month), -1
+ * (day * 24 * 3600 + 3600 * hour + 60 * minute + second));
+ durationSerde.serialize(aDuration, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AFloatConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AFloatConstructorDescriptor.java
new file mode 100644
index 0000000..0af6328
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AFloatConstructorDescriptor.java
@@ -0,0 +1,199 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AFloat;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AFloatConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "float", 1, false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of float";
+ private final byte[] POSITIVE_INF = { 0, 3, 'I', 'N', 'F' };
+ private final byte[] NEGATIVE_INF = { 0, 4, '-', 'I', 'N', 'F' };
+ private final byte[] NAN = { 0, 3, 'N', 'a', 'N' };
+ // private int offset = 3, value = 0, pointIndex = 0, eIndex
+ // = 1;
+ // private int integerPart = 0, fractionPart = 0,
+ // exponentPart = 0;
+ // float floatValue = 0;
+ // boolean positiveInteger = true, positiveExponent = true,
+ // expectingInteger = true,
+ // expectingFraction = false, expectingExponent = false;
+ IBinaryComparator utf8BinaryComparator = AqlBinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE
+ .createBinaryComparator();
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AFloat> floatSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ if (utf8BinaryComparator
+ .compare(serString, 1, outInput.getLength(), POSITIVE_INF, 0, 5) == 0) {
+ aFloat.setValue(Float.POSITIVE_INFINITY);
+ } else if (utf8BinaryComparator.compare(serString, 1, outInput.getLength(),
+ NEGATIVE_INF, 0, 6) == 0) {
+ aFloat.setValue(Float.NEGATIVE_INFINITY);
+ } else if (utf8BinaryComparator.compare(serString, 1, outInput.getLength(), NAN, 0, 5) == 0) {
+ aFloat.setValue(Float.NaN);
+ } else
+ aFloat.setValue(Float.parseFloat(new String(serString, 3, outInput.getLength() - 3,
+ "UTF-8")));
+ floatSerde.serialize(aFloat, out);
+
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+
+ // private float parseFloat(byte[] serString) throws
+ // AlgebricksException {
+ //
+ // if (serString[offset] == '+')
+ // offset++;
+ // else if (serString[offset] == '-') {
+ // offset++;
+ // positiveInteger = false;
+ // }
+ //
+ // if ((serString[offset] == '.') || (serString[offset] ==
+ // 'e') || (serString[offset] == 'E')
+ // || (serString[outInput.getLength() - 1] == '.')
+ // || (serString[outInput.getLength() - 1] == 'E')
+ // || (serString[outInput.getLength() - 1] == 'e'))
+ // throw new AlgebricksException(errorMessage);
+ //
+ // for (; offset < outInput.getLength(); offset++) {
+ // if (serString[offset] >= '0' && serString[offset] <= '9')
+ // {
+ // value = value * 10 + serString[offset] - '0';
+ // } else
+ // switch (serString[offset]) {
+ // case '.':
+ // if (expectingInteger) {
+ // if (serString[offset + 1] < '0' || serString[offset + 1]
+ // > '9')
+ // throw new AlgebricksException(errorMessage);
+ // expectingInteger = false;
+ // expectingFraction = true;
+ // integerPart = value;
+ // value = 0;
+ // pointIndex = offset;
+ // eIndex = outInput.getLength();
+ // } else
+ // throw new AlgebricksException(errorMessage);
+ // break;
+ // case 'e':
+ // case 'E':
+ // if (expectingInteger) {
+ // expectingInteger = false;
+ // integerPart = value;
+ // pointIndex = offset - 1;
+ // eIndex = offset;
+ // value = 0;
+ // expectingExponent = true;
+ // } else if (expectingFraction) {
+ //
+ // expectingFraction = false;
+ // fractionPart = value;
+ // eIndex = offset;
+ // value = 0;
+ // expectingExponent = true;
+ // } else
+ // throw new AlgebricksException();
+ //
+ // if (serString[offset + 1] == '+')
+ // offset++;
+ // else if (serString[offset + 1] == '-') {
+ // offset++;
+ // positiveExponent = false;
+ // } else if (serString[offset + 1] < '0' ||
+ // serString[offset + 1] > '9')
+ // throw new AlgebricksException(errorMessage);
+ // break;
+ // default:
+ // throw new AlgebricksException(errorMessage);
+ // }
+ // }
+ //
+ // if (expectingInteger)
+ // integerPart = value;
+ // else if (expectingFraction)
+ // fractionPart = value;
+ // else if (expectingExponent)
+ // exponentPart = value * (positiveExponent ? 1 : -1);
+ //
+ // // floatValue = (float) ( integerPart + ( fractionPart *
+ // (1.0f / Math.pow(10.0f, eIndex - pointIndex - 1))));
+ // // floatValue *= (float) Math.pow(10.0f, exponentPart);
+ //
+ // floatValue = Float.parseFloat(integerPart+"."+
+ // fractionPart+"e"+ exponentPart);
+ //
+ // if (integerPart != 0
+ // && (floatValue == Float.POSITIVE_INFINITY || floatValue
+ // == Float.NEGATIVE_INFINITY || floatValue == 0))
+ // throw new AlgebricksException(errorMessage);
+ //
+ // if (floatValue > 0 && !positiveInteger)
+ // floatValue *= -1;
+ //
+ // return floatValue;
+ // }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt16ConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt16ConstructorDescriptor.java
new file mode 100644
index 0000000..5aa7b02
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt16ConstructorDescriptor.java
@@ -0,0 +1,106 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AInt16ConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "int16", 1, false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private short value;
+ private int offset;
+ private boolean positive;
+ private String errorMessage = "This can not be an instance of int16";
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt16> int16Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ offset = 3;
+ value = 0;
+ positive = true;
+ if (serString[offset] == '+')
+ offset++;
+ else if (serString[offset] == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < outInput.getLength(); offset++) {
+ if (serString[offset] >= '0' && serString[offset] <= '9')
+ value = (short) (value * 10 + serString[offset] - '0');
+ else if (serString[offset] == 'i' && serString[offset + 1] == '1'
+ && serString[offset + 2] == '6' && offset + 3 == outInput.getLength())
+ break;
+ else
+ throw new AlgebricksException(errorMessage);
+ }
+ if (value < 0)
+ throw new AlgebricksException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+
+ aInt16.setValue(value);
+ int16Serde.serialize(aInt16, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt32ConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt32ConstructorDescriptor.java
new file mode 100644
index 0000000..41dea45
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt32ConstructorDescriptor.java
@@ -0,0 +1,105 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AInt32ConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "int32", 1, false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private int value, offset;
+ private boolean positive;
+ private String errorMessage = "This can not be an instance of int32";
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ offset = 3;
+ value = 0;
+ positive = true;
+ if (serString[offset] == '+')
+ offset++;
+ else if (serString[offset] == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < outInput.getLength(); offset++) {
+ if (serString[offset] >= '0' && serString[offset] <= '9')
+ value = value * 10 + serString[offset] - '0';
+ else if (serString[offset] == 'i' && serString[offset + 1] == '3'
+ && serString[offset + 2] == '2' && offset + 3 == outInput.getLength())
+ break;
+ else
+ throw new AlgebricksException(errorMessage);
+ }
+ if (value < 0)
+ throw new AlgebricksException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+
+ aInt32.setValue(value);
+ int32Serde.serialize(aInt32, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt64ConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt64ConstructorDescriptor.java
new file mode 100644
index 0000000..2528f11
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt64ConstructorDescriptor.java
@@ -0,0 +1,106 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AInt64ConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "int64", 1, false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private long value;
+ private int offset;
+ private boolean positive;
+ private String errorMessage = "This can not be an instance of int64";
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt64> int64Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ offset = 3;
+ value = 0;
+ positive = true;
+ if (serString[offset] == '+')
+ offset++;
+ else if (serString[offset] == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < outInput.getLength(); offset++) {
+ if (serString[offset] >= '0' && serString[offset] <= '9')
+ value = value * 10 + serString[offset] - '0';
+ else if (serString[offset] == 'i' && serString[offset + 1] == '6'
+ && serString[offset + 2] == '4' && offset + 3 == outInput.getLength())
+ break;
+ else
+ throw new AlgebricksException(errorMessage);
+ }
+ if (value < 0)
+ throw new AlgebricksException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+
+ aInt64.setValue(value);
+ int64Serde.serialize(aInt64, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt8ConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt8ConstructorDescriptor.java
new file mode 100644
index 0000000..acd7d12
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AInt8ConstructorDescriptor.java
@@ -0,0 +1,106 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt8;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AInt8ConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "int8", 1, false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private byte value;
+ private int offset;
+ private boolean positive;
+ private String errorMessage = "This can not be an instance of int8";
+ private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt8> int8Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ offset = 3;
+ value = 0;
+ positive = true;
+ if (serString[offset] == '+')
+ offset++;
+ else if (serString[offset] == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < outInput.getLength(); offset++) {
+ if (serString[offset] >= '0' && serString[offset] <= '9')
+ value = (byte) (value * 10 + serString[offset] - '0');
+ else if (serString[offset] == 'i' && serString[offset + 1] == '8'
+ && offset + 2 == outInput.getLength())
+ break;
+ else
+ throw new AlgebricksException(errorMessage);
+ }
+ if (value < 0)
+ throw new AlgebricksException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+
+ aInt8.setValue(value);
+ int8Serde.serialize(aInt8, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ALineConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ALineConstructorDescriptor.java
new file mode 100644
index 0000000..d13d646
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ALineConstructorDescriptor.java
@@ -0,0 +1,90 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ALine;
+import edu.uci.ics.asterix.om.base.AMutableLine;
+import edu.uci.ics.asterix.om.base.AMutablePoint;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ALineConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "line", 1, true);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of line";
+ private AMutableLine aLine = new AMutableLine(null, null);
+ private AMutablePoint[] aPoint = { new AMutablePoint(0, 0), new AMutablePoint(0, 0) };
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ALine> lineSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ALINE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ String s = new String(serString, 3, outInput.getLength() - 3, "UTF-8");
+ int commaIndex = s.indexOf(',');
+ int spaceIndex = s.indexOf(' ', commaIndex + 1);
+ aPoint[0].setValue(Double.parseDouble(s.substring(0, commaIndex)),
+ Double.parseDouble(s.substring(commaIndex + 1, spaceIndex)));
+ commaIndex = s.indexOf(',', spaceIndex + 1);
+ aPoint[1].setValue(Double.parseDouble(s.substring(spaceIndex + 1, commaIndex)),
+ Double.parseDouble(s.substring(commaIndex + 1, s.length())));
+ aLine.setValue(aPoint[0], aPoint[1]);
+ lineSerde.serialize(aLine, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ANullConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ANullConstructorDescriptor.java
new file mode 100644
index 0000000..a706b7b
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ANullConstructorDescriptor.java
@@ -0,0 +1,78 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ANullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "null", 1, false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of null";
+ private final byte[] NULL = { 0, 4, 'n', 'u', 'l', 'l' };
+ IBinaryComparator utf8BinaryComparator = AqlBinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE
+ .createBinaryComparator();
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ if (utf8BinaryComparator.compare(serString, 1, outInput.getLength(), NULL, 0, 6) == 0) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ } else
+ throw new AlgebricksException(errorMessage);
+ } else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/APoint3DConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/APoint3DConstructorDescriptor.java
new file mode 100644
index 0000000..b5b4392
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/APoint3DConstructorDescriptor.java
@@ -0,0 +1,87 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutablePoint3D;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.APoint3D;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class APoint3DConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "point3d", 1,
+ true);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of point3d";
+ private AMutablePoint3D aPoint3D = new AMutablePoint3D(0, 0, 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<APoint3D> point3DSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.APOINT3D);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ String s = new String(serString, 3, outInput.getLength() - 3, "UTF-8");
+ int firstCommaIndex = s.indexOf(',');
+ int secondCommaIndex = s.indexOf(',', firstCommaIndex + 1);
+ aPoint3D.setValue(Double.parseDouble(s.substring(0, firstCommaIndex)),
+ Double.parseDouble(s.substring(firstCommaIndex + 1, secondCommaIndex)),
+ Double.parseDouble(s.substring(secondCommaIndex + 1, s.length())));
+ point3DSerde.serialize(aPoint3D, out);
+
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/APointConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/APointConstructorDescriptor.java
new file mode 100644
index 0000000..f036207
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/APointConstructorDescriptor.java
@@ -0,0 +1,82 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutablePoint;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.APoint;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class APointConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "point", 1, true);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of point";
+ private AMutablePoint aPoint = new AMutablePoint(0, 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<APoint> pointSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.APOINT);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ String s = new String(serString, 3, outInput.getLength() - 3, "UTF-8");
+ aPoint.setValue(Double.parseDouble(s.substring(0, s.indexOf(','))),
+ Double.parseDouble(s.substring(s.indexOf(',') + 1, s.length())));
+ pointSerde.serialize(aPoint, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/APolygonConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/APolygonConstructorDescriptor.java
new file mode 100644
index 0000000..ef2ba05
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/APolygonConstructorDescriptor.java
@@ -0,0 +1,84 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class APolygonConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "polygon", 1,
+ true);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_POLYGON_TYPE_TAG = ATypeTag.POLYGON.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of polygon";
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ String s = new String(serString, 3, outInput.getLength() - 3, "UTF-8");
+ String[] points = s.split(" ");
+ if (points.length <= 2)
+ throw new AlgebricksException(errorMessage);
+ out.writeByte(SER_POLYGON_TYPE_TAG);
+ out.writeShort(points.length);
+ for (int i = 0; i < points.length; i++)
+ APointSerializerDeserializer.serialize(Double.parseDouble(points[i].split(",")[0]),
+ Double.parseDouble(points[i].split(",")[1]), out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ARectangleConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ARectangleConstructorDescriptor.java
new file mode 100644
index 0000000..c7e2de7
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ARectangleConstructorDescriptor.java
@@ -0,0 +1,95 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutablePoint;
+import edu.uci.ics.asterix.om.base.AMutableRectangle;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.ARectangle;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ARectangleConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "rectangle", 1,
+ true);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of rectangle";
+ private AMutableRectangle aRectangle = new AMutableRectangle(null, null);
+ private AMutablePoint[] aPoint = { new AMutablePoint(0, 0), new AMutablePoint(0, 0) };
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ARectangle> rectangle2DSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ARECTANGLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ String s = new String(serString, 3, outInput.getLength() - 3, "UTF-8");
+ int commaIndex = s.indexOf(',');
+ int spaceIndex = s.indexOf(' ', commaIndex + 1);
+ aPoint[0].setValue(Double.parseDouble(s.substring(0, commaIndex)),
+ Double.parseDouble(s.substring(commaIndex + 1, spaceIndex)));
+ commaIndex = s.indexOf(',', spaceIndex + 1);
+ aPoint[1].setValue(Double.parseDouble(s.substring(spaceIndex + 1, commaIndex)),
+ Double.parseDouble(s.substring(commaIndex + 1, s.length())));
+ if (aPoint[0].getX() > aPoint[1].getX() || aPoint[0].getY() > aPoint[1].getY()) {
+ throw new IllegalArgumentException(
+ "The low point in the rectangle cannot be larger than the high point");
+ }
+ aRectangle.setValue(aPoint[0], aPoint[1]);
+ rectangle2DSerde.serialize(aRectangle, out);
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AStringConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AStringConstructorDescriptor.java
new file mode 100644
index 0000000..361220e
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AStringConstructorDescriptor.java
@@ -0,0 +1,73 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AStringConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "string", 1,
+ false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private String errorMessage = "This can not be an instance of string";
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ out.write(outInput.getBytes(), outInput.getStartIndex(), outInput.getLength());
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
new file mode 100644
index 0000000..0f86b94
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
@@ -0,0 +1,142 @@
+package edu.uci.ics.asterix.runtime.evaluators.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableTime;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.ATime;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ATimeConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "time", 1, false);
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(outInput);
+ private int offset;
+ private short hour, minute, second, msecond, timezoneHour, timezoneMinute, value;
+ private byte timezonePart = 0;
+ private String errorMessage = "This can not be an instance of time";
+ private AMutableTime aTime = new AMutableTime(0, 0, 0, 0, 0, 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ATime> timeSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ATIME);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput.reset();
+ eval.evaluate(tuple);
+ byte[] serString = outInput.getBytes();
+ if (serString[0] == SER_STRING_TYPE_TAG) {
+ offset = 3;
+ if (serString[offset + 2] != ':' || serString[offset + 5] != ':')
+ throw new AlgebricksException(errorMessage);
+
+ hour = getValue(serString, offset, 2);
+ minute = getValue(serString, offset + 3, 2);
+ second = getValue(serString, offset + 6, 2);
+ msecond = 0;
+
+ if (serString[offset + 8] == ':') {
+ msecond = getValue(serString, offset + 9, 3);
+ if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
+ || msecond < 0 || msecond > 999
+ || (hour == 24 && (minute != 0 || second != 0 || msecond != 0)))
+ throw new AlgebricksException(errorMessage);
+ offset += 12;
+ } else {
+ if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59
+ || (hour == 24 && (minute != 0 || second != 0)))
+ throw new AlgebricksException(errorMessage);
+ offset += 8;
+ }
+
+ if (outInput.getLength() > offset) {
+ if (serString[offset] == 'Z')
+ timezonePart = 0;
+ else {
+ if ((serString[offset] != '+' && serString[offset] != '-')
+ || (serString[offset + 3] != ':'))
+ throw new AlgebricksException(errorMessage);
+
+ timezoneHour = getValue(serString, offset + 1, 2);
+ timezoneMinute = getValue(serString, offset + 4, 2);
+
+ if (timezoneHour < 0
+ || timezoneHour > 24
+ || (timezoneHour == 24 && timezoneMinute != 0)
+ || (timezoneMinute != 0 && timezoneMinute != 15 && timezoneMinute != 30 && timezoneMinute != 45))
+ throw new AlgebricksException(errorMessage);
+
+ if (serString[offset] == '-')
+ timezonePart = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
+ else
+ timezonePart = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+ }
+ }
+
+ aTime.setValue(hour, minute, second, msecond, 0, timezonePart);
+ timeSerde.serialize(aTime, out);
+
+ } else if (serString[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (IOException e1) {
+ throw new AlgebricksException(errorMessage);
+ }
+ }
+
+ private short getValue(byte[] b, int offset, int numberOfDigits) throws AlgebricksException {
+ value = 0;
+ for (int i = 0; i < numberOfDigits; i++) {
+ if ((b[offset] >= '0' && b[offset] <= '9'))
+ value = (short) (value * 10 + b[offset++] - '0');
+ else
+ throw new AlgebricksException(errorMessage);
+ }
+ return value;
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractStringContainsEval.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractStringContainsEval.java
new file mode 100644
index 0000000..ba6a644
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractStringContainsEval.java
@@ -0,0 +1,54 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public abstract class AbstractStringContainsEval implements IEvaluator {
+
+ private DataOutput dout;
+
+ private ArrayBackedValueStorage array0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage array1 = new ArrayBackedValueStorage();
+ private IEvaluator evalString;
+ private IEvaluator evalPattern;
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer boolSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+
+ public AbstractStringContainsEval(DataOutput dout, IEvaluatorFactory evalStringFactory,
+ IEvaluatorFactory evalPatternFactory) throws AlgebricksException {
+ this.dout = dout;
+ this.evalString = evalStringFactory.createEvaluator(array0);
+ this.evalPattern = evalPatternFactory.createEvaluator(array1);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ array1.reset();
+ evalPattern.evaluate(tuple);
+ array0.reset();
+ evalString.evaluate(tuple);
+ byte[] b1 = array0.getBytes();
+ byte[] b2 = array1.getBytes();
+ ABoolean res = findMatch(b1, b2) ? ABoolean.TRUE : ABoolean.FALSE;
+ try {
+ boolSerde.serialize(res, dout);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ protected abstract boolean findMatch(byte[] strBytes, byte[] patternBytes);
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AndDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AndDescriptor.java
new file mode 100644
index 0000000..eb361be
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AndDescriptor.java
@@ -0,0 +1,92 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AndDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS,
+ "and", FunctionIdentifier.VARARGS, true);
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ // one temp. buffer re-used by all children
+ final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ final IEvaluator[] evals = new IEvaluator[args.length];
+ for (int i = 0; i < evals.length; i++) {
+ evals[i] = args[i].createEvaluator(argOut);
+ }
+
+ return new IEvaluator() {
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ int n = args.length;
+ boolean res = true;
+ boolean metNull = false;
+ for (int i = 0; i < n; i++) {
+ argOut.reset();
+ evals[i].evaluate(tuple);
+ if (argOut.getBytes()[0] == SER_NULL_TYPE_TAG) {
+ metNull = true;
+ continue;
+ }
+ boolean argResult = ABooleanSerializerDeserializer.getBoolean(argOut.getBytes(), 1);
+ res = res && argResult;
+ }
+ if (metNull) {
+ if (!res) {
+ ABoolean aResult = ABoolean.FALSE;
+ booleanSerde.serialize(aResult, output.getDataOutput());
+ } else
+ nullSerde.serialize(ANull.NULL, output.getDataOutput());
+ } else {
+ ABoolean aResult = res ? (ABoolean.TRUE) : (ABoolean.FALSE);
+ booleanSerde.serialize(aResult, output.getDataOutput());
+ }
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AnyCollectionMemberDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AnyCollectionMemberDescriptor.java
new file mode 100644
index 0000000..0710283
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AnyCollectionMemberDescriptor.java
@@ -0,0 +1,129 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AUnorderedListSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class AnyCollectionMemberDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "any-collection-member", 1, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new AnyCollectionMemberEvalFactory(args[0]);
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ private static class AnyCollectionMemberEvalFactory implements IEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ private IEvaluatorFactory listEvalFactory;
+ private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+ private final static byte SER_UNORDEREDLIST_TYPE_TAG = ATypeTag.UNORDEREDLIST.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private byte serItemTypeTag;
+ private ATypeTag itemTag;
+ private boolean selfDescList = false;
+
+ public AnyCollectionMemberEvalFactory(IEvaluatorFactory arg) {
+ this.listEvalFactory = arg;
+ }
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage outInputList = new ArrayBackedValueStorage();
+ private IEvaluator evalList = listEvalFactory.createEvaluator(outInputList);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private int itemOffset;
+ private int itemLength;
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInputList.reset();
+ evalList.evaluate(tuple);
+ byte[] serList = outInputList.getBytes();
+
+ if (serList[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (serList[0] != SER_ORDEREDLIST_TYPE_TAG && serList[0] != SER_UNORDEREDLIST_TYPE_TAG) {
+ throw new AlgebricksException("List's get-any-item is not defined for values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[0]));
+ }
+
+ if (serList[0] == SER_ORDEREDLIST_TYPE_TAG) {
+ if (AOrderedListSerializerDeserializer.getNumberOfItems(serList) == 0) {
+ out.writeByte(SER_NULL_TYPE_TAG);
+ return;
+ }
+ itemOffset = AOrderedListSerializerDeserializer.getItemOffset(serList, 0);
+ } else {
+ if (AUnorderedListSerializerDeserializer.getNumberOfItems(serList) == 0) {
+ out.writeByte(SER_NULL_TYPE_TAG);
+ return;
+ }
+ itemOffset = AUnorderedListSerializerDeserializer.getItemOffset(serList, 0);
+ }
+
+ itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[1]);
+ if (itemTag == ATypeTag.ANY)
+ selfDescList = true;
+ else
+ serItemTypeTag = serList[1];
+
+ if (selfDescList) {
+ itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[itemOffset]);
+ itemLength = NonTaggedFormatUtil.getFieldValueLength(serList, itemOffset, itemTag, true) + 1;
+ out.write(serList, itemOffset, itemLength);
+ } else {
+ itemLength = NonTaggedFormatUtil.getFieldValueLength(serList, itemOffset, itemTag, false);
+ out.writeByte(serItemTypeTag);
+ out.write(serList, itemOffset, itemLength);
+ }
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/ClosedRecordConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/ClosedRecordConstructorDescriptor.java
new file mode 100644
index 0000000..8dfaf69
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/ClosedRecordConstructorDescriptor.java
@@ -0,0 +1,33 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.ClosedRecordConstructorEvalFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+
+public class ClosedRecordConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ protected static final FunctionIdentifier FID_CLOSED = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "closed-record-constructor", FunctionIdentifier.VARARGS, true);
+
+ private static final long serialVersionUID = 1L;
+
+ private ARecordType recType;
+
+ public void reset(ARecordType recType) {
+ this.recType = recType;
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID_CLOSED;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new ClosedRecordConstructorEvalFactory(args, recType);
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/ContainsDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/ContainsDescriptor.java
new file mode 100644
index 0000000..611a67b
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/ContainsDescriptor.java
@@ -0,0 +1,77 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.util.StringUtils;
+
+public class ContainsDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "contains", 2,
+ true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+ DataOutput dout = output.getDataOutput();
+
+ return new AbstractStringContainsEval(dout, args[0], args[1]) {
+
+ @Override
+ protected boolean findMatch(byte[] strBytes, byte[] patternBytes) {
+ int utflen1 = UTF8StringPointable.getUTFLen(strBytes, 1);
+ int utflen2 = UTF8StringPointable.getUTFLen(patternBytes, 1);
+
+ int s1Start = 3;
+ int s2Start = 3;
+
+ boolean matches = false;
+ int maxStart = utflen1 - utflen2;
+ int startMatch = 0;
+ while (startMatch <= maxStart) {
+ int c1 = startMatch;
+ int c2 = 0;
+ while (c1 < utflen1 && c2 < utflen2) {
+ char ch1 = UTF8StringPointable.charAt(strBytes, s1Start + c1);
+ char ch2 = UTF8StringPointable.charAt(patternBytes, s2Start + c2);
+
+ if (ch1 != ch2) {
+ break;
+ }
+ c1 += UTF8StringPointable.charSize(strBytes, s1Start + c1);
+ c2 += UTF8StringPointable.charSize(patternBytes, s2Start + c2);
+ }
+ if (c2 == utflen2) {
+ matches = true;
+ break;
+ }
+ startMatch += UTF8StringPointable.charSize(strBytes, s1Start + startMatch);
+ }
+ return matches;
+ }
+
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CountHashedGramTokensDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CountHashedGramTokensDescriptor.java
new file mode 100644
index 0000000..46ec534
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CountHashedGramTokensDescriptor.java
@@ -0,0 +1,45 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.GramTokensEvaluator;
+import edu.uci.ics.fuzzyjoin.tokenizer.HashedUTF8NGramTokenFactory;
+import edu.uci.ics.fuzzyjoin.tokenizer.ITokenFactory;
+import edu.uci.ics.fuzzyjoin.tokenizer.NGramUTF8StringBinaryTokenizer;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+public class CountHashedGramTokensDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "counthashed-gram-tokens", 3, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ ITokenFactory tokenFactory = new HashedUTF8NGramTokenFactory(ATypeTag.INT32.serialize(),
+ ATypeTag.INT32.serialize());
+ NGramUTF8StringBinaryTokenizer tokenizer = new NGramUTF8StringBinaryTokenizer(3, true, false, true,
+ tokenFactory);
+ return new GramTokensEvaluator(args, output, tokenizer, BuiltinType.AINT32);
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CountHashedWordTokensDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CountHashedWordTokensDescriptor.java
new file mode 100644
index 0000000..d20d23d
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CountHashedWordTokensDescriptor.java
@@ -0,0 +1,45 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.WordTokensEvaluator;
+import edu.uci.ics.fuzzyjoin.tokenizer.DelimitedUTF8StringBinaryTokenizer;
+import edu.uci.ics.fuzzyjoin.tokenizer.HashedUTF8WordTokenFactory;
+import edu.uci.ics.fuzzyjoin.tokenizer.IBinaryTokenizer;
+import edu.uci.ics.fuzzyjoin.tokenizer.ITokenFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+public class CountHashedWordTokensDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "counthashed-word-tokens", 1, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ ITokenFactory tokenFactory = new HashedUTF8WordTokenFactory(ATypeTag.INT32.serialize(),
+ ATypeTag.INT32.serialize());
+ IBinaryTokenizer tokenizer = new DelimitedUTF8StringBinaryTokenizer(false, true, tokenFactory);
+ return new WordTokensEvaluator(args, output, tokenizer, BuiltinType.AINT32);
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateCircleDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateCircleDescriptor.java
new file mode 100644
index 0000000..ecb6bff
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateCircleDescriptor.java
@@ -0,0 +1,80 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.Coordinate;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ACircle;
+import edu.uci.ics.asterix.om.base.AMutableCircle;
+import edu.uci.ics.asterix.om.base.AMutablePoint;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class CreateCircleDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "create-circle",
+ 2, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private IEvaluator eval0 = args[0].createEvaluator(outInput0);
+ private IEvaluator eval1 = args[1].createEvaluator(outInput1);
+ private AMutablePoint aPoint = new AMutablePoint(0, 0);
+ private AMutableCircle aCircle = new AMutableCircle(null, 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ACircle> circleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ACIRCLE);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+
+ try {
+ aPoint.setValue(ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X)),
+ ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y)));
+ aCircle.setValue(aPoint, ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(), 1));
+ circleSerde.serialize(aCircle, out);
+ } catch (IOException e1) {
+ throw new AlgebricksException(e1);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateLineDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateLineDescriptor.java
new file mode 100644
index 0000000..9ecd011
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateLineDescriptor.java
@@ -0,0 +1,84 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.Coordinate;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ALine;
+import edu.uci.ics.asterix.om.base.AMutableLine;
+import edu.uci.ics.asterix.om.base.AMutablePoint;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class CreateLineDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "create-line", 2,
+ true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private IEvaluator eval0 = args[0].createEvaluator(outInput0);
+ private IEvaluator eval1 = args[1].createEvaluator(outInput1);
+ private AMutableLine aLine = new AMutableLine(null, null);
+ private AMutablePoint[] aPoint = { new AMutablePoint(0, 0), new AMutablePoint(0, 0) };
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ALine> lineSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ALINE);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+
+ try {
+ aPoint[0].setValue(ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X)),
+ ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y)));
+ aPoint[1].setValue(ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X)),
+ ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y)));
+ aLine.setValue(aPoint[0], aPoint[1]);
+ lineSerde.serialize(aLine, out);
+ } catch (IOException e1) {
+ throw new AlgebricksException(e1);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateMBRDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateMBRDescriptor.java
new file mode 100644
index 0000000..74e8cb1
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateMBRDescriptor.java
@@ -0,0 +1,26 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.CreateMBREvalFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+
+public class CreateMBRDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "create-mbr", 3,
+ true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new CreateMBREvalFactory(args[0], args[1], args[2]);
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreatePointDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreatePointDescriptor.java
new file mode 100644
index 0000000..d75606a
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreatePointDescriptor.java
@@ -0,0 +1,74 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutablePoint;
+import edu.uci.ics.asterix.om.base.APoint;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class CreatePointDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "create-point",
+ 2, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private IEvaluator eval0 = args[0].createEvaluator(outInput0);
+ private IEvaluator eval1 = args[1].createEvaluator(outInput1);
+ private AMutablePoint aPoint = new AMutablePoint(0, 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<APoint> pointSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.APOINT);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+
+ try {
+ aPoint.setValue(ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(), 1),
+ ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(), 1));
+ pointSerde.serialize(aPoint, out);
+
+ } catch (IOException e1) {
+ throw new AlgebricksException(e1);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreatePolygonDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreatePolygonDescriptor.java
new file mode 100644
index 0000000..6cfbe5b
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreatePolygonDescriptor.java
@@ -0,0 +1,74 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class CreatePolygonDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "create-polygon",
+ FunctionIdentifier.VARARGS, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ private DataOutput out;
+ private ArrayBackedValueStorage outInput;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ final IEvaluator[] argEvals = new IEvaluator[args.length];
+ out = output.getDataOutput();
+
+ outInput = new ArrayBackedValueStorage();
+
+ for (int i = 0; i < args.length; i++) {
+ argEvals[i] = args[i].createEvaluator(outInput);
+ }
+
+ return new IEvaluator() {
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ out.writeByte(ATypeTag.POLYGON.serialize());
+ out.writeShort(args.length);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+
+ for (int i = 0; i < argEvals.length; i++) {
+ outInput.reset();
+ argEvals[i].evaluate(tuple);
+ try {
+ out.write(outInput.getBytes(), outInput.getStartIndex() + 1, outInput.getLength() - 1);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateRectangleDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateRectangleDescriptor.java
new file mode 100644
index 0000000..504e666
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CreateRectangleDescriptor.java
@@ -0,0 +1,87 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.Coordinate;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutablePoint;
+import edu.uci.ics.asterix.om.base.AMutableRectangle;
+import edu.uci.ics.asterix.om.base.ARectangle;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class CreateRectangleDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "create-rectangle", 2, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private IEvaluator eval0 = args[0].createEvaluator(outInput0);
+ private IEvaluator eval1 = args[1].createEvaluator(outInput1);
+ private AMutableRectangle aRectangle = new AMutableRectangle(null, null);
+ private AMutablePoint[] aPoint = { new AMutablePoint(0, 0), new AMutablePoint(0, 0) };
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ARectangle> rectangle2DSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ARECTANGLE);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+
+ try {
+ aPoint[0].setValue(ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X)),
+ ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y)));
+ aPoint[1].setValue(ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X)),
+ ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y)));
+ if (aPoint[0].getX() > aPoint[1].getX() || aPoint[0].getY() > aPoint[1].getY()) {
+ throw new IllegalArgumentException(
+ "The low point in the rectangle cannot be larger than the high point");
+ }
+ aRectangle.setValue(aPoint[0], aPoint[1]);
+ rectangle2DSerde.serialize(aRectangle, out);
+ } catch (IOException e1) {
+ throw new AlgebricksException(e1);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EditDistanceCheckDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EditDistanceCheckDescriptor.java
new file mode 100644
index 0000000..23e5e1d
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EditDistanceCheckDescriptor.java
@@ -0,0 +1,116 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.IAOrderedListBuilder;
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.EditDistanceEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class EditDistanceCheckDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "edit-distance-check", 3, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ return new EditDistanceCheckEvaluator(args, output);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ private static class EditDistanceCheckEvaluator extends EditDistanceEvaluator {
+
+ private final IEvaluator edThreshEval;
+ private int edThresh = -1;
+ private IAOrderedListBuilder listBuilder;
+ private ArrayBackedValueStorage inputVal;
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+
+ public EditDistanceCheckEvaluator(IEvaluatorFactory[] args, IDataOutputProvider output)
+ throws AlgebricksException {
+ super(args, output);
+ edThreshEval = args[2].createEvaluator(argOut);
+ listBuilder = new OrderedListBuilder();
+ inputVal = new ArrayBackedValueStorage();
+ }
+
+ @Override
+ protected void runArgEvals(IFrameTupleReference tuple) throws AlgebricksException {
+ super.runArgEvals(tuple);
+ int edThreshStart = argOut.getLength();
+ edThreshEval.evaluate(tuple);
+ edThresh = IntegerSerializerDeserializer.getInt(argOut.getBytes(), edThreshStart + typeIndicatorSize);
+ }
+
+ @Override
+ protected int computeResult(byte[] bytes, int firstStart, int secondStart, ATypeTag argType)
+ throws AlgebricksException {
+ switch (argType) {
+
+ case STRING: {
+ return ed.UTF8StringEditDistance(bytes, firstStart + typeIndicatorSize, secondStart
+ + typeIndicatorSize, edThresh);
+ }
+
+ case ORDEREDLIST: {
+ firstOrdListIter.reset(bytes, firstStart);
+ secondOrdListIter.reset(bytes, secondStart);
+ return (int) ed.getSimilarity(firstOrdListIter, secondOrdListIter, edThresh);
+ }
+
+ default: {
+ throw new AlgebricksException("Invalid type " + argType
+ + " passed as argument to edit distance function.");
+ }
+
+ }
+ }
+
+ @Override
+ protected void writeResult(int ed) throws IOException {
+
+ listBuilder.reset(new AOrderedListType(BuiltinType.ANY, "list"));
+ boolean matches = (ed < 0) ? false : true;
+ inputVal.reset();
+ booleanSerde.serialize(matches ? ABoolean.TRUE : ABoolean.FALSE, inputVal.getDataOutput());
+ listBuilder.addItem(inputVal);
+
+ inputVal.reset();
+ aInt32.setValue((matches) ? ed : Integer.MAX_VALUE);
+ int32Serde.serialize(aInt32, inputVal.getDataOutput());
+ listBuilder.addItem(inputVal);
+
+ listBuilder.write(out, true);
+ }
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EditDistanceDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EditDistanceDescriptor.java
new file mode 100644
index 0000000..740952e
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EditDistanceDescriptor.java
@@ -0,0 +1,36 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.EditDistanceEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+public class EditDistanceDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "edit-distance",
+ 2, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ return new EditDistanceEvaluator(args, output);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EmbedTypeDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EmbedTypeDescriptor.java
new file mode 100644
index 0000000..6f86da8
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EmbedTypeDescriptor.java
@@ -0,0 +1,51 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class EmbedTypeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "embed-type", 1,
+ true);
+ @SuppressWarnings("unused")
+ private IAType fieldType;
+
+ public void reset(IAType fieldType) {
+ this.fieldType = fieldType;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ // TODO Auto-generated method stub
+ return new IEvaluator() {
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ // TODO Auto-generated method stub
+
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EndsWithDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EndsWithDescriptor.java
new file mode 100644
index 0000000..a868a1a
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/EndsWithDescriptor.java
@@ -0,0 +1,73 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.util.StringUtils;
+
+public class EndsWithDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "ends-with", 2,
+ true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+ DataOutput dout = output.getDataOutput();
+
+ return new AbstractStringContainsEval(dout, args[0], args[1]) {
+
+ @Override
+ protected boolean findMatch(byte[] strBytes, byte[] patternBytes) {
+ int utflen1 = UTF8StringPointable.getUTFLen(strBytes, 1);
+ int utflen2 = UTF8StringPointable.getUTFLen(patternBytes, 1);
+
+ int s1Start = 3;
+ int s2Start = 3;
+
+ int startMatch = utflen1 - utflen2;
+ if (startMatch < 0) {
+ return false;
+ }
+ int c1 = 0;
+ while (c1 < startMatch) {
+ c1 += UTF8StringPointable.charSize(strBytes, s1Start + c1);
+ }
+ int c2 = 0;
+ while (c1 < utflen1 && c2 < utflen2) {
+ char ch1 = UTF8StringPointable.charAt(strBytes, s1Start + c1);
+ char ch2 = UTF8StringPointable.charAt(patternBytes, s2Start + c2);
+ if (ch1 != ch2) {
+ break;
+ }
+ c1 += UTF8StringPointable.charSize(strBytes, s1Start + c1);
+ c2 += UTF8StringPointable.charSize(patternBytes, s2Start + c2);
+ }
+ return (c2 == utflen2);
+ }
+
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/FieldAccessByIndexDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/FieldAccessByIndexDescriptor.java
new file mode 100644
index 0000000..7bb7dc3
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/FieldAccessByIndexDescriptor.java
@@ -0,0 +1,31 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.FieldAccessByIndexEvalFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+
+public class FieldAccessByIndexDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private static final FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "field-access-by-index", 2, true);
+ private ARecordType recType;
+
+ public void reset(ARecordType recType) {
+ this.recType = recType;
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(IEvaluatorFactory[] args) {
+ return new FieldAccessByIndexEvalFactory(args[0], args[1], recType);
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/FieldAccessByNameDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/FieldAccessByNameDescriptor.java
new file mode 100644
index 0000000..7eb8fae
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/FieldAccessByNameDescriptor.java
@@ -0,0 +1,116 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARecordSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class FieldAccessByNameDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private static final FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "field-access-by-name", 2, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(IEvaluatorFactory[] args) {
+ return new FieldAccessByNameEvalFactory(args[0], args[1]);
+ }
+
+ private static class FieldAccessByNameEvalFactory implements IEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ private IEvaluatorFactory recordEvalFactory;
+ private IEvaluatorFactory fldNameEvalFactory;
+
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static byte SER_RECORD_TYPE_TAG = ATypeTag.RECORD.serialize();
+
+ public FieldAccessByNameEvalFactory(IEvaluatorFactory recordEvalFactory, IEvaluatorFactory fldNameEvalFactory) {
+ this.recordEvalFactory = recordEvalFactory;
+ this.fldNameEvalFactory = fldNameEvalFactory;
+ }
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private IEvaluator eval0 = recordEvalFactory.createEvaluator(outInput0);
+ private IEvaluator eval1 = fldNameEvalFactory.createEvaluator(outInput1);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private int fieldValueOffset;
+ private int fieldValueLength;
+ private ATypeTag fieldValueTypeTag = ATypeTag.NULL;
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+ byte[] serRecord = outInput0.getBytes();
+
+ if (serRecord[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (serRecord[0] != SER_RECORD_TYPE_TAG) {
+ throw new AlgebricksException("Field accessor is not defined for values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serRecord[0]));
+ }
+
+ byte[] serFldName = outInput1.getBytes();
+ fieldValueOffset = ARecordSerializerDeserializer.getFieldOffsetByName(serRecord, serFldName);
+ if (fieldValueOffset < 0) {
+ out.writeByte(ATypeTag.NULL.serialize());
+ return;
+ }
+
+ fieldValueTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(serRecord[fieldValueOffset]);
+ fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(serRecord, fieldValueOffset,
+ fieldValueTypeTag, true) + 1;
+ out.write(serRecord, fieldValueOffset, fieldValueLength);
+
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/FuzzyEqDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/FuzzyEqDescriptor.java
new file mode 100644
index 0000000..056bb61
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/FuzzyEqDescriptor.java
@@ -0,0 +1,26 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+
+public class FuzzyEqDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "fuzzy-eq", 2,
+ true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(IEvaluatorFactory[] args) throws AlgebricksException {
+ throw new NotImplementedException();
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/GetItemDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/GetItemDescriptor.java
new file mode 100644
index 0000000..828ca2f
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/GetItemDescriptor.java
@@ -0,0 +1,133 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class GetItemDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "get-item", 2,
+ true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new GetItemEvalFactory(args);
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ private static class GetItemEvalFactory implements IEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ private IEvaluatorFactory listEvalFactory;
+ private IEvaluatorFactory indexEvalFactory;
+ private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private byte serItemTypeTag;
+ private ATypeTag itemTag;
+ private boolean selfDescList = false;
+
+ public GetItemEvalFactory(IEvaluatorFactory[] args) {
+ this.listEvalFactory = args[0];
+ this.indexEvalFactory = args[1];
+ }
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage outInputList = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInputIdx = new ArrayBackedValueStorage();
+ private IEvaluator evalList = listEvalFactory.createEvaluator(outInputList);
+ private IEvaluator evalIdx = indexEvalFactory.createEvaluator(outInputIdx);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private int itemIndex;
+ private int itemOffset;
+ private int itemLength;
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ outInputList.reset();
+ evalList.evaluate(tuple);
+ outInputIdx.reset();
+ evalIdx.evaluate(tuple);
+ byte[] serOrderedList = outInputList.getBytes();
+
+ if (serOrderedList[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (serOrderedList[0] != SER_ORDEREDLIST_TYPE_TAG) {
+ throw new AlgebricksException("List's get-item can not be called on values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serOrderedList[0]));
+ }
+
+ itemIndex = IntegerSerializerDeserializer.getInt(outInputIdx.getBytes(), 1);
+ if (itemIndex >= AOrderedListSerializerDeserializer.getNumberOfItems(serOrderedList)) {
+ out.writeByte(SER_NULL_TYPE_TAG);
+ return;
+ }
+ if (itemIndex < 0)
+ throw new AlgebricksException("Item index can be negative !!");
+
+ itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serOrderedList[1]);
+ if (itemTag == ATypeTag.ANY)
+ selfDescList = true;
+ else
+ serItemTypeTag = serOrderedList[1];
+
+ itemOffset = AOrderedListSerializerDeserializer.getItemOffset(serOrderedList, itemIndex);
+
+ if (selfDescList) {
+ itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serOrderedList[itemOffset]);
+ itemLength = NonTaggedFormatUtil.getFieldValueLength(serOrderedList, itemOffset, itemTag,
+ true) + 1;
+ out.write(serOrderedList, itemOffset, itemLength);
+ } else {
+ itemLength = NonTaggedFormatUtil.getFieldValueLength(serOrderedList, itemOffset, itemTag,
+ false);
+ out.writeByte(serItemTypeTag);
+ out.write(serOrderedList, itemOffset, itemLength);
+ }
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/GramTokensDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/GramTokensDescriptor.java
new file mode 100644
index 0000000..7321766
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/GramTokensDescriptor.java
@@ -0,0 +1,44 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.GramTokensEvaluator;
+import edu.uci.ics.fuzzyjoin.tokenizer.ITokenFactory;
+import edu.uci.ics.fuzzyjoin.tokenizer.NGramUTF8StringBinaryTokenizer;
+import edu.uci.ics.fuzzyjoin.tokenizer.UTF8NGramTokenFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+public class GramTokensDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "gram-tokens",
+ 3, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ ITokenFactory tokenFactory = new UTF8NGramTokenFactory(ATypeTag.STRING.serialize(),
+ ATypeTag.INT32.serialize());
+ NGramUTF8StringBinaryTokenizer tokenizer = new NGramUTF8StringBinaryTokenizer(3, true, true, true,
+ tokenFactory);
+ return new GramTokensEvaluator(args, output, tokenizer, BuiltinType.ASTRING);
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/HashedGramTokensDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/HashedGramTokensDescriptor.java
new file mode 100644
index 0000000..e2193f5
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/HashedGramTokensDescriptor.java
@@ -0,0 +1,44 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.GramTokensEvaluator;
+import edu.uci.ics.fuzzyjoin.tokenizer.HashedUTF8NGramTokenFactory;
+import edu.uci.ics.fuzzyjoin.tokenizer.ITokenFactory;
+import edu.uci.ics.fuzzyjoin.tokenizer.NGramUTF8StringBinaryTokenizer;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+public class HashedGramTokensDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "hashed-gram-tokens", 3, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ ITokenFactory tokenFactory = new HashedUTF8NGramTokenFactory(ATypeTag.INT32.serialize(),
+ ATypeTag.INT32.serialize());
+ NGramUTF8StringBinaryTokenizer tokenizer = new NGramUTF8StringBinaryTokenizer(3, true, true, true,
+ tokenFactory);
+ return new GramTokensEvaluator(args, output, tokenizer, BuiltinType.AINT32);
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/HashedWordTokensDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/HashedWordTokensDescriptor.java
new file mode 100644
index 0000000..e223b2a
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/HashedWordTokensDescriptor.java
@@ -0,0 +1,45 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.WordTokensEvaluator;
+import edu.uci.ics.fuzzyjoin.tokenizer.DelimitedUTF8StringBinaryTokenizer;
+import edu.uci.ics.fuzzyjoin.tokenizer.HashedUTF8WordTokenFactory;
+import edu.uci.ics.fuzzyjoin.tokenizer.IBinaryTokenizer;
+import edu.uci.ics.fuzzyjoin.tokenizer.ITokenFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+public class HashedWordTokensDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "hashed-word-tokens", 1, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ ITokenFactory tokenFactory = new HashedUTF8WordTokenFactory(ATypeTag.INT32.serialize(),
+ ATypeTag.INT32.serialize());
+ IBinaryTokenizer tokenizer = new DelimitedUTF8StringBinaryTokenizer(true, true, tokenFactory);
+ return new WordTokensEvaluator(args, output, tokenizer, BuiltinType.AINT32);
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/InjectFailureDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/InjectFailureDescriptor.java
new file mode 100644
index 0000000..863c213
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/InjectFailureDescriptor.java
@@ -0,0 +1,71 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class InjectFailureDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "inject-failure", 2, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ final IEvaluator[] evals = new IEvaluator[args.length];
+ evals[0] = args[0].createEvaluator(argOut);
+ evals[1] = args[1].createEvaluator(argOut);
+
+ return new IEvaluator() {
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ // evaluator the failure condition
+ argOut.reset();
+ evals[1].evaluate(tuple);
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[0]);
+ if (typeTag == ATypeTag.BOOLEAN) {
+ boolean argResult = ABooleanSerializerDeserializer.getBoolean(argOut.getBytes(), 1);
+ if (argResult)
+ throw new AlgebricksException("Injecting a intended failure");
+ }
+
+ // evaluate the real evaluator
+ argOut.reset();
+ evals[0].evaluate(tuple);
+ output.getDataOutput().write(argOut.getBytes(), argOut.getStartIndex(), argOut.getLength());
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ };
+ }
+ };
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/IsNullDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/IsNullDescriptor.java
new file mode 100644
index 0000000..d6fe887
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/IsNullDescriptor.java
@@ -0,0 +1,63 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AObjectSerializerDeserializer;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class IsNullDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+
+ public final static FunctionIdentifier FID = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS,
+ "is-null", 1, true);
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(argOut);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+ eval.evaluate(tuple);
+ boolean isNull = argOut.getBytes()[argOut.getStartIndex()] == SER_NULL_TYPE_TAG;
+ ABoolean res = isNull ? ABoolean.TRUE : ABoolean.FALSE;
+ try {
+ AObjectSerializerDeserializer.INSTANCE.serialize(res, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/LenDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/LenDescriptor.java
new file mode 100644
index 0000000..077b704
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/LenDescriptor.java
@@ -0,0 +1,101 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AUnorderedListSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class LenDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "len", 1, true);
+ private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+ private final static byte SER_UNORDEREDLIST_TYPE_TAG = ATypeTag.UNORDEREDLIST.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ return new IEvaluator() {
+
+ private final DataOutput out = output.getDataOutput();
+ private final ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private final IEvaluator evalList = args[0].createEvaluator(inputVal);
+
+ // result
+ private final AMutableInt32 res = new AMutableInt32(0);
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ inputVal.reset();
+ evalList.evaluate(tuple);
+
+ byte[] serList = inputVal.getBytes();
+
+ if (serList[0] == SER_NULL_TYPE_TAG) {
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ return;
+ }
+
+ if (serList[0] != SER_ORDEREDLIST_TYPE_TAG && serList[0] != SER_UNORDEREDLIST_TYPE_TAG) {
+ throw new AlgebricksException("len() can only be called on ordered or unordered lists.");
+ }
+
+ int numberOfitems = 0;
+ if (serList[0] == SER_ORDEREDLIST_TYPE_TAG)
+ numberOfitems = AOrderedListSerializerDeserializer.getNumberOfItems(serList);
+ else
+ numberOfitems = AUnorderedListSerializerDeserializer.getNumberOfItems(serList);
+
+ res.setValue(numberOfitems);
+ try {
+ int32Serde.serialize(res, out);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/LikeDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/LikeDescriptor.java
new file mode 100644
index 0000000..5f59851
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/LikeDescriptor.java
@@ -0,0 +1,164 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.common.utils.UTF8CharSequence;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.AString;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+/**
+ * Creates new Matcher and Pattern objects each time the value of the pattern
+ * argument (the second argument) changes.
+ */
+
+public class LikeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "like", 2, true);
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+ final DataOutput dout = output.getDataOutput();
+
+ return new IEvaluator() {
+
+ private boolean first = true;
+ private ArrayBackedValueStorage array0 = new ArrayBackedValueStorage();
+ private IEvaluator evalString = args[0].createEvaluator(array0);
+ private IEvaluator evalPattern = args[1].createEvaluator(array0);
+ private ByteArrayAccessibleOutputStream lastPattern = new ByteArrayAccessibleOutputStream();
+ private UTF8CharSequence carSeq = new UTF8CharSequence();
+ private IBinaryComparator strComp = AqlBinaryComparatorFactoryProvider.INSTANCE
+ .getBinaryComparatorFactory(BuiltinType.ASTRING, OrderKind.ASC).createBinaryComparator();
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ASTRING);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private Matcher matcher;
+ private Pattern pattern;
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ // evaluate the pattern first
+ try {
+ array0.reset();
+ evalPattern.evaluate(tuple);
+ if (array0.getBytes()[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, dout);
+ return;
+ }
+ boolean newPattern = false;
+ if (first) {
+ first = false;
+ newPattern = true;
+ } else {
+ int c = strComp.compare(array0.getBytes(), array0.getStartIndex(), array0.getLength(),
+ lastPattern.getByteArray(), 0, lastPattern.size());
+ if (c != 0) {
+ newPattern = true;
+ }
+ }
+ if (newPattern) {
+ lastPattern.reset();
+ lastPattern.write(array0.getBytes(), array0.getStartIndex(), array0.getLength());
+ // ! object creation !
+ DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+ lastPattern.getByteArray()));
+ AString strPattern = (AString) stringSerde.deserialize(di);
+ pattern = Pattern.compile(toRegex(strPattern));
+
+ }
+ array0.reset();
+ evalString.evaluate(tuple);
+ if (array0.getBytes()[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, dout);
+ return;
+ }
+ carSeq.reset(array0, 1);
+ if (newPattern) {
+ matcher = pattern.matcher(carSeq);
+ } else {
+ matcher.reset(carSeq);
+ }
+ ABoolean res = (matcher.matches()) ? ABoolean.TRUE : ABoolean.FALSE;
+
+ booleanSerde.serialize(res, dout);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ private String toRegex(AString pattern) {
+ StringBuilder sb = new StringBuilder();
+ String str = pattern.getStringValue();
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c == '\\' && (i < str.length() - 1)
+ && (str.charAt(i + 1) == '_' || str.charAt(i + 1) == '%')) {
+ sb.append(str.charAt(i + 1));
+ ++i;
+ } else if (c == '%') {
+ sb.append(".*");
+ } else if (c == '_') {
+ sb.append(".");
+ } else {
+ if (Arrays.binarySearch(reservedRegexChars, c) >= 0) {
+ sb.append('\\');
+ }
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+ };
+ }
+ };
+ }
+
+ private static char[] reservedRegexChars = new char[] { '\\', '(', ')', '[', ']', '{', '}', '.', '^', '$', '*', '|' };
+ static {
+ Arrays.sort(reservedRegexChars);
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NotDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NotDescriptor.java
new file mode 100644
index 0000000..0f4b0a0
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NotDescriptor.java
@@ -0,0 +1,81 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class NotDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS,
+ "not", 1, true);
+
+ private final static byte SER_BOOLEAN_TYPE_TAG = ATypeTag.BOOLEAN.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ final DataOutput out = output.getDataOutput();
+
+ return new IEvaluator() {
+
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(argOut);
+
+ private String errorMessage = "Not() can only be applied on boolean";
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+ eval.evaluate(tuple);
+ try {
+ if (argOut.getBytes()[0] == SER_BOOLEAN_TYPE_TAG) {
+ boolean argRes = ABooleanSerializerDeserializer.getBoolean(argOut.getBytes(), 1);
+ ABoolean aResult = argRes ? (ABoolean.FALSE) : (ABoolean.TRUE);
+ booleanSerde.serialize(aResult, out);
+ } else if (argOut.getBytes()[0] == SER_NULL_TYPE_TAG)
+ nullSerde.serialize(ANull.NULL, out);
+ else
+ throw new AlgebricksException(errorMessage);
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAddDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAddDescriptor.java
new file mode 100644
index 0000000..8e4c319
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAddDescriptor.java
@@ -0,0 +1,173 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class NumericAddDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS,
+ "numeric-add", 2, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ return new IEvaluator() {
+ private DataOutput out = output.getDataOutput();
+ // one temp. buffer re-used by both children
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private IEvaluator evalLeft = args[0].createEvaluator(argOut);
+ private IEvaluator evalRight = args[1].createEvaluator(argOut);
+ private double[] operands = new double[args.length];
+ private boolean metInt8 = false, metInt16 = false, metInt32 = false, metInt64 = false,
+ metFloat = false, metDouble = false;
+ private ATypeTag typeTag;
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer serde;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ for (int i = 0; i < args.length; i++) {
+ argOut.reset();
+ if (i == 0)
+ evalLeft.evaluate(tuple);
+ else
+ evalRight.evaluate(tuple);
+ typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ metInt8 = true;
+ operands[i] = AInt8SerializerDeserializer.getByte(argOut.getBytes(), 1);
+ break;
+ }
+ case INT16: {
+ metInt16 = true;
+ operands[i] = AInt16SerializerDeserializer.getShort(argOut.getBytes(), 1);
+ break;
+ }
+ case INT32: {
+ metInt32 = true;
+ operands[i] = AInt32SerializerDeserializer.getInt(argOut.getBytes(), 1);
+ break;
+ }
+ case INT64: {
+ metInt64 = true;
+ operands[i] = AInt64SerializerDeserializer.getLong(argOut.getBytes(), 1);
+ break;
+ }
+ case FLOAT: {
+ metFloat = true;
+ operands[i] = AFloatSerializerDeserializer.getFloat(argOut.getBytes(), 1);
+ break;
+ }
+ case DOUBLE: {
+ metDouble = true;
+ operands[i] = ADoubleSerializerDeserializer.getDouble(argOut.getBytes(), 1);
+ break;
+ }
+ case NULL: {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ return;
+ }
+ default: {
+ throw new NotImplementedException(i == 0 ? "Left"
+ : "Right"
+ + " Operand of Addition can not be "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut
+ .getBytes()[0]));
+ }
+ }
+ }
+
+ if (metDouble) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ aDouble.setValue(operands[0] + operands[1]);
+ serde.serialize(aDouble, out);
+ } else if (metFloat) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ aFloat.setValue((float) (operands[0] + operands[1]));
+ serde.serialize(aFloat, out);
+ } else if (metInt64) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ aInt64.setValue((long) (operands[0] + operands[1]));
+ serde.serialize(aInt64, out);
+ } else if (metInt32) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ aInt32.setValue((int) (operands[0] + operands[1]));
+ serde.serialize(aInt32, out);
+ } else if (metInt16) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ aInt16.setValue((short) (operands[0] + operands[1]));
+ serde.serialize(aInt16, out);
+ } else if (metInt8) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ aInt8.setValue((byte) (operands[0] + operands[1]));
+ serde.serialize(aInt8, out);
+ }
+
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
new file mode 100644
index 0000000..c7274f8
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
@@ -0,0 +1,173 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class NumericDivideDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "numeric-divide",
+ 2, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ return new IEvaluator() {
+ private DataOutput out = output.getDataOutput();
+ // one temp. buffer re-used by both children
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private IEvaluator evalLeft = args[0].createEvaluator(argOut);
+ private IEvaluator evalRight = args[1].createEvaluator(argOut);
+ private double[] operands = new double[args.length];
+ private boolean metInt8 = false, metInt16 = false, metInt32 = false, metInt64 = false,
+ metFloat = false, metDouble = false;
+ private ATypeTag typeTag;
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer serde;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ for (int i = 0; i < args.length; i++) {
+ argOut.reset();
+ if (i == 0)
+ evalLeft.evaluate(tuple);
+ else
+ evalRight.evaluate(tuple);
+ typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ metInt8 = true;
+ operands[i] = AInt8SerializerDeserializer.getByte(argOut.getBytes(), 1);
+ break;
+ }
+ case INT16: {
+ metInt16 = true;
+ operands[i] = AInt16SerializerDeserializer.getShort(argOut.getBytes(), 1);
+ break;
+ }
+ case INT32: {
+ metInt32 = true;
+ operands[i] = AInt32SerializerDeserializer.getInt(argOut.getBytes(), 1);
+ break;
+ }
+ case INT64: {
+ metInt64 = true;
+ operands[i] = AInt64SerializerDeserializer.getLong(argOut.getBytes(), 1);
+ break;
+ }
+ case FLOAT: {
+ metFloat = true;
+ operands[i] = AFloatSerializerDeserializer.getFloat(argOut.getBytes(), 1);
+ break;
+ }
+ case DOUBLE: {
+ metDouble = true;
+ operands[i] = ADoubleSerializerDeserializer.getDouble(argOut.getBytes(), 1);
+ break;
+ }
+ case NULL: {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ return;
+ }
+ default: {
+ throw new NotImplementedException(i == 0 ? "Left"
+ : "Right"
+ + " Operand of Division can not be "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut
+ .getBytes()[0]));
+ }
+ }
+ }
+
+ if (metDouble) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ aDouble.setValue(operands[0] / operands[1]);
+ serde.serialize(aDouble, out);
+ } else if (metFloat) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ aFloat.setValue((float) (operands[0] / operands[1]));
+ serde.serialize(aFloat, out);
+ } else if (metInt64) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ aInt64.setValue((long) (operands[0] / operands[1]));
+ serde.serialize(aInt64, out);
+ } else if (metInt32) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ aInt32.setValue((int) (operands[0] / operands[1]));
+ serde.serialize(aInt32, out);
+ } else if (metInt16) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ aInt16.setValue((short) (operands[0] / operands[1]));
+ serde.serialize(aInt16, out);
+ } else if (metInt8) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ aInt8.setValue((byte) (operands[0] / operands[1]));
+ serde.serialize(aInt8, out);
+ }
+
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java
new file mode 100644
index 0000000..1970210
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java
@@ -0,0 +1,172 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class NumericMultiplyDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "numeric-multiply", 2, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ return new IEvaluator() {
+ private DataOutput out = output.getDataOutput();
+ // one temp. buffer re-used by both children
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private IEvaluator evalLeft = args[0].createEvaluator(argOut);
+ private IEvaluator evalRight = args[1].createEvaluator(argOut);
+ private double[] operands = new double[args.length];
+ private boolean metInt8 = false, metInt16 = false, metInt32 = false, metInt64 = false,
+ metFloat = false, metDouble = false;
+ private ATypeTag typeTag;
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer serde;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ for (int i = 0; i < args.length; i++) {
+ argOut.reset();
+ if (i == 0)
+ evalLeft.evaluate(tuple);
+ else
+ evalRight.evaluate(tuple);
+ typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ metInt8 = true;
+ operands[i] = AInt8SerializerDeserializer.getByte(argOut.getBytes(), 1);
+ break;
+ }
+ case INT16: {
+ metInt16 = true;
+ operands[i] = AInt16SerializerDeserializer.getShort(argOut.getBytes(), 1);
+ break;
+ }
+ case INT32: {
+ metInt32 = true;
+ operands[i] = AInt32SerializerDeserializer.getInt(argOut.getBytes(), 1);
+ break;
+ }
+ case INT64: {
+ metInt64 = true;
+ operands[i] = AInt64SerializerDeserializer.getLong(argOut.getBytes(), 1);
+ break;
+ }
+ case FLOAT: {
+ metFloat = true;
+ operands[i] = AFloatSerializerDeserializer.getFloat(argOut.getBytes(), 1);
+ break;
+ }
+ case DOUBLE: {
+ metDouble = true;
+ operands[i] = ADoubleSerializerDeserializer.getDouble(argOut.getBytes(), 1);
+ break;
+ }
+ case NULL: {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ return;
+ }
+ default: {
+ throw new NotImplementedException(i == 0 ? "Left"
+ : "Right"
+ + " Operand of Multiplication can not be "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut
+ .getBytes()[0]));
+ }
+ }
+ }
+ if (metDouble) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ aDouble.setValue(operands[0] * operands[1]);
+ serde.serialize(aDouble, out);
+ } else if (metFloat) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ aFloat.setValue((float) (operands[0] * operands[1]));
+ serde.serialize(aFloat, out);
+ } else if (metInt64) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ aInt64.setValue((long) (operands[0] * operands[1]));
+ serde.serialize(aInt64, out);
+ } else if (metInt32) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ aInt32.setValue((int) (operands[0] * operands[1]));
+ serde.serialize(aInt32, out);
+ } else if (metInt16) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ aInt16.setValue((short) (operands[0] * operands[1]));
+ serde.serialize(aInt16, out);
+ } else if (metInt8) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ aInt8.setValue((byte) (operands[0] * operands[1]));
+ serde.serialize(aInt8, out);
+ }
+
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericSubtractDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericSubtractDescriptor.java
new file mode 100644
index 0000000..51dab06
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericSubtractDescriptor.java
@@ -0,0 +1,173 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class NumericSubtractDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "numeric-subtract", 2, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ return new IEvaluator() {
+ private DataOutput out = output.getDataOutput();
+ // one temp. buffer re-used by both children
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private IEvaluator evalLeft = args[0].createEvaluator(argOut);
+ private IEvaluator evalRight = args[1].createEvaluator(argOut);
+ private double[] operands = new double[args.length];
+ private boolean metInt8 = false, metInt16 = false, metInt32 = false, metInt64 = false,
+ metFloat = false, metDouble = false;
+ private ATypeTag typeTag;
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer serde;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ for (int i = 0; i < args.length; i++) {
+ argOut.reset();
+ if (i == 0)
+ evalLeft.evaluate(tuple);
+ else
+ evalRight.evaluate(tuple);
+ typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[0]);
+ switch (typeTag) {
+ case INT8: {
+ metInt8 = true;
+ operands[i] = AInt8SerializerDeserializer.getByte(argOut.getBytes(), 1);
+ break;
+ }
+ case INT16: {
+ metInt16 = true;
+ operands[i] = AInt16SerializerDeserializer.getShort(argOut.getBytes(), 1);
+ break;
+ }
+ case INT32: {
+ metInt32 = true;
+ operands[i] = AInt32SerializerDeserializer.getInt(argOut.getBytes(), 1);
+ break;
+ }
+ case INT64: {
+ metInt64 = true;
+ operands[i] = AInt64SerializerDeserializer.getLong(argOut.getBytes(), 1);
+ break;
+ }
+ case FLOAT: {
+ metFloat = true;
+ operands[i] = AFloatSerializerDeserializer.getFloat(argOut.getBytes(), 1);
+ break;
+ }
+ case DOUBLE: {
+ metDouble = true;
+ operands[i] = ADoubleSerializerDeserializer.getDouble(argOut.getBytes(), 1);
+ break;
+ }
+ case NULL: {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ return;
+ }
+ default: {
+ throw new NotImplementedException(i == 0 ? "Left"
+ : "Right"
+ + " Operand of Substraction can not be "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut
+ .getBytes()[0]));
+ }
+ }
+ }
+
+ if (metDouble) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ aDouble.setValue(operands[0] - operands[1]);
+ serde.serialize(aDouble, out);
+ } else if (metFloat) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ aFloat.setValue((float) (operands[0] - operands[1]));
+ serde.serialize(aFloat, out);
+ } else if (metInt64) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ aInt64.setValue((long) (operands[0] - operands[1]));
+ serde.serialize(aInt64, out);
+ } else if (metInt32) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ aInt32.setValue((int) (operands[0] - operands[1]));
+ serde.serialize(aInt32, out);
+ } else if (metInt16) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ aInt16.setValue((short) (operands[0] - operands[1]));
+ serde.serialize(aInt16, out);
+ } else if (metInt8) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ aInt8.setValue((byte) (operands[0] - operands[1]));
+ serde.serialize(aInt8, out);
+ }
+
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericUnaryMinusDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericUnaryMinusDescriptor.java
new file mode 100644
index 0000000..38808bb
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericUnaryMinusDescriptor.java
@@ -0,0 +1,129 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class NumericUnaryMinusDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "numeric-unary-minus", 1, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(argOut);
+ private byte serNullTypeTag = ATypeTag.NULL.serialize();
+ private byte serInt8TypeTag = ATypeTag.INT8.serialize();
+ private byte serInt16TypeTag = ATypeTag.INT16.serialize();
+ private byte serInt32TypeTag = ATypeTag.INT32.serialize();
+ private byte serInt64TypeTag = ATypeTag.INT64.serialize();
+ private byte serFloatTypeTag = ATypeTag.FLOAT.serialize();
+ private byte serDoubleTypeTag = ATypeTag.DOUBLE.serialize();
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer serde;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+ eval.evaluate(tuple);
+ try {
+ if (argOut.getBytes()[0] == serNullTypeTag) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ return;
+ } else if (argOut.getBytes()[0] == serInt8TypeTag) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ aInt8.setValue((byte) -AInt8SerializerDeserializer.getByte(argOut.getBytes(), 1));
+ serde.serialize(aInt8, out);
+ } else if (argOut.getBytes()[0] == serInt16TypeTag) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ aInt16.setValue((short) -AInt16SerializerDeserializer.getShort(argOut.getBytes(), 1));
+ serde.serialize(aInt16, out);
+ } else if (argOut.getBytes()[0] == serInt32TypeTag) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ aInt32.setValue(-AInt32SerializerDeserializer.getInt(argOut.getBytes(), 1));
+ serde.serialize(aInt32, out);
+ } else if (argOut.getBytes()[0] == serInt64TypeTag) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ aInt64.setValue(-AInt64SerializerDeserializer.getLong(argOut.getBytes(), 1));
+ serde.serialize(aInt64, out);
+ } else if (argOut.getBytes()[0] == serFloatTypeTag) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ aFloat.setValue(-AFloatSerializerDeserializer.getFloat(argOut.getBytes(), 1));
+ serde.serialize(aFloat, out);
+ } else if (argOut.getBytes()[0] == serDoubleTypeTag) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ aDouble.setValue(-ADoubleSerializerDeserializer.getDouble(argOut.getBytes(), 1));
+ serde.serialize(aDouble, out);
+ } else {
+ throw new NotImplementedException("Unary minus is not implemented for "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getBytes()[0]));
+ }
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OpenRecordConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OpenRecordConstructorDescriptor.java
new file mode 100644
index 0000000..f1cbdca
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OpenRecordConstructorDescriptor.java
@@ -0,0 +1,92 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.RecordBuilder;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class OpenRecordConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ protected static final FunctionIdentifier FID_OPEN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "open-record-constructor", FunctionIdentifier.VARARGS, true);
+
+ private static final long serialVersionUID = 1L;
+ private ARecordType recType;
+ private boolean[] openFields;
+
+ public void reset(ARecordType recType, boolean[] openFields) {
+ this.recType = recType;
+ this.openFields = openFields;
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID_OPEN;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ int n = args.length / 2;
+ final IEvaluator[] evalNames = new IEvaluator[n];
+ final IEvaluator[] evalFields = new IEvaluator[n];
+ final ArrayBackedValueStorage fieldNameBuffer = new ArrayBackedValueStorage();
+ final ArrayBackedValueStorage fieldValueBuffer = new ArrayBackedValueStorage();
+ for (int i = 0; i < n; i++) {
+ evalNames[i] = args[2 * i].createEvaluator(fieldNameBuffer);
+ evalFields[i] = args[2 * i + 1].createEvaluator(fieldValueBuffer);
+ }
+ final DataOutput out = output.getDataOutput();
+ return new IEvaluator() {
+ private RecordBuilder recBuilder = new RecordBuilder();
+ private int closedFieldId;
+ private boolean first = true;
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ closedFieldId = 0;
+ if (first) {
+ first = false;
+ recBuilder.reset(recType);
+ }
+ recBuilder.init();
+ for (int i = 0; i < evalFields.length; i++) {
+ fieldValueBuffer.reset();
+ evalFields[i].evaluate(tuple);
+ if (openFields[i]) {
+ fieldNameBuffer.reset();
+ evalNames[i].evaluate(tuple);
+ recBuilder.addField(fieldNameBuffer, fieldValueBuffer);
+ } else {
+ if (fieldValueBuffer.getBytes()[0] != ATypeTag.NULL.serialize()) {
+ recBuilder.addField(closedFieldId, fieldValueBuffer);
+ }
+ closedFieldId++;
+ }
+ }
+ recBuilder.write(out, true);
+ } catch (IOException ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrDescriptor.java
new file mode 100644
index 0000000..9ed1cfd
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrDescriptor.java
@@ -0,0 +1,94 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class OrDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS, "or",
+ FunctionIdentifier.VARARGS, true);
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ // one temp. buffer re-used by all children
+ final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ final IEvaluator[] evals = new IEvaluator[args.length];
+ for (int i = 0; i < evals.length; i++) {
+ evals[i] = args[i].createEvaluator(argOut);
+ }
+
+ return new IEvaluator() {
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ int n = args.length;
+ boolean res = false;
+ boolean metNull = false;
+ for (int i = 0; i < n; i++) {
+ argOut.reset();
+ evals[i].evaluate(tuple);
+ if (argOut.getBytes()[0] == SER_NULL_TYPE_TAG) {
+ metNull = true;
+ continue;
+ }
+ boolean argResult = ABooleanSerializerDeserializer.getBoolean(argOut.getBytes(), 1);
+ if (argResult == true) {
+ res = true;
+ break;
+ }
+ }
+ if (metNull) {
+ if (!res) {
+ ABoolean aResult = ABoolean.FALSE;
+ booleanSerde.serialize(aResult, output.getDataOutput());
+ } else
+ nullSerde.serialize(ANull.NULL, output.getDataOutput());
+ } else {
+ ABoolean aResult = res ? (ABoolean.TRUE) : (ABoolean.FALSE);
+ booleanSerde.serialize(aResult, output.getDataOutput());
+ }
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrderedListConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrderedListConstructorDescriptor.java
new file mode 100644
index 0000000..61c1d8c
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/OrderedListConstructorDescriptor.java
@@ -0,0 +1,120 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class OrderedListConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "ordered-list-constructor", FunctionIdentifier.VARARGS, true);
+
+ private AOrderedListType oltype;
+
+ public void reset(AOrderedListType orderedListType) {
+ this.oltype = orderedListType;
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new OrderedListConstructorEvaluatorFactory(args, oltype);
+ }
+
+ private static class OrderedListConstructorEvaluatorFactory implements IEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+ private IEvaluatorFactory[] args;
+
+ private boolean selfDescList = false;
+
+ private AOrderedListType orderedlistType;
+
+ public OrderedListConstructorEvaluatorFactory(IEvaluatorFactory[] args, AOrderedListType type) {
+ this.args = args;
+
+ this.orderedlistType = type;
+ if (type == null || type.getItemType() == null || type.getItemType().getTypeTag() == ATypeTag.ANY) {
+ this.selfDescList = true;
+ }
+ }
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ final DataOutput out = output.getDataOutput();
+ final ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ final IEvaluator[] argEvals = new IEvaluator[args.length];
+ for (int i = 0; i < args.length; i++) {
+ argEvals[i] = args[i].createEvaluator(inputVal);
+ }
+
+ return new IEvaluator() {
+
+ private OrderedListBuilder builder = new OrderedListBuilder();
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ builder.reset(orderedlistType);
+ if (selfDescList) {
+ this.writeUntypedItems(tuple);
+ } else {
+ this.writeTypedItems(tuple);
+ }
+ builder.write(out, true);
+ } catch (IOException ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+
+ private void writeUntypedItems(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ for (int i = 0; i < argEvals.length; i++) {
+ inputVal.reset();
+ argEvals[i].evaluate(tuple);
+ builder.addItem(inputVal);
+ }
+
+ } catch (IOException ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+
+ private void writeTypedItems(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ for (int i = 0; i < argEvals.length; i++) {
+ inputVal.reset();
+ argEvals[i].evaluate(tuple);
+ builder.addItem(inputVal);
+ }
+
+ } catch (IOException ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+
+ };
+
+ }
+
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/PrefixLenDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/PrefixLenDescriptor.java
new file mode 100644
index 0000000..1c1d9b48
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/PrefixLenDescriptor.java
@@ -0,0 +1,94 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.SimilarityFiltersCache;
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityFilters;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class PrefixLenDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "prefix-len", 3,
+ true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ return new IEvaluator() {
+
+ private final DataOutput out = output.getDataOutput();
+ private final ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private final IEvaluator evalLen = args[0].createEvaluator(inputVal);
+ private final IEvaluator evalSimilarity = args[1].createEvaluator(inputVal);
+ private final IEvaluator evalThreshold = args[2].createEvaluator(inputVal);
+
+ private final SimilarityFiltersCache similarityFiltersCache = new SimilarityFiltersCache();
+
+ // result
+ private final AMutableInt32 res = new AMutableInt32(0);
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ // length
+ inputVal.reset();
+ evalLen.evaluate(tuple);
+ int length = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ // similarity threshold
+ inputVal.reset();
+ evalThreshold.evaluate(tuple);
+ float similarityThreshold = (float) ADoubleSerializerDeserializer.getDouble(
+ inputVal.getBytes(), 1);
+
+ // similarity name
+ inputVal.reset();
+ evalSimilarity.evaluate(tuple);
+ SimilarityFilters similarityFilters = similarityFiltersCache.get(similarityThreshold,
+ inputVal.getBytes());
+
+ int prefixLength = similarityFilters.getPrefixLength(length);
+ res.setValue(prefixLength);
+
+ try {
+ int32Serde.serialize(res, out);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/PrefixLenJaccardDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/PrefixLenJaccardDescriptor.java
new file mode 100644
index 0000000..fa6d47c
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/PrefixLenJaccardDescriptor.java
@@ -0,0 +1,91 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityFiltersJaccard;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class PrefixLenJaccardDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "prefix-len-jaccard", 2, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ return new IEvaluator() {
+
+ private final DataOutput out = output.getDataOutput();
+ private final ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private final IEvaluator evalLen = args[0].createEvaluator(inputVal);
+ private final IEvaluator evalThreshold = args[1].createEvaluator(inputVal);
+
+ private float similarityThresholdCache;
+ private SimilarityFiltersJaccard similarityFilters;
+
+ // result
+ private final AMutableInt32 res = new AMutableInt32(0);
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ // length
+ inputVal.reset();
+ evalLen.evaluate(tuple);
+ int length = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ // similarity threshold
+ inputVal.reset();
+ evalThreshold.evaluate(tuple);
+ float similarityThreshold = (float) AFloatSerializerDeserializer.getFloat(inputVal.getBytes(),
+ 1);
+
+ if (similarityThreshold != similarityThresholdCache || similarityFilters == null) {
+ similarityFilters = new SimilarityFiltersJaccard(similarityThreshold);
+ }
+
+ int prefixLength = similarityFilters.getPrefixLength(length);
+ res.setValue(prefixLength);
+
+ try {
+ int32Serde.serialize(res, out);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/RegExpDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/RegExpDescriptor.java
new file mode 100644
index 0000000..0da578f
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/RegExpDescriptor.java
@@ -0,0 +1,135 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.common.utils.UTF8CharSequence;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.AString;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+/**
+ * Creates new Matcher and Pattern objects each time the value of the pattern
+ * argument (the second argument) changes.
+ */
+
+public class RegExpDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "reg-exp", 2,
+ true);
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+ final DataOutput dout = output.getDataOutput();
+
+ return new IEvaluator() {
+
+ private boolean first = true;
+ private ArrayBackedValueStorage array0 = new ArrayBackedValueStorage();
+ private IEvaluator evalString = args[0].createEvaluator(array0);
+ private IEvaluator evalPattern = args[1].createEvaluator(array0);
+ private ByteArrayAccessibleOutputStream lastPattern = new ByteArrayAccessibleOutputStream();
+ private UTF8CharSequence carSeq = new UTF8CharSequence();
+ private IBinaryComparator strComp = AqlBinaryComparatorFactoryProvider.INSTANCE
+ .getBinaryComparatorFactory(BuiltinType.ASTRING, OrderKind.ASC).createBinaryComparator();
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ASTRING);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private Matcher matcher;
+ private Pattern pattern;
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ // evaluate the pattern first
+ try {
+ array0.reset();
+ evalPattern.evaluate(tuple);
+ if (array0.getBytes()[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, dout);
+ return;
+ }
+ boolean newPattern = false;
+ if (first) {
+ first = false;
+ newPattern = true;
+ } else {
+ int c = strComp.compare(array0.getBytes(), array0.getStartIndex(), array0.getLength(),
+ lastPattern.getByteArray(), 0, lastPattern.size());
+ if (c != 0) {
+ newPattern = true;
+ }
+ }
+ if (newPattern) {
+ lastPattern.reset();
+ lastPattern.write(array0.getBytes(), array0.getStartIndex(), array0.getLength());
+ // ! object creation !
+ DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+ lastPattern.getByteArray()));
+ AString strPattern = (AString) stringSerde.deserialize(di);
+ pattern = Pattern.compile(strPattern.getStringValue());
+
+ }
+ array0.reset();
+ evalString.evaluate(tuple);
+ if (array0.getBytes()[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, dout);
+ return;
+ }
+ carSeq.reset(array0, 1);
+ if (newPattern) {
+ matcher = pattern.matcher(carSeq);
+ } else {
+ matcher.reset(carSeq);
+ }
+ ABoolean res = (matcher.find(0)) ? ABoolean.TRUE : ABoolean.FALSE;
+ booleanSerde.serialize(res, dout);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityDescriptor.java
new file mode 100644
index 0000000..cbfc727
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityDescriptor.java
@@ -0,0 +1,237 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AUnorderedListSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.SimilarityFiltersCache;
+import edu.uci.ics.fuzzyjoin.IntArray;
+import edu.uci.ics.fuzzyjoin.similarity.PartialIntersect;
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityFilters;
+import edu.uci.ics.fuzzyjoin.similarity.SimilarityMetric;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class SimilarityDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "similarity", 7,
+ true);
+
+ private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+ private final static byte SER_UNORDEREDLIST_TYPE_TAG = ATypeTag.UNORDEREDLIST.serialize();
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+ return new IEvaluator() {
+
+ private final DataOutput out = output.getDataOutput();
+ private final ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private final IEvaluator evalLen1 = args[0].createEvaluator(inputVal);
+ private final IEvaluator evalTokens1 = args[1].createEvaluator(inputVal);
+ private final IEvaluator evalLen2 = args[2].createEvaluator(inputVal);
+ private final IEvaluator evalTokens2 = args[3].createEvaluator(inputVal);
+ private final IEvaluator evalTokenPrefix = args[4].createEvaluator(inputVal);
+ private final IEvaluator evalSimilarity = args[5].createEvaluator(inputVal);
+ private final IEvaluator evalThreshold = args[6].createEvaluator(inputVal);
+
+ private final SimilarityFiltersCache similarityFiltersCache = new SimilarityFiltersCache();
+
+ private final IntArray tokens1 = new IntArray();
+ private final IntArray tokens2 = new IntArray();
+ private final PartialIntersect parInter = new PartialIntersect();
+
+ // result
+ private final AMutableDouble res = new AMutableDouble(0);
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ // similarity threshold
+ inputVal.reset();
+ evalThreshold.evaluate(tuple);
+ float similarityThreshold = (float) ADoubleSerializerDeserializer.getDouble(
+ inputVal.getBytes(), 1);
+
+ // similarity name
+ inputVal.reset();
+ evalSimilarity.evaluate(tuple);
+ SimilarityFilters similarityFilters = similarityFiltersCache.get(similarityThreshold,
+ inputVal.getBytes());
+
+ inputVal.reset();
+ evalLen1.evaluate(tuple);
+ int length1 = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ inputVal.reset();
+ evalLen2.evaluate(tuple);
+ int length2 = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ float sim = 0;
+
+ //
+ // -- - length filter - --
+ //
+ if (similarityFilters.passLengthFilter(length1, length2)) {
+
+ // -- - tokens1 - --
+ int i;
+ tokens1.reset();
+ inputVal.reset();
+ evalTokens1.evaluate(tuple);
+
+ byte[] serList = inputVal.getBytes();
+ if (serList[0] != SER_ORDEREDLIST_TYPE_TAG && serList[0] != SER_UNORDEREDLIST_TYPE_TAG) {
+ throw new AlgebricksException("Scan collection is not defined for values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[0]));
+ }
+
+ int lengthTokens1;
+ if (serList[0] == SER_ORDEREDLIST_TYPE_TAG) {
+ lengthTokens1 = AOrderedListSerializerDeserializer
+ .getNumberOfItems(inputVal.getBytes());
+ // read tokens
+ for (i = 0; i < lengthTokens1; i++) {
+ int itemOffset;
+ try {
+ itemOffset = AOrderedListSerializerDeserializer.getItemOffset(serList, i);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ tokens1.add(IntegerSerializerDeserializer.getInt(serList, itemOffset));
+ }
+ } else {
+ lengthTokens1 = AUnorderedListSerializerDeserializer.getNumberOfItems(inputVal
+ .getBytes());
+ // read tokens
+ for (i = 0; i < lengthTokens1; i++) {
+ int itemOffset;
+ try {
+ itemOffset = AUnorderedListSerializerDeserializer.getItemOffset(serList, i);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ tokens1.add(IntegerSerializerDeserializer.getInt(serList, itemOffset));
+ }
+ }
+ // pad tokens
+ for (; i < length1; i++) {
+ tokens1.add(Integer.MAX_VALUE);
+ }
+
+ // -- - tokens2 - --
+ tokens2.reset();
+ inputVal.reset();
+ evalTokens2.evaluate(tuple);
+
+ serList = inputVal.getBytes();
+ if (serList[0] != SER_ORDEREDLIST_TYPE_TAG && serList[0] != SER_UNORDEREDLIST_TYPE_TAG) {
+ throw new AlgebricksException("Scan collection is not defined for values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[0]));
+ }
+
+ int lengthTokens2;
+ if (serList[0] == SER_ORDEREDLIST_TYPE_TAG) {
+ lengthTokens2 = AOrderedListSerializerDeserializer
+ .getNumberOfItems(inputVal.getBytes());
+ // read tokens
+ for (i = 0; i < lengthTokens2; i++) {
+ int itemOffset;
+ try {
+ itemOffset = AOrderedListSerializerDeserializer.getItemOffset(serList, i);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ tokens2.add(IntegerSerializerDeserializer.getInt(serList, itemOffset));
+ }
+ } else {
+ lengthTokens2 = AUnorderedListSerializerDeserializer.getNumberOfItems(inputVal
+ .getBytes());
+ // read tokens
+ for (i = 0; i < lengthTokens2; i++) {
+ int itemOffset;
+ try {
+ itemOffset = AUnorderedListSerializerDeserializer.getItemOffset(serList, i);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ tokens2.add(IntegerSerializerDeserializer.getInt(serList, itemOffset));
+ }
+ }
+ // pad tokens
+ for (; i < length2; i++) {
+ tokens2.add(Integer.MAX_VALUE);
+ }
+
+ // -- - token prefix - --
+ inputVal.reset();
+ evalTokenPrefix.evaluate(tuple);
+ int tokenPrefix = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ //
+ // -- - position filter - --
+ //
+ SimilarityMetric.getPartialIntersectSize(tokens1.get(), 0, tokens1.length(), tokens2.get(),
+ 0, tokens2.length(), tokenPrefix, parInter);
+ if (similarityFilters.passPositionFilter(parInter.intersectSize, parInter.posXStop,
+ length1, parInter.posYStop, length2)) {
+
+ //
+ // -- - suffix filter - --
+ //
+ if (similarityFilters.passSuffixFilter(tokens1.get(), 0, tokens1.length(),
+ parInter.posXStart, tokens2.get(), 0, tokens2.length(), parInter.posYStart)) {
+
+ sim = similarityFilters.passSimilarityFilter(tokens1.get(), 0, tokens1.length(),
+ parInter.posXStop + 1, tokens2.get(), 0, tokens2.length(),
+ parInter.posYStop + 1, parInter.intersectSize);
+ }
+ }
+ }
+
+ res.setValue(sim);
+
+ try {
+ doubleSerde.serialize(res, out);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardCheckDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardCheckDescriptor.java
new file mode 100644
index 0000000..b84019d
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardCheckDescriptor.java
@@ -0,0 +1,111 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.IAOrderedListBuilder;
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.SimilarityJaccardEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+//assumes that both arguments are sorted by the same ordering
+
+public class SimilarityJaccardCheckDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "similarity-jaccard-check", 3, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ return new SimilarityJaccardCheckEvaluator(args, output);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ private static class SimilarityJaccardCheckEvaluator extends SimilarityJaccardEvaluator {
+
+ private final IEvaluator jaccThreshEval;
+ private float jaccThresh = -1f;
+
+ private IAOrderedListBuilder listBuilder;
+ private ArrayBackedValueStorage inputVal;
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ private final AOrderedListType listType = new AOrderedListType(BuiltinType.ANY, "list");
+
+ public SimilarityJaccardCheckEvaluator(IEvaluatorFactory[] args, IDataOutputProvider output)
+ throws AlgebricksException {
+ super(args, output);
+ jaccThreshEval = args[2].createEvaluator(argOut);
+ listBuilder = new OrderedListBuilder();
+ inputVal = new ArrayBackedValueStorage();
+ }
+
+ @Override
+ protected void runArgEvals(IFrameTupleReference tuple) throws AlgebricksException {
+ super.runArgEvals(tuple);
+ int jaccThreshStart = argOut.getLength();
+ jaccThreshEval.evaluate(tuple);
+ jaccThresh = (float) AFloatSerializerDeserializer.getFloat(argOut.getBytes(), jaccThreshStart
+ + typeIndicatorSize);
+ }
+
+ @Override
+ protected float computeResult(byte[] bytes, int firstStart, int secondStart, ATypeTag argType)
+ throws AlgebricksException {
+ firstListIter.reset(bytes, firstStart);
+ secondListIter.reset(bytes, secondStart);
+ // Check for special case where one of the lists is empty, since
+ // list types won't match.
+ if (firstListIter.size() == 0 || secondListIter.size() == 0) {
+ return (jaccThresh == 0.0f) ? 0.0f : -1.0f;
+ }
+ if (firstTypeTag == ATypeTag.ANY || secondTypeTag == ATypeTag.ANY)
+ throw new AlgebricksException("\n Jaccard can only be called on homogenous lists");
+ return jaccard.getSimilarity(firstListIter, secondListIter, jaccThresh);
+ }
+
+ @Override
+ protected void writeResult(float jacc) throws IOException {
+ listBuilder.reset(listType);
+ boolean matches = (jacc < 0) ? false : true;
+ inputVal.reset();
+ booleanSerde.serialize(matches ? ABoolean.TRUE : ABoolean.FALSE, inputVal.getDataOutput());
+ listBuilder.addItem(inputVal);
+
+ inputVal.reset();
+ aFloat.setValue((matches) ? jacc : 0.0f);
+ floatSerde.serialize(aFloat, inputVal.getDataOutput());
+ listBuilder.addItem(inputVal);
+
+ listBuilder.write(out, true);
+ }
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardDescriptor.java
new file mode 100644
index 0000000..4c598cc
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardDescriptor.java
@@ -0,0 +1,37 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.SimilarityJaccardEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+//assumes that both arguments are sorted by the same ordering
+
+public class SimilarityJaccardDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "similarity-jaccard", 2, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ return new SimilarityJaccardEvaluator(args, output);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardPrefixCheckDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardPrefixCheckDescriptor.java
new file mode 100644
index 0000000..c8b1c9b
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardPrefixCheckDescriptor.java
@@ -0,0 +1,89 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.IAOrderedListBuilder;
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.AFloat;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.SimilarityJaccardPrefixEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+public class SimilarityJaccardPrefixCheckDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "similarity-jaccard-prefix-check", 6, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new SimilarityJaccardPrefixCheckEvaluator(args, output);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ private static class SimilarityJaccardPrefixCheckEvaluator extends SimilarityJaccardPrefixEvaluator {
+
+ private final IAOrderedListBuilder listBuilder;
+ private ArrayBackedValueStorage inputVal;
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<AFloat> floatSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ private final AMutableFloat aFloat = new AMutableFloat(0);
+
+ private final AOrderedListType listType = new AOrderedListType(BuiltinType.ANY, "list");
+
+ public SimilarityJaccardPrefixCheckEvaluator(IEvaluatorFactory[] args, IDataOutputProvider output)
+ throws AlgebricksException {
+ super(args, output);
+ listBuilder = new OrderedListBuilder();
+ inputVal = new ArrayBackedValueStorage();
+ }
+
+ @Override
+ public void writeResult() throws AlgebricksException, IOException {
+ listBuilder.reset(listType);
+ boolean matches = (sim <= 0) ? false : true;
+ float jaccSim = (matches) ? sim : 0.0f;
+
+ inputVal.reset();
+ booleanSerde.serialize(matches ? ABoolean.TRUE : ABoolean.FALSE, inputVal.getDataOutput());
+ listBuilder.addItem(inputVal);
+
+ inputVal.reset();
+ aFloat.setValue(jaccSim);
+ floatSerde.serialize(aFloat, inputVal.getDataOutput());
+ listBuilder.addItem(inputVal);
+
+ listBuilder.write(out, true);
+
+ }
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardPrefixDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardPrefixDescriptor.java
new file mode 100644
index 0000000..eee64ea
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SimilarityJaccardPrefixDescriptor.java
@@ -0,0 +1,35 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.SimilarityJaccardPrefixEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+public class SimilarityJaccardPrefixDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "similarity-jaccard-prefix", 6, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new SimilarityJaccardPrefixEvaluator(args, output);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialAreaDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialAreaDescriptor.java
new file mode 100644
index 0000000..0b1d2b9e
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialAreaDescriptor.java
@@ -0,0 +1,107 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.Coordinate;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ACircleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARectangleSerializerDeserializer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.SpatialUtils;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SpatialAreaDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "spatial-area",
+ 1, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private IEvaluator eval = args[0].createEvaluator(argOut);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+ eval.evaluate(tuple);
+
+ try {
+ byte[] bytes = argOut.getBytes();
+ ATypeTag tag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes[0]);
+ double area = 0.0;
+
+ switch (tag) {
+ case POLYGON:
+ int numOfPoints = AInt16SerializerDeserializer.getShort(argOut.getBytes(), 1);
+
+ if (numOfPoints < 3) {
+ throw new AlgebricksException("Polygon must have at least 3 points");
+ }
+ area = Math.abs(SpatialUtils.polygonArea(argOut.getBytes(), numOfPoints));
+ break;
+ case CIRCLE:
+ double radius = ADoubleSerializerDeserializer.getDouble(argOut.getBytes(),
+ ACircleSerializerDeserializer.getRadiusOffset());
+ area = SpatialUtils.pi() * radius * radius;
+ break;
+ case RECTANGLE:
+ double x1 = ADoubleSerializerDeserializer.getDouble(argOut.getBytes(),
+ ARectangleSerializerDeserializer
+ .getBottomLeftCoordinateOffset(Coordinate.X));
+ double y1 = ADoubleSerializerDeserializer.getDouble(argOut.getBytes(),
+ ARectangleSerializerDeserializer
+ .getBottomLeftCoordinateOffset(Coordinate.Y));
+
+ double x2 = ADoubleSerializerDeserializer.getDouble(argOut.getBytes(),
+ ARectangleSerializerDeserializer
+ .getUpperRightCoordinateOffset(Coordinate.X));
+ double y2 = ADoubleSerializerDeserializer.getDouble(argOut.getBytes(),
+ ARectangleSerializerDeserializer
+ .getUpperRightCoordinateOffset(Coordinate.Y));
+ area = (x2 - x1) * (y2 - y1);
+ break;
+ default:
+ throw new NotImplementedException("spatial-area does not support the type: " + tag
+ + " It is only implemented for POLYGON, CIRCLE and RECTANGLE.");
+ }
+ out.writeByte(ATypeTag.DOUBLE.serialize());
+ out.writeDouble(area);
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialCellDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialCellDescriptor.java
new file mode 100644
index 0000000..c2a6d6b
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialCellDescriptor.java
@@ -0,0 +1,110 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.Coordinate;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutablePoint;
+import edu.uci.ics.asterix.om.base.AMutableRectangle;
+import edu.uci.ics.asterix.om.base.ARectangle;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SpatialCellDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "spatial-cell",
+ 4, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+
+ private ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput2 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput3 = new ArrayBackedValueStorage();
+ private IEvaluator eval0 = args[0].createEvaluator(outInput0);
+ private IEvaluator eval1 = args[1].createEvaluator(outInput1);
+ private IEvaluator eval2 = args[2].createEvaluator(outInput2);
+ private IEvaluator eval3 = args[3].createEvaluator(outInput3);
+ private AMutableRectangle aRectangle = new AMutableRectangle(null, null);
+ private AMutablePoint[] aPoint = { new AMutablePoint(0, 0), new AMutablePoint(0, 0) };
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ARectangle> rectangleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ARECTANGLE);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+ outInput2.reset();
+ eval2.evaluate(tuple);
+ outInput3.reset();
+ eval3.evaluate(tuple);
+
+ try {
+ ATypeTag tag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(outInput0.getBytes()[0]);
+ if (tag == ATypeTag.POINT) {
+ double xLoc = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
+ double yLoc = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));
+
+ double xOrigin = ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
+ double yOrigin = ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));
+
+ double xInc = ADoubleSerializerDeserializer.getDouble(outInput2.getBytes(), 1);
+ double yInc = ADoubleSerializerDeserializer.getDouble(outInput3.getBytes(), 1);
+
+ double x = xOrigin + (Math.floor((xLoc - xOrigin) / xInc)) * xInc;
+ double y = yOrigin + (Math.floor((yLoc - yOrigin) / yInc)) * yInc;
+ aPoint[0].setValue(x, y);
+ aPoint[1].setValue(x + xInc, y + yInc);
+ aRectangle.setValue(aPoint[0], aPoint[1]);
+ rectangleSerde.serialize(aRectangle, out);
+ } else {
+ throw new NotImplementedException("spatial-cell does not support the type: " + tag
+ + " It is only implemented for POINT.");
+ }
+ } catch (IOException e1) {
+ throw new AlgebricksException(e1);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialDistanceDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialDistanceDescriptor.java
new file mode 100644
index 0000000..130ca4f
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialDistanceDescriptor.java
@@ -0,0 +1,94 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.Coordinate;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SpatialDistanceDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "spatial-distance", 2, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private IEvaluator eval0 = args[0].createEvaluator(outInput0);
+ private IEvaluator eval1 = args[1].createEvaluator(outInput1);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+
+ try {
+ byte[] bytes0 = outInput0.getBytes();
+ byte[] bytes1 = outInput1.getBytes();
+ ATypeTag tag0 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes0[0]);
+ ATypeTag tag1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes1[0]);
+ double distance = 0.0;
+ if (tag0 == ATypeTag.POINT) {
+ if (tag1 == ATypeTag.POINT) {
+ double x1 = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
+ double y1 = ADoubleSerializerDeserializer.getDouble(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));
+ double x2 = ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
+ double y2 = ADoubleSerializerDeserializer.getDouble(outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));
+ distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
+ } else {
+ throw new NotImplementedException("spatial-distance does not support the type: "
+ + tag1 + " It is only implemented for POINT.");
+ }
+ } else {
+ throw new NotImplementedException("spatial-distance does not support the type: " + tag0
+ + " It is only implemented for POINT.");
+ }
+ out.writeByte(ATypeTag.DOUBLE.serialize());
+ out.writeDouble(distance);
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialIntersectDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialIntersectDescriptor.java
new file mode 100644
index 0000000..315cafb
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SpatialIntersectDescriptor.java
@@ -0,0 +1,1029 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.Coordinate;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ACircleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ALineSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AObjectSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APolygonSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARectangleSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.DoubleArray;
+import edu.uci.ics.asterix.runtime.evaluators.common.SpatialUtils;
+import edu.uci.ics.fuzzyjoin.IntArray;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SpatialIntersectDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "spatial-intersect", 2, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private final DataOutput out = output.getDataOutput();
+ private final ArrayBackedValueStorage outInput0 = new ArrayBackedValueStorage();
+ private final ArrayBackedValueStorage outInput1 = new ArrayBackedValueStorage();
+ private final IEvaluator eval0 = args[0].createEvaluator(outInput0);
+ private final IEvaluator eval1 = args[1].createEvaluator(outInput1);
+ private final IBinaryComparator ascDoubleComp = AqlBinaryComparatorFactoryProvider.DOUBLE_POINTABLE_INSTANCE
+ .createBinaryComparator();
+ private final SpatialUtils spatialUtils = new SpatialUtils();
+ private final IntArray pointsOffsets0 = new IntArray();
+ private final IntArray pointsOffsets1 = new IntArray();
+ private final DoubleArray trianglesX0 = new DoubleArray();
+ private final DoubleArray trianglesY0 = new DoubleArray();
+ private final DoubleArray trianglesX1 = new DoubleArray();
+ private final DoubleArray trianglesY1 = new DoubleArray();
+
+ private boolean pointOnLine(byte[] bytes0, byte[] bytes1) throws HyracksDataException {
+ double startX = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getStartPointCoordinateOffset(Coordinate.X));
+ double startY = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getStartPointCoordinateOffset(Coordinate.Y));
+ double endX = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.X));
+ double endY = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.Y));
+
+ double pX = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
+ double pY = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));
+
+ double crossProduct = SpatialUtils.crossProduct(pY - startY, pX - startX, endY - startY, endX
+ - startX);
+ if (Math.abs(crossProduct) > SpatialUtils.doubleEpsilon()) { // crossProduct
+ // != 0
+ return false;
+ }
+
+ double dotProduct = SpatialUtils.dotProduct((pX - startX), (pY - startY), (endX - startX),
+ (endY - startY));
+ if (dotProduct < 0.0) {
+ return false;
+ }
+
+ double squaredLengthBA = (endX - startX) * (endX - startX) + (endY - startY) * (endY - startY);
+ if (dotProduct > squaredLengthBA) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean pointInPolygon(byte[] bytes0, byte[] bytes1) throws HyracksDataException { // ray
+ // casting
+
+ double pX = ADoubleSerializerDeserializer.getDouble(bytes0,
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
+ double pY = ADoubleSerializerDeserializer.getDouble(bytes0,
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));
+ int numOfPoints1 = AInt16SerializerDeserializer.getShort(bytes1,
+ APolygonSerializerDeserializer.getNumberOfPointsOffset());
+
+ if (numOfPoints1 < 3) {
+ throw new HyracksDataException("Polygon must have at least 3 points.");
+ }
+
+ int counter = 0;
+ double xInters;
+ double x1, x2, y1, y2;
+ x1 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(0, Coordinate.X));
+ y1 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(0, Coordinate.Y));
+
+ for (int i = 1; i <= numOfPoints1; i++) {
+ if (i == numOfPoints1) {
+ x2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(0, Coordinate.X));
+ y2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(0, Coordinate.Y));
+ } else {
+ x2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(i, Coordinate.X));
+ y2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(i, Coordinate.Y));
+ }
+ if (pY > Math.min(y1, y2)) {
+ if (pY <= Math.max(y1, y2)) {
+ if (pX <= Math.max(x1, x2)) {
+ if (y1 != y2) {
+ xInters = (pY - y1) * (x2 - x1) / (y2 - y1) + x1;
+ if (x1 == x2 || pX <= xInters) {
+ counter++;
+ }
+ }
+ }
+ }
+ }
+ x1 = x2;
+ y1 = y2;
+ }
+ if (counter % 2 == 1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private boolean pointInCircle(byte[] bytes0, byte[] bytes1) throws HyracksDataException {
+ double x = ADoubleSerializerDeserializer.getDouble(bytes0,
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
+ double y = ADoubleSerializerDeserializer.getDouble(bytes0,
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));
+
+ double cX = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.X));
+ double cY = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.Y));
+ double radius = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ACircleSerializerDeserializer.getRadiusOffset());
+
+ if ((x - cX) * (x - cX) + (y - cY) * (y - cY) < (radius * radius)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean lineLineIntersection(double startX1, double startY1, double endX1, double endY1,
+ double startX2, double startY2, double endX2, double endY2) {
+ double A1 = endY1 - startY1;
+ double B1 = startX1 - endX1;
+ double C1 = A1 * startX1 + B1 * startY1;
+
+ double A2 = endY2 - startY2;
+ double B2 = startX2 - endX2;
+ double C2 = A2 * startX2 + B2 * startY2;
+
+ double det = (A1 * B2) - (A2 * B1);
+ if (Math.abs(det) > SpatialUtils.doubleEpsilon()) { // det
+ // !=
+ // 0
+ double x = (B2 * C1 - B1 * C2) / det;
+ double y = (A1 * C2 - A2 * C1) / det;
+
+ if ((x >= Math.min(startX1, endX1) && x <= Math.max(startX1, endX1))
+ && (y >= Math.min(startY1, endY1) && y <= Math.max(startY1, endY1))) {
+ if ((x >= Math.min(startX2, endX2) && x <= Math.max(startX2, endX2))
+ && (y >= Math.min(startY2, endY2) && y <= Math.max(startY2, endY2))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean linePolygonIntersection(byte[] bytes0, byte[] bytes1) throws HyracksDataException {
+ double startX1 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getStartPointCoordinateOffset(Coordinate.X));
+ double startY1 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getStartPointCoordinateOffset(Coordinate.Y));
+ double endX1 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.X));
+ double endY1 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.Y));
+
+ int numOfPoints1 = AInt16SerializerDeserializer.getShort(bytes1,
+ APolygonSerializerDeserializer.getNumberOfPointsOffset());
+
+ if (numOfPoints1 < 3) {
+ throw new HyracksDataException("Polygon must have at least 3 points.");
+ }
+ for (int i = 0; i < numOfPoints1; i++) {
+ double startX2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(i, Coordinate.X));
+ double startY2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(i, Coordinate.Y));
+
+ double endX2;
+ double endY2;
+ if (i + 1 == numOfPoints1) {
+ endX2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(0, Coordinate.X));
+ endY2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(0, Coordinate.Y));
+ } else {
+ endX2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(i + 1, Coordinate.X));
+ endY2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ APolygonSerializerDeserializer.getCoordinateOffset(i + 1, Coordinate.Y));
+ }
+
+ boolean intersect = lineLineIntersection(startX1, startY1, endX1, endY1, startX2, startY2,
+ endX2, endY2);
+ if (intersect) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean lineRectangleIntersection(byte[] bytes0, byte[] bytes1) throws HyracksDataException {
+ double startX1 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getStartPointCoordinateOffset(Coordinate.X));
+ double startY1 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getStartPointCoordinateOffset(Coordinate.Y));
+ double endX1 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.X));
+ double endY1 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.Y));
+
+ double x1 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ARectangleSerializerDeserializer.getBottomLeftCoordinateOffset(Coordinate.X));
+ double y1 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ARectangleSerializerDeserializer.getBottomLeftCoordinateOffset(Coordinate.Y));
+
+ double x2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ARectangleSerializerDeserializer.getUpperRightCoordinateOffset(Coordinate.X));
+ double y2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ARectangleSerializerDeserializer.getUpperRightCoordinateOffset(Coordinate.Y));
+
+ if (lineLineIntersection(startX1, startY1, endX1, endY1, x1, y1, x1, y2)
+ || lineLineIntersection(startX1, startY1, endX1, endY1, x1, y2, x2, y2)
+ || lineLineIntersection(startX1, startY1, endX1, endY1, x2, y2, x2, y1)
+ || lineLineIntersection(startX1, startY1, endX1, endY1, x2, y1, x1, y1)) {
+ return true;
+ }
+ return false;
+
+ }
+
+ private boolean lineCircleIntersection(byte[] bytes0, byte[] bytes1) throws HyracksDataException {
+ double startX = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getStartPointCoordinateOffset(Coordinate.X));
+ double startY = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getStartPointCoordinateOffset(Coordinate.Y));
+ double endX = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.X));
+ double endY = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ALineSerializerDeserializer.getEndPointCoordinateOffset(Coordinate.Y));
+
+ double cX = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.X));
+ double cY = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.Y));
+ double radius = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ACircleSerializerDeserializer.getRadiusOffset());
+
+ double dx = endX - startX;
+ double dy = endY - startY;
+ double t = -((startX - cX) * dx + (startY - cY) * dy) / ((dx * dx) + (dy * dy));
+
+ if (t < 0.0) {
+ t = 0.0;
+ } else if (t > 1.0) {
+ t = 1.0;
+ }
+
+ dx = (startX + t * (endX - startX)) - cX;
+ dy = (startY + t * (endY - startY)) - cY;
+ double rt = (dx * dx) + (dy * dy);
+ if (rt < (radius * radius)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean findEar(byte[] bytes, int u, int v, int w, int n, IntArray pointsOffsets)
+ throws HyracksDataException {
+ int p;
+ double Ax, Ay, Bx, By, Cx, Cy, Px, Py;
+
+ Ax = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(pointsOffsets.get(u), Coordinate.X));
+ Ay = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(pointsOffsets.get(u), Coordinate.Y));
+
+ Bx = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(pointsOffsets.get(v), Coordinate.X));
+ By = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(pointsOffsets.get(v), Coordinate.Y));
+
+ Cx = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(pointsOffsets.get(w), Coordinate.X));
+ Cy = ADoubleSerializerDeserializer.getDouble(bytes,
+ APolygonSerializerDeserializer.getCoordinateOffset(pointsOffsets.get(w), Coordinate.Y));
+
+ if (SpatialUtils.doubleEpsilon() > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) {
+
+ return false;
+ }
+
+ for (p = 0; p < n; p++) {
+ if ((p == u) || (p == v) || (p == w)) {
+ continue;
+ }
+ Px = ADoubleSerializerDeserializer.getDouble(bytes, APolygonSerializerDeserializer
+ .getCoordinateOffset(pointsOffsets.get(p), Coordinate.X));
+ Py = ADoubleSerializerDeserializer.getDouble(bytes, APolygonSerializerDeserializer
+ .getCoordinateOffset(pointsOffsets.get(p), Coordinate.Y));
+ if (pointInsideTriangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private int triangulatePolygon(byte[] bytes, int numOfPoints, IntArray pointsOffsets,
+ DoubleArray trianglesX, DoubleArray trianglesY, int triangleId,
+ int nonSimplePolygonDetection, int middleVertex) throws HyracksDataException { // Ear
+ // clipping
+
+ if (numOfPoints < 3) {
+ return -1;
+ }
+
+ boolean foundEar = false;
+ int v = middleVertex;
+ while (!foundEar) {
+ if (0 >= (nonSimplePolygonDetection--)) {
+ throw new NotImplementedException("Non-simple polygons are not supported.");
+ }
+ int u = v;
+ if (numOfPoints <= u) {
+ u = 0;
+ }
+ v = u + 1;
+ if (numOfPoints <= v) {
+ v = 0;
+ }
+ int w = v + 1;
+ if (numOfPoints <= w) {
+ w = 0;
+ }
+
+ if (findEar(bytes, u, v, w, numOfPoints, pointsOffsets)) {
+ int s, t;
+
+ addRectangle(trianglesX, trianglesY);
+
+ SpatialUtils.setTriangleXCoordinate(trianglesX, triangleId, 0,
+ ADoubleSerializerDeserializer.getDouble(bytes, APolygonSerializerDeserializer
+ .getCoordinateOffset(pointsOffsets.get(u), Coordinate.X)));
+
+ SpatialUtils.setTriangleYCoordinate(trianglesY, triangleId, 0,
+ ADoubleSerializerDeserializer.getDouble(bytes, APolygonSerializerDeserializer
+ .getCoordinateOffset(pointsOffsets.get(u), Coordinate.Y)));
+
+ SpatialUtils.setTriangleXCoordinate(trianglesX, triangleId, 1,
+ ADoubleSerializerDeserializer.getDouble(bytes, APolygonSerializerDeserializer
+ .getCoordinateOffset(pointsOffsets.get(v), Coordinate.X)));
+
+ SpatialUtils.setTriangleYCoordinate(trianglesY, triangleId, 1,
+ ADoubleSerializerDeserializer.getDouble(bytes, APolygonSerializerDeserializer
+ .getCoordinateOffset(pointsOffsets.get(v), Coordinate.Y)));
+
+ SpatialUtils.setTriangleXCoordinate(trianglesX, triangleId, 2,
+ ADoubleSerializerDeserializer.getDouble(bytes, APolygonSerializerDeserializer
+ .getCoordinateOffset(pointsOffsets.get(w), Coordinate.X)));
+
+ SpatialUtils.setTriangleYCoordinate(trianglesY, triangleId, 2,
+ ADoubleSerializerDeserializer.getDouble(bytes, APolygonSerializerDeserializer
+ .getCoordinateOffset(pointsOffsets.get(w), Coordinate.Y)));
+
+ // remove v from polygon
+ for (s = v, t = v + 1; t < numOfPoints; s++, t++) {
+ pointsOffsets.get()[s] = pointsOffsets.get(t);
+ }
+ foundEar = true;
+ }
+ }
+
+ return v;
+ }
+
+ private boolean triangleTriangleIntersection(DoubleArray trianglesX0, DoubleArray trianglesY0,
+ int triangleId0, DoubleArray trianglesX1, DoubleArray trianglesY1, int triangleId1)
+ throws HyracksDataException { // separating axis
+ // theorem
+
+ for (int side = 0; side < 3; side++) {
+ spatialUtils.findNormals(trianglesX0, trianglesY0, triangleId0, side);
+ spatialUtils.projectPolygon(trianglesX0, trianglesY0, triangleId0, spatialUtils.getXAxis(),
+ spatialUtils.getYAxis());
+ double min1 = spatialUtils.getMinProjection();
+ double max1 = spatialUtils.getMaxProjection();
+ spatialUtils.projectPolygon(trianglesX1, trianglesY1, triangleId1, spatialUtils.getXAxis(),
+ spatialUtils.getYAxis());
+ double min2 = spatialUtils.getMinProjection();
+ double max2 = spatialUtils.getMaxProjection();
+
+ if (max1 < min2 || min1 > max2) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private final boolean pointInsideTriangle(double x1, double y1, double x2, double y2, double x3,
+ double y3, double pX, double pY)
+
+ {
+ return pointsOnSameSide(pX, pY, x1, y1, x2, y2, x3, y3)
+ && pointsOnSameSide(pX, pY, x2, y2, x1, y1, x3, y3)
+ && pointsOnSameSide(pX, pY, x3, y3, x1, y1, x2, y2);
+ }
+
+ private boolean pointsOnSameSide(double pX, double pY, double x1, double y1, double x2, double y2,
+ double x3, double y3) {
+ double cp1 = SpatialUtils.crossProduct(x3 - x2, y3 - y2, pX - x2, pY - y2);
+ double cp2 = SpatialUtils.crossProduct(x3 - x2, y3 - y2, x1 - x2, y1 - y2);
+ return (cp1 * cp2) >= 0.0;
+ }
+
+ private boolean circleTriangleIntersection(byte[] bytes0, DoubleArray trianglesX,
+ DoubleArray trianglesY, int triangleId) throws HyracksDataException { // separating
+ // axis
+ // theorem
+
+ double cX = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.X));
+ double cY = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.Y));
+ double radius = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ACircleSerializerDeserializer.getRadiusOffset());
+
+ double distance = Double.MAX_VALUE;
+ double distanceSquared;
+
+ double temp;
+ double closestPointX = 0.0;
+ double closestPointY = 0.0;
+ for (int i = 0; i < 3; i++) {
+ double pX = SpatialUtils.getTriangleXCoordinate(trianglesX, triangleId, i);
+ double pY = SpatialUtils.getTriangleXCoordinate(trianglesY, triangleId, i);
+
+ distanceSquared = (cX - pX) * (cX - pX) + (cY - pY) * (cY - pY);
+ if (distanceSquared < distance) {
+ distance = distanceSquared;
+ closestPointX = pX;
+ closestPointY = pY;
+ }
+ }
+
+ double x = Math.abs(cX - closestPointX);
+ double y = Math.abs(cY - closestPointY);
+
+ temp = Math.sqrt(SpatialUtils.dotProduct(x, y, x, y));
+ x /= temp;
+ y /= temp;
+
+ spatialUtils.projectPolygon(trianglesX, trianglesY, triangleId, x, y);
+
+ double min1 = spatialUtils.getMinProjection();
+ double max1 = spatialUtils.getMaxProjection();
+
+ double dotProduct = SpatialUtils.dotProduct(x, y, cX, cY);
+ double max2 = dotProduct + radius;
+ double min2 = dotProduct - radius;
+
+ if (max1 < min2 || min1 > max2) {
+ return false;
+ }
+
+ for (int side = 0; side < 3; side++) {
+ spatialUtils.findNormals(trianglesX, trianglesY, triangleId, side);
+ spatialUtils.projectPolygon(trianglesX, trianglesY, triangleId, spatialUtils.getXAxis(),
+ spatialUtils.getYAxis());
+ min1 = spatialUtils.getMinProjection();
+ max1 = spatialUtils.getMaxProjection();
+
+ dotProduct = SpatialUtils.dotProduct(spatialUtils.getXAxis(), spatialUtils.getYAxis(), cX,
+ cY);
+ max2 = dotProduct + radius;
+ min2 = dotProduct - radius;
+
+ if (max1 < min2 || min1 > max2) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean circleCircleIntersection(byte[] bytes0, byte[] bytes1) throws HyracksDataException {
+ double cX0 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.X));
+ double cY0 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.Y));
+ double radius0 = ADoubleSerializerDeserializer.getDouble(bytes0,
+ ACircleSerializerDeserializer.getRadiusOffset());
+
+ double cX1 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.X));
+ double cY1 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ACircleSerializerDeserializer.getCenterPointCoordinateOffset(Coordinate.Y));
+ double radius1 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ACircleSerializerDeserializer.getRadiusOffset());
+
+ double distanceSquared = SpatialUtils.dotProduct(cX0 - cX1, cY0 - cY1, cX0 - cX1, cY0 - cY1);
+ double radiusDistanceSquared = (radius0 + radius1) * (radius0 + radius1);
+ if (distanceSquared <= radiusDistanceSquared) {
+ return true;
+ }
+ return false;
+ }
+
+ private void getCounterClockWisePolygon(byte[] bytes, IntArray pointsOffsets, int numOfPoints)
+ throws HyracksDataException {
+ pointsOffsets.reset();
+ if (SpatialUtils.polygonArea(bytes, numOfPoints) > 0.0) {
+ for (int i = 0; i < numOfPoints; i++) {
+ pointsOffsets.add(i);
+ }
+ } else {
+ for (int i = 0; i < numOfPoints; i++) {
+ pointsOffsets.add((numOfPoints - 1) - i);
+ }
+ }
+ }
+
+ private boolean pointInRectangle(byte[] bytes0, byte[] bytes1) throws HyracksDataException {
+
+ double pX = ADoubleSerializerDeserializer.getDouble(bytes0,
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
+ double pY = ADoubleSerializerDeserializer.getDouble(bytes0,
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));
+
+ double x1 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ARectangleSerializerDeserializer.getBottomLeftCoordinateOffset(Coordinate.X));
+ double y1 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ARectangleSerializerDeserializer.getBottomLeftCoordinateOffset(Coordinate.Y));
+
+ double x2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ARectangleSerializerDeserializer.getUpperRightCoordinateOffset(Coordinate.X));
+ double y2 = ADoubleSerializerDeserializer.getDouble(bytes1,
+ ARectangleSerializerDeserializer.getUpperRightCoordinateOffset(Coordinate.Y));
+
+ if (pointInsideTriangle(x1, y1, x1, y2, x2, y2, pX, pY)
+ || pointInsideTriangle(x1, y1, x2, y1, x2, y2, pX, pY)) {
+ return true;
+ }
+ return false;
+
+ }
+
+ private void addRectangle(DoubleArray trianglesX, DoubleArray trianglesY) {
+ for (int i = 0; i < 3; i++) {
+ double temp = 0;
+ trianglesX.add(temp);
+ trianglesY.add(temp);
+ }
+ }
+
+ private boolean rectangleCircleIntersection(byte[] bytes0, byte[] bytes1)
+ throws HyracksDataException {
+ triangulateRectangle(bytes0, trianglesX0, trianglesY0);
+ boolean res = false;
+ // 2 triangles in a rectangle
+ for (int i = 0; i < 2; i++) {
+ res = circleTriangleIntersection(bytes1, trianglesX0, trianglesY0, i);
+ if (res) {
+ break;
+ }
+ }
+ return res;
+ }
+
+ private void triangulateRectangle(byte[] bytes, DoubleArray trianglesX, DoubleArray trianglesY)
+ throws HyracksDataException {
+ double x1 = ADoubleSerializerDeserializer.getDouble(bytes,
+ ARectangleSerializerDeserializer.getBottomLeftCoordinateOffset(Coordinate.X));
+ double y1 = ADoubleSerializerDeserializer.getDouble(bytes,
+ ARectangleSerializerDeserializer.getBottomLeftCoordinateOffset(Coordinate.Y));
+
+ double x2 = ADoubleSerializerDeserializer.getDouble(bytes,
+ ARectangleSerializerDeserializer.getUpperRightCoordinateOffset(Coordinate.X));
+ double y2 = ADoubleSerializerDeserializer.getDouble(bytes,
+ ARectangleSerializerDeserializer.getUpperRightCoordinateOffset(Coordinate.Y));
+ trianglesX.reset();
+ trianglesY.reset();
+
+ addRectangle(trianglesX, trianglesY);
+ addRectangle(trianglesX, trianglesY);
+
+ SpatialUtils.setTriangleXCoordinate(trianglesX, 0, 0, x1);
+ SpatialUtils.setTriangleYCoordinate(trianglesY, 0, 0, y1);
+
+ SpatialUtils.setTriangleXCoordinate(trianglesX, 0, 1, x2);
+ SpatialUtils.setTriangleYCoordinate(trianglesY, 0, 1, y1);
+
+ SpatialUtils.setTriangleXCoordinate(trianglesX, 0, 2, x2);
+ SpatialUtils.setTriangleYCoordinate(trianglesY, 0, 2, y2);
+
+ SpatialUtils.setTriangleXCoordinate(trianglesX, 1, 0, x2);
+ SpatialUtils.setTriangleYCoordinate(trianglesY, 1, 0, y2);
+
+ SpatialUtils.setTriangleXCoordinate(trianglesX, 1, 1, x1);
+ SpatialUtils.setTriangleYCoordinate(trianglesY, 1, 1, y2);
+
+ SpatialUtils.setTriangleXCoordinate(trianglesX, 1, 2, x1);
+ SpatialUtils.setTriangleYCoordinate(trianglesY, 1, 2, y1);
+ }
+
+ private boolean rectanglePolygonIntersection(byte[] bytes0, byte[] bytes1)
+ throws HyracksDataException, AlgebricksException {
+ int numOfPoints1 = AInt16SerializerDeserializer.getShort(bytes1,
+ APolygonSerializerDeserializer.getNumberOfPointsOffset());
+
+ if (numOfPoints1 < 3) {
+ throw new AlgebricksException("Polygon must have at least 3 points.");
+ }
+
+ getCounterClockWisePolygon(bytes1, pointsOffsets1, numOfPoints1);
+ int nonSimplePolygonDetection1 = 2 * numOfPoints1;
+ int middleVertex1 = numOfPoints1 - 1;
+ int numOfTriangles1 = 0;
+
+ trianglesX1.reset();
+ trianglesY1.reset();
+ while (true) {
+ middleVertex1 = triangulatePolygon(bytes1, numOfPoints1, pointsOffsets1, trianglesX1,
+ trianglesY1, numOfTriangles1, nonSimplePolygonDetection1, middleVertex1);
+
+ if (middleVertex1 == -1) {
+ break;
+ }
+
+ numOfPoints1--;
+ nonSimplePolygonDetection1 = 2 * numOfPoints1;
+ numOfTriangles1++;
+ }
+
+ triangulateRectangle(bytes0, trianglesX0, trianglesY0);
+ boolean res = false;
+ // 2 triangles in a rectangle
+ for (int j = 0; j < 2; j++) {
+ for (int i = 0; i < numOfTriangles1; i++) {
+
+ res = triangleTriangleIntersection(trianglesX1, trianglesY1, i, trianglesX0,
+ trianglesY0, j);
+
+ if (res) {
+ res = triangleTriangleIntersection(trianglesX0, trianglesY0, j, trianglesX1,
+ trianglesY1, i);
+
+ if (res) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean polygonCircleIntersection(byte[] bytes0, byte[] bytes1)
+ throws HyracksDataException, AlgebricksException {
+ int numOfPoints = AInt16SerializerDeserializer.getShort(bytes0,
+ APolygonSerializerDeserializer.getNumberOfPointsOffset());
+
+ if (numOfPoints < 3) {
+ throw new AlgebricksException("Polygon must have at least 3 points.");
+ }
+
+ getCounterClockWisePolygon(bytes0, pointsOffsets0, numOfPoints);
+ int nonSimplePolygonDetection = 2 * numOfPoints;
+ int middleVertex = numOfPoints - 1;
+ int numOfTriangles = 0;
+
+ trianglesX0.reset();
+ trianglesY0.reset();
+ boolean res = false;
+ while (true) {
+ middleVertex = triangulatePolygon(bytes0, numOfPoints, pointsOffsets0, trianglesX0,
+ trianglesY0, numOfTriangles, nonSimplePolygonDetection, middleVertex);
+
+ if (middleVertex == -1) {
+ break;
+ }
+ numOfPoints--;
+ nonSimplePolygonDetection = 2 * numOfPoints;
+ numOfTriangles++;
+ int lastTriangle = (trianglesX0.length() / 3) - 1;
+
+ res = circleTriangleIntersection(bytes1, trianglesX0, trianglesY0, lastTriangle);
+ if (res) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ outInput0.reset();
+ eval0.evaluate(tuple);
+ outInput1.reset();
+ eval1.evaluate(tuple);
+
+ try {
+ boolean res = false;
+ ATypeTag tag0 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(outInput0.getBytes()[0]);
+ ATypeTag tag1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(outInput1.getBytes()[0]);
+
+ switch (tag0) {
+ case POINT:
+ switch (tag1) {
+ case POINT:
+ if (ascDoubleComp.compare(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X), 8,
+ outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.X), 8) == 0) {
+ if (ascDoubleComp.compare(outInput0.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y),
+ 8, outInput1.getBytes(),
+ APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y),
+ 8) == 0) {
+ res = true;
+ }
+ }
+ break;
+ case LINE:
+ res = pointOnLine(outInput1.getBytes(), outInput0.getBytes());
+ break;
+ case POLYGON:
+ res = pointInPolygon(outInput0.getBytes(), outInput1.getBytes());
+ break;
+ case CIRCLE:
+ res = pointInCircle(outInput0.getBytes(), outInput1.getBytes());
+ break;
+ case RECTANGLE:
+ res = pointInRectangle(outInput0.getBytes(), outInput1.getBytes());
+ break;
+ default:
+ throw new NotImplementedException(
+ "spatial-intersection does not support the type: "
+ + tag1
+ + " It is only implemented for POINT, ALINE, POLYGON, and CIRCLE.");
+ }
+ break;
+ case LINE:
+ switch (tag1) {
+ case POINT:
+ res = pointOnLine(outInput0.getBytes(), outInput1.getBytes());
+ break;
+ case LINE:
+ double startX1 = ADoubleSerializerDeserializer.getDouble(outInput0
+ .getBytes(), ALineSerializerDeserializer
+ .getStartPointCoordinateOffset(Coordinate.X));
+ double startY1 = ADoubleSerializerDeserializer.getDouble(outInput0
+ .getBytes(), ALineSerializerDeserializer
+ .getStartPointCoordinateOffset(Coordinate.Y));
+ double endX1 = ADoubleSerializerDeserializer.getDouble(
+ outInput0.getBytes(), ALineSerializerDeserializer
+ .getEndPointCoordinateOffset(Coordinate.X));
+ double endY1 = ADoubleSerializerDeserializer.getDouble(
+ outInput0.getBytes(), ALineSerializerDeserializer
+ .getEndPointCoordinateOffset(Coordinate.Y));
+
+ double startX2 = ADoubleSerializerDeserializer.getDouble(outInput1
+ .getBytes(), ALineSerializerDeserializer
+ .getStartPointCoordinateOffset(Coordinate.X));
+ double startY2 = ADoubleSerializerDeserializer.getDouble(outInput1
+ .getBytes(), ALineSerializerDeserializer
+ .getStartPointCoordinateOffset(Coordinate.Y));
+ double endX2 = ADoubleSerializerDeserializer.getDouble(
+ outInput1.getBytes(), ALineSerializerDeserializer
+ .getEndPointCoordinateOffset(Coordinate.X));
+ double endY2 = ADoubleSerializerDeserializer.getDouble(
+ outInput1.getBytes(), ALineSerializerDeserializer
+ .getEndPointCoordinateOffset(Coordinate.Y));
+ res = lineLineIntersection(startX1, startY1, endX1, endY1, startX2,
+ startY2, endX2, endY2);
+ break;
+ case POLYGON:
+ res = linePolygonIntersection(outInput0.getBytes(), outInput1.getBytes());
+ break;
+ case CIRCLE:
+ res = lineCircleIntersection(outInput0.getBytes(), outInput1.getBytes());
+ break;
+ case RECTANGLE:
+ res = lineRectangleIntersection(outInput0.getBytes(), outInput1.getBytes());
+ break;
+ default:
+ throw new NotImplementedException(
+ "spatial-intersection does not support the type: "
+ + tag1
+ + " It is only implemented for POINT, ALINE, POLYGON, and CIRCLE.");
+ }
+ break;
+ case POLYGON:
+ switch (tag1) {
+ case POINT:
+ res = pointInPolygon(outInput1.getBytes(), outInput0.getBytes());
+ break;
+ case LINE:
+ res = linePolygonIntersection(outInput1.getBytes(), outInput0.getBytes());
+ break;
+ case POLYGON:
+ int numOfPoints0 = AInt16SerializerDeserializer.getShort(
+ outInput0.getBytes(),
+ APolygonSerializerDeserializer.getNumberOfPointsOffset());
+ int numOfPoints1 = AInt16SerializerDeserializer.getShort(
+ outInput1.getBytes(),
+ APolygonSerializerDeserializer.getNumberOfPointsOffset());
+
+ if (numOfPoints0 < 3 || numOfPoints1 < 3) {
+ throw new AlgebricksException("Polygon must have at least 3 points.");
+ }
+
+ getCounterClockWisePolygon(outInput0.getBytes(), pointsOffsets0,
+ numOfPoints0);
+ getCounterClockWisePolygon(outInput1.getBytes(), pointsOffsets1,
+ numOfPoints1);
+ int nonSimplePolygonDetection0 = 2 * numOfPoints0;
+ int nonSimplePolygonDetection1 = 2 * numOfPoints1;
+ boolean intersect = false;
+ int middleVertex0 = numOfPoints0 - 1;
+
+ int numOfTriangles1 = 0;
+ int middleVertex1 = numOfPoints1 - 1;
+ trianglesX1.reset();
+ trianglesY1.reset();
+ while (true) {
+ middleVertex1 = triangulatePolygon(outInput1.getBytes(), numOfPoints1,
+ pointsOffsets1, trianglesX1, trianglesY1, numOfTriangles1,
+ nonSimplePolygonDetection1, middleVertex1);
+
+ if (middleVertex1 == -1) {
+ break;
+ }
+
+ numOfPoints1--;
+ nonSimplePolygonDetection1 = 2 * numOfPoints1;
+ numOfTriangles1++;
+ }
+ int numOfTriangles0 = 0;
+ trianglesX0.reset();
+ trianglesY0.reset();
+ while (true) {
+ middleVertex0 = triangulatePolygon(outInput0.getBytes(), numOfPoints0,
+ pointsOffsets0, trianglesX0, trianglesY0, numOfTriangles0,
+ nonSimplePolygonDetection0, middleVertex0);
+
+ if (middleVertex0 == -1) {
+ break;
+ }
+ numOfPoints0--;
+ nonSimplePolygonDetection0 = 2 * numOfPoints0;
+ numOfTriangles0++;
+ int lastTriangle = (trianglesX0.length() / 3) - 1;
+
+ for (int i = 0; i < numOfTriangles1; i++) {
+
+ res = triangleTriangleIntersection(trianglesX0, trianglesY0,
+ lastTriangle, trianglesX1, trianglesY1, i);
+
+ if (res) {
+ res = triangleTriangleIntersection(trianglesX1, trianglesY1, i,
+ trianglesX0, trianglesY0, lastTriangle);
+
+ if (res) {
+ intersect = true;
+ break;
+ }
+ }
+ }
+ if (intersect) {
+ break;
+ }
+ }
+ break;
+ case CIRCLE:
+ res = polygonCircleIntersection(outInput0.getBytes(), outInput1.getBytes());
+ break;
+ case RECTANGLE:
+ res = rectanglePolygonIntersection(outInput1.getBytes(),
+ outInput0.getBytes());
+ break;
+ default:
+ throw new NotImplementedException(
+ "spatial-intersection does not support the type: "
+ + tag1
+ + " It is only implemented for POINT, ALINE, POLYGON, and CIRCLE.");
+ }
+ break;
+ case CIRCLE:
+ switch (tag1) {
+ case POINT:
+ res = pointInCircle(outInput1.getBytes(), outInput0.getBytes());
+ break;
+ case LINE:
+ res = lineCircleIntersection(outInput1.getBytes(), outInput0.getBytes());
+ break;
+ case POLYGON:
+ res = polygonCircleIntersection(outInput1.getBytes(), outInput0.getBytes());
+ break;
+ case CIRCLE:
+ res = circleCircleIntersection(outInput0.getBytes(), outInput1.getBytes());
+ break;
+ case RECTANGLE:
+ res = rectangleCircleIntersection(outInput1.getBytes(),
+ outInput0.getBytes());
+ break;
+ default:
+ throw new NotImplementedException(
+ "spatial-intersection does not support the type: "
+ + tag1
+ + " It is only implemented for POINT, ALINE, POLYGON, and CIRCLE.");
+ }
+ break;
+ case RECTANGLE:
+ switch (tag1) {
+ case POINT:
+ res = pointInRectangle(outInput1.getBytes(), outInput0.getBytes());
+ break;
+ case LINE:
+ res = lineRectangleIntersection(outInput1.getBytes(), outInput0.getBytes());
+ break;
+ case POLYGON:
+ res = rectanglePolygonIntersection(outInput0.getBytes(),
+ outInput1.getBytes());
+ break;
+ case CIRCLE:
+ res = rectangleCircleIntersection(outInput0.getBytes(),
+ outInput1.getBytes());
+ break;
+ case RECTANGLE:
+ triangulateRectangle(outInput0.getBytes(), trianglesX0, trianglesY0);
+ triangulateRectangle(outInput1.getBytes(), trianglesX1, trianglesY1);
+
+ boolean intersect = false;
+ // 2 triangles in a rectangle
+ for (int j = 0; j < 2; j++) {
+ for (int i = 0; i < 2; i++) {
+
+ res = triangleTriangleIntersection(trianglesX1, trianglesY1, i,
+ trianglesX0, trianglesY0, j);
+
+ if (res) {
+ res = triangleTriangleIntersection(trianglesX0, trianglesY0, j,
+ trianglesX1, trianglesY1, i);
+
+ if (res) {
+ intersect = true;
+ break;
+ }
+ }
+ }
+ if (intersect) {
+ break;
+ }
+ }
+ break;
+ default:
+ throw new NotImplementedException(
+ "spatial-intersection does not support the type: "
+ + tag1
+ + " It is only implemented for POINT, ALINE, POLYGON, and CIRCLE.");
+ }
+ break;
+ default:
+ throw new NotImplementedException(
+ "spatial-intersection does not support the type: " + tag0
+ + " It is only implemented for POINT, ALINE, POLYGON, and CIRCLE.");
+ }
+
+ ABoolean aResult = res ? (ABoolean.TRUE) : (ABoolean.FALSE);
+ AObjectSerializerDeserializer.INSTANCE.serialize(aResult, out);
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StartsWithDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StartsWithDescriptor.java
new file mode 100644
index 0000000..2ef49f9
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StartsWithDescriptor.java
@@ -0,0 +1,66 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.util.StringUtils;
+
+public class StartsWithDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "starts-with",
+ 2, true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+ DataOutput dout = output.getDataOutput();
+
+ return new AbstractStringContainsEval(dout, args[0], args[1]) {
+
+ @Override
+ protected boolean findMatch(byte[] strBytes, byte[] patternBytes) {
+ int utflen1 = UTF8StringPointable.getUTFLen(strBytes, 1);
+ int utflen2 = UTF8StringPointable.getUTFLen(patternBytes, 1);
+
+ int s1Start = 3;
+ int s2Start = 3;
+
+ int c1 = 0;
+ int c2 = 0;
+ while (c1 < utflen1 && c2 < utflen2) {
+ char ch1 = UTF8StringPointable.charAt(strBytes, s1Start + c1);
+ char ch2 = UTF8StringPointable.charAt(patternBytes, s2Start + c2);
+ if (ch1 != ch2) {
+ break;
+ }
+ c1 += UTF8StringPointable.charSize(strBytes, s1Start + c1);
+ c2 += UTF8StringPointable.charSize(patternBytes, s2Start + c2);
+ }
+ return (c2 == utflen2);
+ }
+
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SubstringDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SubstringDescriptor.java
new file mode 100644
index 0000000..503df91
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SubstringDescriptor.java
@@ -0,0 +1,95 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class SubstringDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "substring", 3,
+ true);
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new IEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private IEvaluator evalString = args[0].createEvaluator(argOut);
+ private IEvaluator evalStart = args[1].createEvaluator(argOut);
+ private IEvaluator evalLen = args[2].createEvaluator(argOut);
+ private final byte stt = ATypeTag.STRING.serialize();
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+ evalStart.evaluate(tuple);
+ int start = IntegerSerializerDeserializer.getInt(argOut.getBytes(), 1) - 1;
+ argOut.reset();
+ evalLen.evaluate(tuple);
+ int len = IntegerSerializerDeserializer.getInt(argOut.getBytes(), 1);
+ argOut.reset();
+ evalString.evaluate(tuple);
+
+ byte[] bytes = argOut.getBytes();
+ int utflen = UTF8StringPointable.getUTFLen(bytes, 1);
+ int sStart = 3;
+ int c = 0;
+ int idxPos1 = 0;
+ // skip to start
+ while (idxPos1 < start && c < utflen) {
+ c += UTF8StringPointable.charSize(bytes, sStart + c);
+ ++idxPos1;
+ }
+ int startSubstr = c;
+ int idxPos2 = 0;
+ while (idxPos2 < len && c < utflen) {
+ c += UTF8StringPointable.charSize(bytes, sStart + c);
+ ++idxPos2;
+ }
+
+ if (idxPos2 < len) {
+ throw new AlgebricksException("substring: start=" + start + "\tlen=" + len
+ + "\tgoing past the input length=" + (idxPos1 + idxPos2) + ".");
+ }
+
+ int substrByteLen = c - startSubstr;
+ try {
+ out.writeByte(stt);
+ out.writeByte((byte) ((substrByteLen >>> 8) & 0xFF));
+ out.writeByte((byte) ((substrByteLen >>> 0) & 0xFF));
+ out.write(bytes, sStart + startSubstr, substrByteLen);
+
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java
new file mode 100644
index 0000000..ee5b0d4
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java
@@ -0,0 +1,100 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class SwitchCaseDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "switch-case",
+ FunctionIdentifier.VARARGS, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ final ArrayBackedValueStorage condOut = new ArrayBackedValueStorage();
+ final ArrayBackedValueStorage caseOut = new ArrayBackedValueStorage();
+ final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+
+ final IEvaluator[] evals = new IEvaluator[args.length];
+ // condition
+ evals[0] = args[0].createEvaluator(condOut);
+ // case value
+ for (int i = 1; i < evals.length - 1; i += 2) {
+ evals[i] = args[i].createEvaluator(caseOut);
+ }
+ // case expression
+ for (int i = 2; i < evals.length - 1; i += 2) {
+ evals[i] = args[i].createEvaluator(argOut);
+ }
+ // default expression
+ evals[evals.length - 1] = args[evals.length - 1].createEvaluator(argOut);
+
+ return new IEvaluator() {
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ int n = args.length;
+ condOut.reset();
+ evals[0].evaluate(tuple);
+ for (int i = 1; i < n; i += 2) {
+ caseOut.reset();
+ evals[i].evaluate(tuple);
+ if (equals(condOut, caseOut)) {
+ argOut.reset();
+ evals[i + 1].evaluate(tuple);
+ output.getDataOutput().write(argOut.getBytes(), argOut.getStartIndex(),
+ argOut.getLength());
+ return;
+ }
+ }
+ // the default case
+ argOut.reset();
+ evals[n - 1].evaluate(tuple);
+ output.getDataOutput().write(argOut.getBytes(), argOut.getStartIndex(), argOut.getLength());
+ } catch (HyracksDataException hde) {
+ throw new AlgebricksException(hde);
+ } catch (IOException ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+
+ private boolean equals(ArrayBackedValueStorage out1, ArrayBackedValueStorage out2) {
+ if (out1.getStartIndex() != out2.getStartIndex() || out1.getLength() != out2.getLength())
+ return false;
+ byte[] data1 = out1.getBytes();
+ byte[] data2 = out2.getBytes();
+ for (int i = out1.getStartIndex(); i < out1.getLength(); i++) {
+ if (data1[i] != data2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/UnorderedListConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/UnorderedListConstructorDescriptor.java
new file mode 100644
index 0000000..ed26a89
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/UnorderedListConstructorDescriptor.java
@@ -0,0 +1,119 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.builders.UnorderedListBuilder;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnorderedListType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class UnorderedListConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "unordered-list-constructor", FunctionIdentifier.VARARGS, true);
+
+ private AUnorderedListType ultype;
+
+ public void reset(AUnorderedListType unorderedListType) {
+ this.ultype = unorderedListType;
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+ return new UnorderedListConstructorEvaluatorFactory(args, ultype);
+ }
+
+ private static class UnorderedListConstructorEvaluatorFactory implements IEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+ private IEvaluatorFactory[] args;
+
+ private boolean selfDescList = false;
+ private boolean homoList = false;
+ private AUnorderedListType unorderedlistType;
+
+ public UnorderedListConstructorEvaluatorFactory(IEvaluatorFactory[] args, AUnorderedListType type) {
+ this.args = args;
+ this.unorderedlistType = type;
+ if (type == null || type.getItemType() == null || type.getItemType().getTypeTag() == ATypeTag.ANY)
+ this.selfDescList = true;
+ else
+ this.homoList = true;
+ }
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ final DataOutput out = output.getDataOutput();
+ final ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ final IEvaluator[] argEvals = new IEvaluator[args.length];
+ for (int i = 0; i < args.length; i++) {
+ argEvals[i] = args[i].createEvaluator(inputVal);
+ }
+
+ return new IEvaluator() {
+
+ private UnorderedListBuilder builder = new UnorderedListBuilder();
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ builder.reset(unorderedlistType);
+ if (selfDescList) {
+ this.writeUntypedItems(tuple);
+ }
+ if (homoList) {
+ this.writeTypedItems(tuple);
+ }
+ builder.write(out, true);
+ } catch (IOException ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+
+ private void writeUntypedItems(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ for (int i = 0; i < argEvals.length; i++) {
+ inputVal.reset();
+ argEvals[i].evaluate(tuple);
+ builder.addItem(inputVal);
+ }
+ } catch (IOException ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+
+ private void writeTypedItems(IFrameTupleReference tuple) throws AlgebricksException {
+
+ try {
+ for (int i = 0; i < argEvals.length; i++) {
+ inputVal.reset();
+ argEvals[i].evaluate(tuple);
+ builder.addItem(inputVal);
+ }
+ } catch (IOException ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+
+ };
+
+ }
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/WordTokensDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/WordTokensDescriptor.java
new file mode 100644
index 0000000..6b8979e
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/WordTokensDescriptor.java
@@ -0,0 +1,44 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.WordTokensEvaluator;
+import edu.uci.ics.fuzzyjoin.tokenizer.DelimitedUTF8StringBinaryTokenizer;
+import edu.uci.ics.fuzzyjoin.tokenizer.IBinaryTokenizer;
+import edu.uci.ics.fuzzyjoin.tokenizer.ITokenFactory;
+import edu.uci.ics.fuzzyjoin.tokenizer.UTF8WordTokenFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+
+public class WordTokensDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "word-tokens",
+ 1, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) throws AlgebricksException {
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ ITokenFactory tokenFactory = new UTF8WordTokenFactory(ATypeTag.STRING.serialize(),
+ ATypeTag.INT32.serialize());
+ IBinaryTokenizer tokenizer = new DelimitedUTF8StringBinaryTokenizer(true, true, tokenFactory);
+ return new WordTokensEvaluator(args, output, tokenizer, BuiltinType.ASTRING);
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/YearDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/YearDescriptor.java
new file mode 100644
index 0000000..9c8b857
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/YearDescriptor.java
@@ -0,0 +1,97 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.util.StringUtils;
+
+public class YearDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "year", 1, true);
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ /**
+ * Returns the 4-digit representation of a year from a string, as an int32.
+ * e.g. year('2010-10-24') = 2010
+ */
+
+ @Override
+ public IEvaluatorFactory createEvaluatorFactory(final IEvaluatorFactory[] args) {
+
+ return new IEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+ final DataOutput out = output.getDataOutput();
+
+ return new IEvaluator() {
+ private ArrayBackedValueStorage out1 = new ArrayBackedValueStorage();
+ private IEvaluator eval1 = args[0].createEvaluator(out1);
+ private AMutableInt32 m = new AMutableInt32(0);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ out1.reset();
+ eval1.evaluate(tuple);
+ byte[] dateArray = out1.getBytes();
+
+ if (dateArray[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (dateArray[0] != SER_STRING_TYPE_TAG) {
+ throw new AlgebricksException("year function can not be called on values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(dateArray[0]));
+ }
+
+ int year = (UTF8StringPointable.charAt(dateArray, 3) - '0') * 1000
+ + (UTF8StringPointable.charAt(dateArray, 4) - '0') * 100
+ + (UTF8StringPointable.charAt(dateArray, 5) - '0') * 10
+ + (UTF8StringPointable.charAt(dateArray, 6) - '0');
+ m.setValue(year);
+
+ int32Serde.serialize(m, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/FormatUtils.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/FormatUtils.java
new file mode 100644
index 0000000..a24a19a
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/FormatUtils.java
@@ -0,0 +1,9 @@
+package edu.uci.ics.asterix.runtime.formats;
+
+import edu.uci.ics.asterix.formats.base.IDataFormat;
+
+public final class FormatUtils {
+ public static IDataFormat getDefaultFormat() {
+ return NonTaggedDataFormat.INSTANCE;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
new file mode 100644
index 0000000..959a135
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -0,0 +1,675 @@
+package edu.uci.ics.asterix.runtime.formats;
+
+import java.io.DataOutput;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
+import edu.uci.ics.asterix.common.functions.FunctionUtils;
+import edu.uci.ics.asterix.common.parse.IParseFileSplitsDecl;
+import edu.uci.ics.asterix.dataflow.data.nontagged.AqlNullWriterFactory;
+import edu.uci.ics.asterix.formats.base.IDataFormat;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryBooleanInspectorImpl;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryHashFunctionFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlBinaryIntegerInspector;
+import edu.uci.ics.asterix.formats.nontagged.AqlNormalizedKeyComputerFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlPrinterFactoryProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.formats.nontagged.AqlTypeTraitProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.AString;
+import edu.uci.ics.asterix.om.base.IAObject;
+import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.functions.FunctionManagerHolder;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionManager;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.AUnorderedListType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.aggregates.collections.ListifyAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.serializable.std.SerializableAvgAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.serializable.std.SerializableCountAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.serializable.std.SerializableGlobalAvgAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.serializable.std.SerializableLocalAvgAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.serializable.std.SerializableSumAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.std.AvgAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.std.CountAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.std.GlobalAvgAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.std.LocalAvgAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.std.MaxAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.std.MinAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.std.SumAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.aggregates.stream.NonEmptyStreamAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.common.CreateMBREvalFactory;
+import edu.uci.ics.asterix.runtime.evaluators.common.FieldAccessByIndexEvalFactory;
+import edu.uci.ics.asterix.runtime.evaluators.common.FunctionManagerImpl;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ABooleanConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ACircleConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ADateConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ADateTimeConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ADoubleConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ADurationConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.AFloatConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.AInt16ConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.AInt32ConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.AInt64ConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.AInt8ConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ALineConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ANullConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.APoint3DConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.APointConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.APolygonConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ARectangleConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.AStringConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.constructors.ATimeConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.AndDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.AnyCollectionMemberDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.ClosedRecordConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.ContainsDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.CountHashedGramTokensDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.CountHashedWordTokensDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.CreateCircleDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.CreateLineDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.CreateMBRDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.CreatePointDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.CreatePolygonDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.CreateRectangleDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.EditDistanceCheckDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.EditDistanceDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.EmbedTypeDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.EndsWithDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.FieldAccessByIndexDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.FieldAccessByNameDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.FuzzyEqDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.GetItemDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.GramTokensDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.HashedGramTokensDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.HashedWordTokensDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.InjectFailureDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.IsNullDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.LenDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.LikeDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NotDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericAddDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericDivideDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericMultiplyDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericSubtractDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericUnaryMinusDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.OpenRecordConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.OrDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.OrderedListConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.PrefixLenJaccardDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.RegExpDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SimilarityJaccardCheckDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SimilarityJaccardDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SimilarityJaccardPrefixCheckDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SimilarityJaccardPrefixDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SpatialAreaDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SpatialCellDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SpatialDistanceDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SpatialIntersectDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StartsWithDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SubstringDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SwitchCaseDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.UnorderedListConstructorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.WordTokensDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.YearDescriptor;
+import edu.uci.ics.asterix.runtime.operators.file.AdmSchemafullRecordParserFactory;
+import edu.uci.ics.asterix.runtime.operators.file.NtDelimitedDataTupleParserFactory;
+import edu.uci.ics.asterix.runtime.runningaggregates.std.TidRunningAggregateDescriptor;
+import edu.uci.ics.asterix.runtime.unnestingfunctions.std.RangeDescriptor;
+import edu.uci.ics.asterix.runtime.unnestingfunctions.std.ScanCollectionDescriptor;
+import edu.uci.ics.asterix.runtime.unnestingfunctions.std.SubsetCollectionDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryBooleanInspector;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryComparatorFactoryProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryHashFunctionFactoryProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryIntegerInspector;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.INormalizedKeyComputerFactoryProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.IPrinterFactoryProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.ISerializerDeserializerProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.data.ITypeTraitProvider;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IAlgebricksConstantValue;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IExpressionEvalSizeComputer;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableEvalSizeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.evaluators.ColumnAccessEvalFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.evaluators.ConstantEvalFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.algebricks.core.utils.Triple;
+import edu.uci.ics.hyracks.api.dataflow.value.INullWriterFactory;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.DoubleParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.FloatParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IntegerParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.LongParserFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.UTF8StringParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.ITupleParserFactory;
+
+public class NonTaggedDataFormat implements IDataFormat {
+
+ private static boolean registered = false;
+
+ public static final NonTaggedDataFormat INSTANCE = new NonTaggedDataFormat();
+
+ private static LogicalVariable METADATA_DUMMY_VAR = new LogicalVariable(-1);
+
+ private static final HashMap<ATypeTag, IValueParserFactory> typeToValueParserFactMap = new HashMap<ATypeTag, IValueParserFactory>();
+ static {
+ typeToValueParserFactMap.put(ATypeTag.INT32, IntegerParserFactory.INSTANCE);
+ typeToValueParserFactMap.put(ATypeTag.FLOAT, FloatParserFactory.INSTANCE);
+ typeToValueParserFactMap.put(ATypeTag.DOUBLE, DoubleParserFactory.INSTANCE);
+ typeToValueParserFactMap.put(ATypeTag.INT64, LongParserFactory.INSTANCE);
+ typeToValueParserFactMap.put(ATypeTag.STRING, UTF8StringParserFactory.INSTANCE);
+ }
+
+ public NonTaggedDataFormat() {
+ }
+
+ public void registerRuntimeFunctions() throws AlgebricksException {
+
+ if (registered) {
+ return;
+ }
+ registered = true;
+
+ if (FunctionManagerHolder.getFunctionManager() != null) {
+ return;
+ }
+
+ List<IFunctionDescriptor> temp = new ArrayList<IFunctionDescriptor>();
+
+ // format-independent
+ temp.add(new ContainsDescriptor());
+ temp.add(new EndsWithDescriptor());
+ temp.add(new StartsWithDescriptor());
+ temp.add(new SubstringDescriptor());
+ temp.add(new TidRunningAggregateDescriptor());
+
+ // format-dependent
+ temp.add(new AndDescriptor());
+ temp.add(new OrDescriptor());
+ temp.add(new LikeDescriptor());
+ temp.add(new YearDescriptor());
+ temp.add(new ScanCollectionDescriptor());
+ temp.add(new AnyCollectionMemberDescriptor());
+ temp.add(new ClosedRecordConstructorDescriptor());
+ temp.add(new FieldAccessByIndexDescriptor());
+ temp.add(new FieldAccessByNameDescriptor());
+ temp.add(new GetItemDescriptor());
+ temp.add(new NumericUnaryMinusDescriptor());
+ temp.add(new OpenRecordConstructorDescriptor());
+ temp.add(new OrderedListConstructorDescriptor());
+ temp.add(new UnorderedListConstructorDescriptor());
+ temp.add(new EmbedTypeDescriptor());
+
+ temp.add(new NumericAddDescriptor());
+ temp.add(new NumericDivideDescriptor());
+ temp.add(new NumericMultiplyDescriptor());
+ temp.add(new NumericSubtractDescriptor());
+ temp.add(new IsNullDescriptor());
+ temp.add(new NotDescriptor());
+ temp.add(new LenDescriptor());
+ temp.add(new NonEmptyStreamAggregateDescriptor());
+ temp.add(new RangeDescriptor());
+
+ // aggregates
+ temp.add(new ListifyAggregateDescriptor());
+ temp.add(new CountAggregateDescriptor());
+ temp.add(new AvgAggregateDescriptor());
+ temp.add(new LocalAvgAggregateDescriptor());
+ temp.add(new GlobalAvgAggregateDescriptor());
+ temp.add(new SumAggregateDescriptor());
+ temp.add(new MaxAggregateDescriptor());
+ temp.add(new MinAggregateDescriptor());
+
+ // serializable aggregates
+ temp.add(new SerializableCountAggregateDescriptor());
+ temp.add(new SerializableAvgAggregateDescriptor());
+ temp.add(new SerializableLocalAvgAggregateDescriptor());
+ temp.add(new SerializableGlobalAvgAggregateDescriptor());
+ temp.add(new SerializableSumAggregateDescriptor());
+
+ // new functions - constructors
+ temp.add(new ABooleanConstructorDescriptor());
+ temp.add(new ANullConstructorDescriptor());
+ temp.add(new AStringConstructorDescriptor());
+ temp.add(new AInt8ConstructorDescriptor());
+ temp.add(new AInt16ConstructorDescriptor());
+ temp.add(new AInt32ConstructorDescriptor());
+ temp.add(new AInt64ConstructorDescriptor());
+ temp.add(new AFloatConstructorDescriptor());
+ temp.add(new ADoubleConstructorDescriptor());
+ temp.add(new APointConstructorDescriptor());
+ temp.add(new APoint3DConstructorDescriptor());
+ temp.add(new ALineConstructorDescriptor());
+ temp.add(new APolygonConstructorDescriptor());
+ temp.add(new ACircleConstructorDescriptor());
+ temp.add(new ARectangleConstructorDescriptor());
+ temp.add(new ATimeConstructorDescriptor());
+ temp.add(new ADateConstructorDescriptor());
+ temp.add(new ADateTimeConstructorDescriptor());
+ temp.add(new ADurationConstructorDescriptor());
+
+ // Spatial
+ temp.add(new CreatePointDescriptor());
+ temp.add(new CreateLineDescriptor());
+ temp.add(new CreatePolygonDescriptor());
+ temp.add(new CreateCircleDescriptor());
+ temp.add(new CreateRectangleDescriptor());
+ temp.add(new SpatialAreaDescriptor());
+ temp.add(new SpatialDistanceDescriptor());
+ temp.add(new SpatialIntersectDescriptor());
+ temp.add(new CreateMBRDescriptor());
+ temp.add(new SpatialCellDescriptor());
+
+ // fuzzyjoin function
+ temp.add(new FuzzyEqDescriptor());
+ temp.add(new SubsetCollectionDescriptor());
+ temp.add(new PrefixLenJaccardDescriptor());
+
+ temp.add(new WordTokensDescriptor());
+ temp.add(new HashedWordTokensDescriptor());
+ temp.add(new CountHashedWordTokensDescriptor());
+
+ temp.add(new GramTokensDescriptor());
+ temp.add(new HashedGramTokensDescriptor());
+ temp.add(new CountHashedGramTokensDescriptor());
+
+ temp.add(new EditDistanceDescriptor());
+ temp.add(new EditDistanceCheckDescriptor());
+
+ temp.add(new SimilarityJaccardDescriptor());
+ temp.add(new SimilarityJaccardCheckDescriptor());
+ temp.add(new SimilarityJaccardPrefixDescriptor());
+ temp.add(new SimilarityJaccardPrefixCheckDescriptor());
+
+ temp.add(new SwitchCaseDescriptor());
+ temp.add(new RegExpDescriptor());
+ temp.add(new InjectFailureDescriptor());
+
+ IFunctionManager mgr = new FunctionManagerImpl();
+ for (IFunctionDescriptor fd : temp) {
+ mgr.registerFunction(fd);
+ }
+ FunctionManagerHolder.setFunctionManager(mgr);
+ }
+
+ @Override
+ public IBinaryBooleanInspector getBinaryBooleanInspector() {
+ return AqlBinaryBooleanInspectorImpl.INSTANCE;
+ }
+
+ @Override
+ public IBinaryComparatorFactoryProvider getBinaryComparatorFactoryProvider() {
+ return AqlBinaryComparatorFactoryProvider.INSTANCE;
+ }
+
+ @Override
+ public IBinaryHashFunctionFactoryProvider getBinaryHashFunctionFactoryProvider() {
+ return AqlBinaryHashFunctionFactoryProvider.INSTANCE;
+ }
+
+ @Override
+ public ISerializerDeserializerProvider getSerdeProvider() {
+ return AqlSerializerDeserializerProvider.INSTANCE; // done
+ }
+
+ @Override
+ public ITypeTraitProvider getTypeTraitProvider() {
+ return AqlTypeTraitProvider.INSTANCE;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public IEvaluatorFactory getFieldAccessEvaluatorFactory(ARecordType recType, String fldName, int recordColumn)
+ throws AlgebricksException {
+ String[] names = recType.getFieldNames();
+ int n = names.length;
+ for (int i = 0; i < n; i++) {
+ if (names[i].equals(fldName)) {
+ IEvaluatorFactory recordEvalFactory = new ColumnAccessEvalFactory(recordColumn);
+ ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
+ DataOutput dos = abvs.getDataOutput();
+ try {
+ AInt32 ai = new AInt32(i);
+ AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(ai.getType()).serialize(ai,
+ dos);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ IEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs.getBytes(),
+ abvs.getLength()));
+ IEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory,
+ fldIndexEvalFactory, recType);
+ return evalFactory;
+ }
+ }
+ throw new AlgebricksException("Could not find field " + fldName + " in the schema.");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public IEvaluatorFactory[] createMBRFactory(ARecordType recType, String fldName, int recordColumn, int dimension)
+ throws AlgebricksException {
+ IEvaluatorFactory evalFactory = getFieldAccessEvaluatorFactory(recType, fldName, recordColumn);
+ int numOfFields = dimension * 2;
+ IEvaluatorFactory[] evalFactories = new IEvaluatorFactory[numOfFields];
+
+ ArrayBackedValueStorage abvs1 = new ArrayBackedValueStorage();
+ DataOutput dos1 = abvs1.getDataOutput();
+ try {
+ AInt32 ai = new AInt32(dimension);
+ AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(ai.getType()).serialize(ai, dos1);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ IEvaluatorFactory dimensionEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs1.getBytes(),
+ abvs1.getLength()));
+
+ for (int i = 0; i < numOfFields; i++) {
+ ArrayBackedValueStorage abvs2 = new ArrayBackedValueStorage();
+ DataOutput dos2 = abvs2.getDataOutput();
+ try {
+ AInt32 ai = new AInt32(i);
+ AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(ai.getType()).serialize(ai, dos2);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ IEvaluatorFactory coordinateEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs2.getBytes(),
+ abvs2.getLength()));
+
+ evalFactories[i] = new CreateMBREvalFactory(evalFactory, dimensionEvalFactory, coordinateEvalFactory);
+ }
+ return evalFactories;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Triple<IEvaluatorFactory, ScalarFunctionCallExpression, IAType> partitioningEvaluatorFactory(
+ ARecordType recType, String fldName) throws AlgebricksException {
+ String[] names = recType.getFieldNames();
+ int n = names.length;
+ for (int i = 0; i < n; i++) {
+ if (names[i].equals(fldName)) {
+ IEvaluatorFactory recordEvalFactory = new ColumnAccessEvalFactory(
+ GlobalConfig.DEFAULT_INPUT_DATA_COLUMN);
+ ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
+ DataOutput dos = abvs.getDataOutput();
+ try {
+ AInt32 ai = new AInt32(i);
+ AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(ai.getType()).serialize(ai,
+ dos);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ IEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs.getBytes(),
+ abvs.getLength()));
+ IEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory,
+ fldIndexEvalFactory, recType);
+ IFunctionInfo finfoAccess = FunctionUtils
+ .getFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX);
+ ScalarFunctionCallExpression partitionFun = new ScalarFunctionCallExpression(finfoAccess,
+ new MutableObject<ILogicalExpression>(new VariableReferenceExpression(METADATA_DUMMY_VAR)),
+ new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AInt32(i)))));
+ return new Triple<IEvaluatorFactory, ScalarFunctionCallExpression, IAType>(evalFactory, partitionFun,
+ recType.getFieldTypes()[i]);
+ }
+ }
+ throw new AlgebricksException("Could not find field " + fldName + " in the schema.");
+ }
+
+ @Override
+ public IFunctionDescriptor resolveFunction(ILogicalExpression expr, IVariableTypeEnvironment context)
+ throws AlgebricksException {
+ FunctionIdentifier fnId = ((AbstractFunctionCallExpression) expr).getFunctionIdentifier();
+ IFunctionManager mgr = FunctionManagerHolder.getFunctionManager();
+ IFunctionDescriptor fd = mgr.lookupFunction(fnId);
+ if (fd == null) {
+ throw new AsterixRuntimeException("Unresolved function " + fnId);
+ }
+ typeInference(expr, fd, context);
+ return fd;
+ }
+
+ private void typeInference(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context)
+ throws AlgebricksException {
+ if (fd.getIdentifier().equals(AsterixBuiltinFunctions.LISTIFY)) {
+ AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expr;
+ if (f.getArguments().size() == 0) {
+ ((ListifyAggregateDescriptor) fd).reset(new AOrderedListType(null, null));
+ } else {
+ IAType itemType = (IAType) context.getType(f.getArguments().get(0).getValue());
+ ((ListifyAggregateDescriptor) fd).reset(new AOrderedListType(itemType, null));
+ }
+ }
+ if (fd.getIdentifier().equals(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR)) {
+ ARecordType rt = (ARecordType) context.getType(expr);
+ ((OpenRecordConstructorDescriptor) fd).reset(rt,
+ computeOpenFields((AbstractFunctionCallExpression) expr, rt));
+ }
+ if (fd.getIdentifier().equals(AsterixBuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR)) {
+ ((ClosedRecordConstructorDescriptor) fd).reset((ARecordType) context.getType(expr));
+ }
+ if (fd.getIdentifier().equals(AsterixBuiltinFunctions.ORDERED_LIST_CONSTRUCTOR)) {
+ ((OrderedListConstructorDescriptor) fd).reset((AOrderedListType) context.getType(expr));
+ }
+ if (fd.getIdentifier().equals(AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR)) {
+ ((UnorderedListConstructorDescriptor) fd).reset((AUnorderedListType) context.getType(expr));
+ }
+ if (fd.getIdentifier().equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX)) {
+ AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr;
+ IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue());
+ switch (t.getTypeTag()) {
+ case RECORD: {
+ ARecordType recType = (ARecordType) t;
+ ((FieldAccessByIndexDescriptor) fd).reset(recType);
+ break;
+ }
+ case UNION: {
+ AUnionType unionT = (AUnionType) t;
+ if (unionT.isNullableType()) {
+ IAType t2 = unionT.getUnionList().get(1);
+ if (t2.getTypeTag() == ATypeTag.RECORD) {
+ ARecordType recType = (ARecordType) t2;
+ ((FieldAccessByIndexDescriptor) fd).reset(recType);
+ break;
+ }
+ }
+ throw new NotImplementedException("field-access-by-index for data of type " + t);
+ }
+ default: {
+ throw new NotImplementedException("field-access-by-index for data of type " + t);
+ }
+ }
+ }
+ }
+
+ private boolean[] computeOpenFields(AbstractFunctionCallExpression expr, ARecordType recType) {
+ int n = expr.getArguments().size() / 2;
+ boolean[] open = new boolean[n];
+ for (int i = 0; i < n; i++) {
+ Mutable<ILogicalExpression> argRef = expr.getArguments().get(2 * i);
+ ILogicalExpression arg = argRef.getValue();
+ if (arg.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
+ String fn = ((AString) ((AsterixConstantValue) ((ConstantExpression) arg).getValue()).getObject())
+ .getStringValue();
+ open[i] = true;
+ for (String s : recType.getFieldNames()) {
+ if (s.equals(fn)) {
+ open[i] = false;
+ break;
+ }
+ }
+ } else {
+ open[i] = true;
+ }
+ }
+ return open;
+ }
+
+ @Override
+ public IPrinterFactoryProvider getPrinterFactoryProvider() {
+ return AqlPrinterFactoryProvider.INSTANCE;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public IEvaluatorFactory getConstantEvalFactory(IAlgebricksConstantValue value) throws AlgebricksException {
+ IAObject obj = null;
+ if (value.isNull()) {
+ obj = ANull.NULL;
+ } else if (value.isTrue()) {
+ obj = ABoolean.TRUE;
+ } else if (value.isFalse()) {
+ obj = ABoolean.FALSE;
+ } else {
+ AsterixConstantValue acv = (AsterixConstantValue) value;
+ obj = acv.getObject();
+ }
+ ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
+ DataOutput dos = abvs.getDataOutput();
+ try {
+ AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(obj.getType()).serialize(obj, dos);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ return new ConstantEvalFactory(Arrays.copyOf(abvs.getBytes(), abvs.getLength()));
+ }
+
+ @Override
+ public IBinaryIntegerInspector getBinaryIntegerInspector() {
+ return AqlBinaryIntegerInspector.INSTANCE;
+ }
+
+ @Override
+ public ITupleParserFactory createTupleParser(ARecordType recType, IParseFileSplitsDecl decl) {
+ if (decl.isDelimitedFileFormat()) {
+ int n = recType.getFieldTypes().length;
+ IValueParserFactory[] fieldParserFactories = new IValueParserFactory[n];
+ for (int i = 0; i < n; i++) {
+ ATypeTag tag = recType.getFieldTypes()[i].getTypeTag();
+ IValueParserFactory vpf = typeToValueParserFactMap.get(tag);
+ if (vpf == null) {
+ throw new NotImplementedException("No value parser factory for delimited fields of type " + tag);
+ }
+ fieldParserFactories[i] = vpf;
+ }
+ return new NtDelimitedDataTupleParserFactory(recType, fieldParserFactories, decl.getDelimChar());
+ } else {
+ return new AdmSchemafullRecordParserFactory(recType);
+ }
+ }
+
+ @Override
+ public ITupleParserFactory createTupleParser(ARecordType recType, boolean delimitedFormat, Character delimiter) {
+ if (delimitedFormat) {
+ int n = recType.getFieldTypes().length;
+ IValueParserFactory[] fieldParserFactories = new IValueParserFactory[n];
+ for (int i = 0; i < n; i++) {
+ ATypeTag tag = recType.getFieldTypes()[i].getTypeTag();
+ IValueParserFactory vpf = typeToValueParserFactMap.get(tag);
+ if (vpf == null) {
+ throw new NotImplementedException("No value parser factory for delimited fields of type " + tag);
+ }
+ fieldParserFactories[i] = vpf;
+ }
+ return new NtDelimitedDataTupleParserFactory(recType, fieldParserFactories, delimiter);
+ } else {
+ return new AdmSchemafullRecordParserFactory(recType);
+ }
+ }
+
+ @Override
+ public INullWriterFactory getNullWriterFactory() {
+ return AqlNullWriterFactory.INSTANCE;
+ }
+
+ @Override
+ public IExpressionEvalSizeComputer getExpressionEvalSizeComputer() {
+ return new IExpressionEvalSizeComputer() {
+ @Override
+ public int getEvalSize(ILogicalExpression expr, IVariableEvalSizeEnvironment env)
+ throws AlgebricksException {
+ switch (expr.getExpressionTag()) {
+ case CONSTANT: {
+ ConstantExpression c = (ConstantExpression) expr;
+ if (c == ConstantExpression.NULL) {
+ return 1;
+ } else if (c == ConstantExpression.FALSE || c == ConstantExpression.TRUE) {
+ return 2;
+ } else {
+ AsterixConstantValue acv = (AsterixConstantValue) c.getValue();
+ IAObject o = acv.getObject();
+ switch (o.getType().getTypeTag()) {
+ case DOUBLE: {
+ return 9;
+ }
+ case BOOLEAN: {
+ return 2;
+ }
+ case NULL: {
+ return 1;
+ }
+ case INT32: {
+ return 5;
+ }
+ case INT64: {
+ return 9;
+ }
+ default: {
+ // TODO
+ return -1;
+ }
+ }
+ }
+ }
+ case FUNCTION_CALL: {
+ AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expr;
+ if (f.getFunctionIdentifier().equals(AsterixBuiltinFunctions.TID)) {
+ return 5;
+ } else {
+ // TODO
+ return -1;
+ }
+ }
+ default: {
+ // TODO
+ return -1;
+ }
+ }
+ }
+ };
+ }
+
+ @Override
+ public INormalizedKeyComputerFactoryProvider getNormalizedKeyComputerFactoryProvider() {
+ return AqlNormalizedKeyComputerFactoryProvider.INSTANCE;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/job/listener/JobEventListenerFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/job/listener/JobEventListenerFactory.java
new file mode 100644
index 0000000..0a1faac
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/job/listener/JobEventListenerFactory.java
@@ -0,0 +1,50 @@
+package edu.uci.ics.asterix.runtime.job.listener;
+
+import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
+import edu.uci.ics.asterix.transaction.management.service.transaction.ITransactionManager;
+import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionContext;
+import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionProvider;
+import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionContext.TransactionType;
+import edu.uci.ics.hyracks.api.context.IHyracksJobletContext;
+import edu.uci.ics.hyracks.api.job.IJobletEventListener;
+import edu.uci.ics.hyracks.api.job.IJobletEventListenerFactory;
+import edu.uci.ics.hyracks.api.job.JobStatus;
+
+public class JobEventListenerFactory implements IJobletEventListenerFactory {
+
+ private static final long serialVersionUID = 1L;
+ private final long txnId;
+ private final boolean transactionalWrite;
+
+ public JobEventListenerFactory(long txnId, boolean transactionalWrite) {
+ this.txnId = txnId;
+ this.transactionalWrite = transactionalWrite;
+ }
+
+ @Override
+ public IJobletEventListener createListener(final IHyracksJobletContext jobletContext) {
+
+ return new IJobletEventListener() {
+ @Override
+ public void jobletFinish(JobStatus jobStatus) {
+ try {
+ TransactionProvider factory = (TransactionProvider) (jobletContext.getApplicationContext()
+ .getApplicationObject());
+ ITransactionManager txnManager = factory.getTransactionManager();
+ TransactionContext txnContext = txnManager.getTransactionContext(txnId);
+ txnContext.setTransactionType(transactionalWrite ? TransactionType.READ_WRITE
+ : TransactionType.READ);
+ txnManager.completedTransaction(txnContext, !(jobStatus == JobStatus.FAILURE));
+ } catch (ACIDException e) {
+ throw new Error(e);
+ }
+ }
+
+ @Override
+ public void jobletStart() {
+
+ }
+
+ };
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/AbstractTupleParser.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/AbstractTupleParser.java
new file mode 100644
index 0000000..6e83689
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/AbstractTupleParser.java
@@ -0,0 +1,72 @@
+package edu.uci.ics.asterix.runtime.operators.file;
+
+import java.io.InputStream;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AFloat;
+import edu.uci.ics.asterix.om.base.AInt16;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AInt64;
+import edu.uci.ics.asterix.om.base.AInt8;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.AMutableString;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.AString;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.hyracks.api.comm.IFrameWriter;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.std.file.ITupleParser;
+
+public abstract class AbstractTupleParser implements ITupleParser {
+
+ // Mutable Types..
+ protected AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ protected AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ protected AMutableInt32 aInt32 = new AMutableInt32(0);
+ protected AMutableInt64 aInt64 = new AMutableInt64(0);
+ protected AMutableDouble aDouble = new AMutableDouble(0);
+ protected AMutableFloat aFloat = new AMutableFloat(0);
+ protected AMutableString aString = new AMutableString("");
+ protected AMutableString aStringFieldName = new AMutableString("");
+
+ // Serializers
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ASTRING);
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<AFloat> floatSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<AInt8> int8Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<AInt16> int16Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<AInt64> int64Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ protected ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+
+ @Override
+ public abstract void parse(InputStream in, IFrameWriter writer) throws HyracksDataException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/AdmSchemafullRecordParserFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/AdmSchemafullRecordParserFactory.java
new file mode 100644
index 0000000..46d1ba3
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/AdmSchemafullRecordParserFactory.java
@@ -0,0 +1,1007 @@
+package edu.uci.ics.asterix.runtime.operators.file;
+
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
+import java.util.BitSet;
+import java.util.List;
+import java.util.Queue;
+
+import edu.uci.ics.asterix.adm.parser.nontagged.AdmLexer;
+import edu.uci.ics.asterix.adm.parser.nontagged.AdmLexerConstants;
+import edu.uci.ics.asterix.adm.parser.nontagged.ParseException;
+import edu.uci.ics.asterix.adm.parser.nontagged.Token;
+import edu.uci.ics.asterix.builders.IAOrderedListBuilder;
+import edu.uci.ics.asterix.builders.IARecordBuilder;
+import edu.uci.ics.asterix.builders.IAUnorderedListBuilder;
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.builders.RecordBuilder;
+import edu.uci.ics.asterix.builders.UnorderedListBuilder;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ACircleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ALineSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APoint3DSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APolygonSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARectangleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ADouble;
+import edu.uci.ics.asterix.om.base.AFloat;
+import edu.uci.ics.asterix.om.base.AInt16;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AInt64;
+import edu.uci.ics.asterix.om.base.AInt8;
+import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableFloat;
+import edu.uci.ics.asterix.om.base.AMutableInt16;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt64;
+import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.AMutableString;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.AString;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.AUnorderedListType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.hyracks.api.comm.IFrameWriter;
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender;
+import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.std.file.ITupleParser;
+import edu.uci.ics.hyracks.dataflow.std.file.ITupleParserFactory;
+
+public class AdmSchemafullRecordParserFactory implements ITupleParserFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ protected ARecordType recType;
+
+ public AdmSchemafullRecordParserFactory(ARecordType recType) {
+ this.recType = recType;
+ }
+
+ @Override
+ public ITupleParser createTupleParser(final IHyracksTaskContext ctx) {
+ return new ITupleParser() {
+ private AdmLexer admLexer;
+ private ArrayTupleBuilder tb = new ArrayTupleBuilder(1);
+ private DataOutput dos = tb.getDataOutput();
+ private FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+ private ByteBuffer frame = ctx.allocateFrame();
+
+ private int nullableFieldId = 0;
+
+ private Queue<ArrayBackedValueStorage> baaosPool = new ArrayDeque<ArrayBackedValueStorage>();
+ private Queue<IARecordBuilder> recordBuilderPool = new ArrayDeque<IARecordBuilder>();
+ private Queue<IAOrderedListBuilder> orderedListBuilderPool = new ArrayDeque<IAOrderedListBuilder>();
+ private Queue<IAUnorderedListBuilder> unorderedListBuilderPool = new ArrayDeque<IAUnorderedListBuilder>();
+
+ private String mismatchErrorMessage = "Mismatch Type, expecting a value of type ";
+
+ // Mutable Types..
+ private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+ private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private AMutableInt64 aInt64 = new AMutableInt64(0);
+ private AMutableDouble aDouble = new AMutableDouble(0);
+ private AMutableFloat aFloat = new AMutableFloat(0);
+ private AMutableString aString = new AMutableString("");
+ private AMutableString aStringFieldName = new AMutableString("");
+
+ // Serializers
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADouble> doubleSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADOUBLE);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ASTRING);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AFloat> floatSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AFLOAT);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt8> int8Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT8);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt16> int16Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT16);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt64> int64Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT64);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void parse(InputStream in, IFrameWriter writer) throws HyracksDataException {
+ admLexer = new AdmLexer(in);
+ appender.reset(frame, true);
+ int tupleNum = 0;
+ try {
+ while (true) {
+ tb.reset();
+ if (!parseAdmInstance(recType, true, dos)) {
+ break;
+ }
+ tb.addFieldEndOffset();
+ if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
+ FrameUtils.flushFrame(frame, writer);
+ appender.reset(frame, true);
+ if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
+ throw new IllegalStateException();
+ }
+ }
+ tupleNum++;
+ }
+ if (appender.getTupleCount() > 0) {
+ FrameUtils.flushFrame(frame, writer);
+ }
+ } catch (AsterixException ae) {
+ throw new HyracksDataException(ae);
+ } catch (IOException ioe) {
+ throw new HyracksDataException(ioe);
+ }
+ }
+
+ private boolean parseAdmInstance(IAType objectType, Boolean datasetRec, DataOutput out)
+ throws AsterixException, IOException {
+ Token token;
+ try {
+ token = admLexer.next();
+ } catch (ParseException pe) {
+ throw new AsterixException(pe);
+ }
+ if (token.kind == AdmLexerConstants.EOF) {
+ return false;
+ } else {
+ admFromLexerStream(token, objectType, out, datasetRec);
+ return true;
+ }
+ }
+
+ private void admFromLexerStream(Token token, IAType objectType, DataOutput out, Boolean datasetRec)
+ throws AsterixException, IOException {
+
+ switch (token.kind) {
+ case AdmLexerConstants.NULL_LITERAL: {
+ if (checkType(ATypeTag.NULL, objectType, out)) {
+ nullSerde.serialize(ANull.NULL, out);
+ } else
+ throw new AsterixException(" This field can not be null ");
+ break;
+ }
+ case AdmLexerConstants.TRUE_LITERAL: {
+ if (checkType(ATypeTag.BOOLEAN, objectType, out)) {
+ booleanSerde.serialize(ABoolean.TRUE, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.BOOLEAN_CONS: {
+ parseConstructor(ATypeTag.BOOLEAN, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.FALSE_LITERAL: {
+ if (checkType(ATypeTag.BOOLEAN, objectType, out)) {
+ booleanSerde.serialize(ABoolean.FALSE, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.DOUBLE_LITERAL: {
+ if (checkType(ATypeTag.DOUBLE, objectType, out)) {
+ aDouble.setValue(Double.parseDouble(token.image));
+ doubleSerde.serialize(aDouble, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.DOUBLE_CONS: {
+ parseConstructor(ATypeTag.DOUBLE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.FLOAT_LITERAL: {
+ if (checkType(ATypeTag.FLOAT, objectType, out)) {
+ aFloat.setValue(Float.parseFloat(token.image));
+ floatSerde.serialize(aFloat, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.FLOAT_CONS: {
+ parseConstructor(ATypeTag.FLOAT, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.INT8_LITERAL: {
+ if (checkType(ATypeTag.INT8, objectType, out)) {
+ parseInt8(token.image, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.INT8_CONS: {
+ parseConstructor(ATypeTag.INT8, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.INT16_LITERAL: {
+ if (checkType(ATypeTag.INT16, objectType, out)) {
+ parseInt16(token.image, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.INT16_CONS: {
+ parseConstructor(ATypeTag.INT16, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.INT_LITERAL:
+ case AdmLexerConstants.INT32_LITERAL: {
+ if (checkType(ATypeTag.INT32, objectType, out)) {
+ parseInt32(token.image, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.INT32_CONS: {
+ parseConstructor(ATypeTag.INT32, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.INT64_LITERAL: {
+ if (checkType(ATypeTag.INT64, objectType, out)) {
+ parseInt64(token.image, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.INT64_CONS: {
+ parseConstructor(ATypeTag.INT64, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.STRING_LITERAL: {
+ if (checkType(ATypeTag.STRING, objectType, out)) {
+ aString.setValue(token.image.substring(1, token.image.length() - 1));
+ stringSerde.serialize(aString, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.STRING_CONS: {
+ parseConstructor(ATypeTag.STRING, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.DATE_CONS: {
+ parseConstructor(ATypeTag.DATE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.TIME_CONS: {
+ parseConstructor(ATypeTag.TIME, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.DATETIME_CONS: {
+ parseConstructor(ATypeTag.DATETIME, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.DURATION_CONS: {
+ parseConstructor(ATypeTag.DURATION, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.POINT_CONS: {
+ parseConstructor(ATypeTag.POINT, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.POINT3D_CONS: {
+ parseConstructor(ATypeTag.POINT3D, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.CIRCLE_CONS: {
+ parseConstructor(ATypeTag.CIRCLE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.RECTANGLE_CONS: {
+ parseConstructor(ATypeTag.RECTANGLE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.LINE_CONS: {
+ parseConstructor(ATypeTag.LINE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.POLYGON_CONS: {
+ parseConstructor(ATypeTag.POLYGON, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.START_UNORDERED_LIST: {
+ if (checkType(ATypeTag.UNORDEREDLIST, objectType, out)) {
+ objectType = getComplexType(objectType, ATypeTag.UNORDEREDLIST);
+ parseUnorderedList((AUnorderedListType) objectType, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeTag());
+ break;
+ }
+
+ case AdmLexerConstants.START_ORDERED_LIST: {
+ if (checkType(ATypeTag.ORDEREDLIST, objectType, out)) {
+ objectType = getComplexType(objectType, ATypeTag.ORDEREDLIST);
+ parseOrderedList((AOrderedListType) objectType, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeTag());
+ break;
+ }
+ case AdmLexerConstants.START_RECORD: {
+ if (checkType(ATypeTag.RECORD, objectType, out)) {
+ objectType = getComplexType(objectType, ATypeTag.RECORD);
+ parseRecord((ARecordType) objectType, out, datasetRec);
+ } else
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeTag());
+ break;
+ }
+ case AdmLexerConstants.EOF: {
+ break;
+ }
+ default: {
+ throw new AsterixException("Unexpected ADM token kind: "
+ + admLexer.tokenKindToString(token.kind) + ".");
+ }
+ }
+ }
+
+ private void parseConstructor(ATypeTag typeTag, IAType objectType, DataOutput out) throws AsterixException {
+ try {
+ Token token = admLexer.next();
+ if (token.kind == AdmLexerConstants.CONSTRUCTOR_OPEN) {
+ if (checkType(typeTag, objectType, out)) {
+ token = admLexer.next();
+ if (token.kind == AdmLexerConstants.STRING_LITERAL) {
+ switch (typeTag) {
+ case BOOLEAN:
+ parseBoolean(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case INT8:
+ parseInt8(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case INT16:
+ parseInt16(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case INT32:
+ parseInt32(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case INT64:
+ parseInt64(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case FLOAT:
+ aFloat.setValue(Float.parseFloat(token.image.substring(1,
+ token.image.length() - 1)));
+ floatSerde.serialize(aFloat, out);
+ break;
+ case DOUBLE:
+ aDouble.setValue(Double.parseDouble(token.image.substring(1,
+ token.image.length() - 1)));
+ doubleSerde.serialize(aDouble, out);
+ break;
+ case STRING:
+ aString.setValue(token.image.substring(1, token.image.length() - 1));
+ stringSerde.serialize(aString, out);
+ break;
+ case TIME:
+ parseTime(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case DATE:
+ parseDate(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case DATETIME:
+ parseDatetime(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case DURATION:
+ parseDuration(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case POINT:
+ parsePoint(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case POINT3D:
+ parsePoint3d(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case CIRCLE:
+ parseCircle(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case RECTANGLE:
+ parseRectangle(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case LINE:
+ parseLine(token.image.substring(1, token.image.length() - 1), out);
+ break;
+ case POLYGON:
+ parsePolygon(token.image.substring(1, token.image.length() - 1), out);
+ break;
+
+ }
+ token = admLexer.next();
+ if (token.kind == AdmLexerConstants.CONSTRUCTOR_CLOSE)
+ return;
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new AsterixException(e);
+ }
+ throw new AsterixException(mismatchErrorMessage + objectType.getTypeName());
+ }
+
+ private void parseBoolean(String bool, DataOutput out) throws AsterixException {
+ String errorMessage = "This can not be an instance of boolean";
+ try {
+ if (bool.equals("true"))
+ booleanSerde.serialize(ABoolean.TRUE, out);
+ else if (bool.equals("false"))
+ booleanSerde.serialize(ABoolean.FALSE, out);
+ else
+ throw new AsterixException(errorMessage);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parseInt8(String int8, DataOutput out) throws AsterixException {
+ String errorMessage = "This can not be an instance of int8";
+ try {
+ boolean positive = true;
+ byte value = 0;
+ int offset = 0;
+
+ if (int8.charAt(offset) == '+')
+ offset++;
+ else if (int8.charAt(offset) == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < int8.length(); offset++) {
+ if (int8.charAt(offset) >= '0' && int8.charAt(offset) <= '9')
+ value = (byte) (value * 10 + int8.charAt(offset) - '0');
+ else if (int8.charAt(offset) == 'i' && int8.charAt(offset + 1) == '8'
+ && offset + 2 == int8.length())
+ break;
+ else
+ throw new AsterixException(errorMessage);
+ }
+ if (value < 0)
+ throw new AsterixException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+ aInt8.setValue(value);
+ int8Serde.serialize(aInt8, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parseInt16(String int16, DataOutput out) throws AsterixException {
+ String errorMessage = "This can not be an instance of int16";
+ try {
+ boolean positive = true;
+ short value = 0;
+ int offset = 0;
+
+ if (int16.charAt(offset) == '+')
+ offset++;
+ else if (int16.charAt(offset) == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < int16.length(); offset++) {
+ if (int16.charAt(offset) >= '0' && int16.charAt(offset) <= '9')
+ value = (short) (value * 10 + int16.charAt(offset) - '0');
+ else if (int16.charAt(offset) == 'i' && int16.charAt(offset + 1) == '1'
+ && int16.charAt(offset + 2) == '6' && offset + 3 == int16.length())
+ break;
+ else
+ throw new AsterixException(errorMessage);
+ }
+ if (value < 0)
+ throw new AsterixException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+ aInt16.setValue(value);
+ int16Serde.serialize(aInt16, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parseInt32(String int32, DataOutput out) throws AsterixException {
+
+ String errorMessage = "This can not be an instance of int32";
+ try {
+ boolean positive = true;
+ int value = 0;
+ int offset = 0;
+
+ if (int32.charAt(offset) == '+')
+ offset++;
+ else if (int32.charAt(offset) == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < int32.length(); offset++) {
+ if (int32.charAt(offset) >= '0' && int32.charAt(offset) <= '9')
+ value = (value * 10 + int32.charAt(offset) - '0');
+ else if (int32.charAt(offset) == 'i' && int32.charAt(offset + 1) == '3'
+ && int32.charAt(offset + 2) == '2' && offset + 3 == int32.length())
+ break;
+ else
+ throw new AsterixException(errorMessage);
+ }
+ if (value < 0)
+ throw new AsterixException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+
+ aInt32.setValue(value);
+ int32Serde.serialize(aInt32, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parseInt64(String int64, DataOutput out) throws AsterixException {
+ String errorMessage = "This can not be an instance of int64";
+ try {
+ boolean positive = true;
+ long value = 0;
+ int offset = 0;
+
+ if (int64.charAt(offset) == '+')
+ offset++;
+ else if (int64.charAt(offset) == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < int64.length(); offset++) {
+ if (int64.charAt(offset) >= '0' && int64.charAt(offset) <= '9')
+ value = (value * 10 + int64.charAt(offset) - '0');
+ else if (int64.charAt(offset) == 'i' && int64.charAt(offset + 1) == '6'
+ && int64.charAt(offset + 2) == '4' && offset + 3 == int64.length())
+ break;
+ else
+ throw new AsterixException(errorMessage);
+ }
+ if (value < 0)
+ throw new AsterixException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+
+ aInt64.setValue(value);
+ int64Serde.serialize(aInt64, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parsePoint(String point, DataOutput out) throws AsterixException {
+ try {
+ APointSerializerDeserializer.parse(point, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parsePoint3d(String point3d, DataOutput out) throws AsterixException {
+ try {
+ APoint3DSerializerDeserializer.parse(point3d, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseCircle(String circle, DataOutput out) throws AsterixException {
+ try {
+ ACircleSerializerDeserializer.parse(circle, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseRectangle(String rectangle, DataOutput out) throws AsterixException {
+ try {
+ ARectangleSerializerDeserializer.parse(rectangle, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseLine(String line, DataOutput out) throws AsterixException {
+ try {
+ ALineSerializerDeserializer.parse(line, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parsePolygon(String polygon, DataOutput out) throws AsterixException, IOException {
+ try {
+ APolygonSerializerDeserializer.parse(polygon, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseTime(String time, DataOutput out) throws AsterixException {
+ try {
+ ATimeSerializerDeserializer.parse(time, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseDate(String date, DataOutput out) throws AsterixException, IOException {
+ try {
+ ADateSerializerDeserializer.parse(date, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseDatetime(String datetime, DataOutput out) throws AsterixException, IOException {
+ try {
+ ADateTimeSerializerDeserializer.parse(datetime, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseDuration(String duration, DataOutput out) throws AsterixException {
+ try {
+ ADurationSerializerDeserializer.parse(duration, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+
+ }
+
+ private IAType getComplexType(IAType aObjectType, ATypeTag tag) {
+
+ if (aObjectType == null) {
+ return null;
+ }
+
+ if (aObjectType.getTypeTag() == tag)
+ return aObjectType;
+
+ if (aObjectType.getTypeTag() == ATypeTag.UNION) {
+ unionList = ((AUnionType) aObjectType).getUnionList();
+ for (int i = 0; i < unionList.size(); i++)
+ if (unionList.get(i).getTypeTag() == tag) {
+ return unionList.get(i);
+ }
+ }
+ return null; // wont get here
+ }
+
+ List<IAType> unionList;
+
+ private boolean checkType(ATypeTag expectedTypeTag, IAType aObjectType, DataOutput out) throws IOException {
+
+ if (aObjectType == null)
+ return true;
+
+ if (aObjectType.getTypeTag() != ATypeTag.UNION) {
+ if (expectedTypeTag == aObjectType.getTypeTag())
+ return true;
+ } else { // union
+ unionList = ((AUnionType) aObjectType).getUnionList();
+ for (int i = 0; i < unionList.size(); i++)
+ if (unionList.get(i).getTypeTag() == expectedTypeTag)
+ return true;
+ }
+ return false;
+ }
+
+ private void parseRecord(ARecordType recType, DataOutput out, Boolean datasetRec) throws IOException,
+ AsterixException {
+
+ ArrayBackedValueStorage fieldValueBuffer = getTempBuffer();
+ ArrayBackedValueStorage fieldNameBuffer = getTempBuffer();
+ IARecordBuilder recBuilder = getRecordBuilder();
+
+ // Boolean[] nulls = null;
+ BitSet nulls = null;
+ if (datasetRec) {
+ if (recType != null) {
+ nulls = new BitSet(recType.getFieldNames().length);
+ recBuilder.reset(recType);
+ } else
+ recBuilder.reset(null);
+ } else if (recType != null) {
+ nulls = new BitSet(recType.getFieldNames().length);
+ recBuilder.reset(recType);
+ } else
+ recBuilder.reset(null);
+
+ recBuilder.init();
+ Token token = null;
+ boolean inRecord = true;
+ boolean expectingRecordField = false;
+ boolean first = true;
+
+ Boolean openRecordField = false;
+ int fieldId = 0;
+ IAType fieldType = null;
+ do {
+ token = nextToken();
+ switch (token.kind) {
+ case AdmLexerConstants.END_RECORD: {
+ if (expectingRecordField) {
+ throw new AsterixException("Found END_RECORD while expecting a record field.");
+ }
+ inRecord = false;
+ break;
+ }
+ case AdmLexerConstants.STRING_LITERAL: {
+ // we've read the name of the field
+ // now read the content
+ fieldNameBuffer.reset();
+ fieldValueBuffer.reset();
+ expectingRecordField = false;
+
+ if (recType != null) {
+ String fldName = token.image.substring(1, token.image.length() - 1);
+ fieldId = recBuilder.getFieldId(fldName);
+ if (fieldId < 0 && !recType.isOpen()) {
+ throw new AsterixException("This record is closed, you can not add extra fields !!");
+ } else if (fieldId < 0 && recType.isOpen()) {
+ aStringFieldName.setValue(token.image.substring(1, token.image.length() - 1));
+ stringSerde.serialize(aStringFieldName, fieldNameBuffer.getDataOutput());
+ openRecordField = true;
+ fieldType = null;
+ } else {
+ // a closed field
+ nulls.set(fieldId);
+ fieldType = recType.getFieldTypes()[fieldId];
+ openRecordField = false;
+ }
+ } else {
+ aStringFieldName.setValue(token.image.substring(1, token.image.length() - 1));
+ stringSerde.serialize(aStringFieldName, fieldNameBuffer.getDataOutput());
+ openRecordField = true;
+ fieldType = null;
+ }
+
+ token = nextToken();
+ if (token.kind != AdmLexerConstants.COLON) {
+ throw new AsterixException("Unexpected ADM token kind: "
+ + admLexer.tokenKindToString(token.kind) + " while expecting \":\".");
+ }
+
+ token = nextToken();
+ this.admFromLexerStream(token, fieldType, fieldValueBuffer.getDataOutput(), false);
+ if (openRecordField) {
+ if (fieldValueBuffer.getBytes()[0] != ATypeTag.NULL.serialize())
+ recBuilder.addField(fieldNameBuffer, fieldValueBuffer);
+ } else if (recType.getFieldTypes()[fieldId].getTypeTag() == ATypeTag.UNION) {
+ if (NonTaggedFormatUtil.isOptionalField((AUnionType) recType.getFieldTypes()[fieldId])) {
+ if (fieldValueBuffer.getBytes()[0] != ATypeTag.NULL.serialize()) {
+ recBuilder.addField(fieldId, fieldValueBuffer);
+ }
+ }
+ } else {
+ recBuilder.addField(fieldId, fieldValueBuffer);
+ }
+
+ break;
+ }
+ case AdmLexerConstants.COMMA: {
+ if (first) {
+ throw new AsterixException("Found COMMA before any record field.");
+ }
+ if (expectingRecordField) {
+ throw new AsterixException("Found COMMA while expecting a record field.");
+ }
+ expectingRecordField = true;
+ break;
+ }
+ default: {
+ throw new AsterixException("Unexpected ADM token kind: "
+ + admLexer.tokenKindToString(token.kind) + " while parsing record fields.");
+ }
+ }
+ first = false;
+ } while (inRecord);
+
+ if (recType != null) {
+ nullableFieldId = checkNullConstraints(recType, nulls);
+ if (nullableFieldId != -1)
+ throw new AsterixException("Field " + nullableFieldId + " can not be null");
+ }
+ recBuilder.write(out, true);
+ returnRecordBuilder(recBuilder);
+ returnTempBuffer(fieldNameBuffer);
+ returnTempBuffer(fieldValueBuffer);
+ }
+
+ private int checkNullConstraints(ARecordType recType, BitSet nulls) {
+
+ boolean isNull = false;
+ for (int i = 0; i < recType.getFieldTypes().length; i++)
+ if (nulls.get(i) == false) {
+ IAType type = recType.getFieldTypes()[i];
+ if (type.getTypeTag() != ATypeTag.NULL && type.getTypeTag() != ATypeTag.UNION)
+ return i;
+
+ if (type.getTypeTag() == ATypeTag.UNION) { // union
+ unionList = ((AUnionType) type).getUnionList();
+ for (int j = 0; j < unionList.size(); j++)
+ if (unionList.get(j).getTypeTag() == ATypeTag.NULL) {
+ isNull = true;
+ break;
+ }
+ if (!isNull)
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private void parseOrderedList(AOrderedListType oltype, DataOutput out) throws IOException, AsterixException {
+
+ ArrayBackedValueStorage itemBuffer = getTempBuffer();
+ OrderedListBuilder orderedListBuilder = (OrderedListBuilder) getOrderedListBuilder();
+
+ IAType itemType = null;
+ if (oltype != null)
+ itemType = oltype.getItemType();
+ orderedListBuilder.reset(oltype);
+
+ Token token = null;
+ boolean inList = true;
+ boolean expectingListItem = false;
+ boolean first = true;
+ do {
+ token = nextToken();
+ if (token.kind == AdmLexerConstants.END_ORDERED_LIST) {
+ if (expectingListItem) {
+ throw new AsterixException("Found END_COLLECTION while expecting a list item.");
+ }
+ inList = false;
+ } else if (token.kind == AdmLexerConstants.COMMA) {
+ if (first) {
+ throw new AsterixException("Found COMMA before any list item.");
+ }
+ if (expectingListItem) {
+ throw new AsterixException("Found COMMA while expecting a list item.");
+ }
+ expectingListItem = true;
+ } else {
+ expectingListItem = false;
+ itemBuffer.reset();
+
+ admFromLexerStream(token, itemType, itemBuffer.getDataOutput(), false);
+ orderedListBuilder.addItem(itemBuffer);
+ }
+ first = false;
+ } while (inList);
+ orderedListBuilder.write(out, true);
+ returnOrderedListBuilder(orderedListBuilder);
+ returnTempBuffer(itemBuffer);
+ }
+
+ private void parseUnorderedList(AUnorderedListType uoltype, DataOutput out) throws IOException,
+ AsterixException {
+
+ ArrayBackedValueStorage itemBuffer = getTempBuffer();
+ UnorderedListBuilder unorderedListBuilder = (UnorderedListBuilder) getUnorderedListBuilder();
+
+ IAType itemType = null;
+
+ if (uoltype != null)
+ itemType = uoltype.getItemType();
+ unorderedListBuilder.reset(uoltype);
+
+ Token token = null;
+ boolean inList = true;
+ boolean expectingListItem = false;
+ boolean first = true;
+ do {
+ token = nextToken();
+ if (token.kind == AdmLexerConstants.END_UNORDERED_LIST) {
+ if (expectingListItem) {
+ throw new AsterixException("Found END_COLLECTION while expecting a list item.");
+ }
+ inList = false;
+ } else if (token.kind == AdmLexerConstants.COMMA) {
+ if (first) {
+ throw new AsterixException("Found COMMA before any list item.");
+ }
+ if (expectingListItem) {
+ throw new AsterixException("Found COMMA while expecting a list item.");
+ }
+ expectingListItem = true;
+ } else {
+ expectingListItem = false;
+ itemBuffer.reset();
+ admFromLexerStream(token, itemType, itemBuffer.getDataOutput(), false);
+ unorderedListBuilder.addItem(itemBuffer);
+ }
+ first = false;
+ } while (inList);
+ unorderedListBuilder.write(out, true);
+ returnUnorderedListBuilder(unorderedListBuilder);
+ returnTempBuffer(itemBuffer);
+ }
+
+ private Token nextToken() throws AsterixException {
+ try {
+ return admLexer.next();
+ } catch (ParseException pe) {
+ throw new AsterixException(pe);
+ }
+ }
+
+ private IARecordBuilder getRecordBuilder() {
+ RecordBuilder recBuilder = (RecordBuilder) recordBuilderPool.poll();
+ if (recBuilder != null)
+ return recBuilder;
+ else
+ return new RecordBuilder();
+ }
+
+ private void returnRecordBuilder(IARecordBuilder recBuilder) {
+ this.recordBuilderPool.add(recBuilder);
+ }
+
+ private IAOrderedListBuilder getOrderedListBuilder() {
+ OrderedListBuilder orderedListBuilder = (OrderedListBuilder) orderedListBuilderPool.poll();
+ if (orderedListBuilder != null)
+ return orderedListBuilder;
+ else
+ return new OrderedListBuilder();
+ }
+
+ private void returnOrderedListBuilder(IAOrderedListBuilder orderedListBuilder) {
+ this.orderedListBuilderPool.add(orderedListBuilder);
+ }
+
+ private IAUnorderedListBuilder getUnorderedListBuilder() {
+ UnorderedListBuilder unorderedListBuilder = (UnorderedListBuilder) unorderedListBuilderPool.poll();
+ if (unorderedListBuilder != null)
+ return unorderedListBuilder;
+ else
+ return new UnorderedListBuilder();
+ }
+
+ private void returnUnorderedListBuilder(IAUnorderedListBuilder unorderedListBuilder) {
+ this.unorderedListBuilderPool.add(unorderedListBuilder);
+ }
+
+ private ArrayBackedValueStorage getTempBuffer() {
+ ArrayBackedValueStorage tmpBaaos = baaosPool.poll();
+ if (tmpBaaos != null) {
+ return tmpBaaos;
+ } else {
+ return new ArrayBackedValueStorage();
+ }
+ }
+
+ private void returnTempBuffer(ArrayBackedValueStorage tempBaaos) {
+ baaosPool.add(tempBaaos);
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/AdmTupleParser.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/AdmTupleParser.java
new file mode 100644
index 0000000..3b52315
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/AdmTupleParser.java
@@ -0,0 +1,1047 @@
+package edu.uci.ics.asterix.runtime.operators.file;
+
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
+import java.util.BitSet;
+import java.util.List;
+import java.util.Queue;
+
+import edu.uci.ics.asterix.adm.parser.nontagged.AdmLexer;
+import edu.uci.ics.asterix.adm.parser.nontagged.AdmLexerConstants;
+import edu.uci.ics.asterix.adm.parser.nontagged.ParseException;
+import edu.uci.ics.asterix.adm.parser.nontagged.Token;
+import edu.uci.ics.asterix.builders.IAOrderedListBuilder;
+import edu.uci.ics.asterix.builders.IARecordBuilder;
+import edu.uci.ics.asterix.builders.IAUnorderedListBuilder;
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.builders.RecordBuilder;
+import edu.uci.ics.asterix.builders.UnorderedListBuilder;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ACircleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ALineSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APoint3DSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APointSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APolygonSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARectangleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
+import edu.uci.ics.asterix.om.base.ABoolean;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.AUnorderedListType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.hyracks.api.comm.IFrameWriter;
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender;
+import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+
+public class AdmTupleParser extends AbstractTupleParser {
+
+ protected AdmLexer admLexer;
+ protected ArrayTupleBuilder tb = new ArrayTupleBuilder(1);
+ protected DataOutput dos = tb.getDataOutput();
+ protected final FrameTupleAppender appender;
+ protected final ByteBuffer frame;
+ protected final ARecordType recType;
+
+ private int nullableFieldId = 0;
+
+ private Queue<ArrayBackedValueStorage> baaosPool = new ArrayDeque<ArrayBackedValueStorage>();
+ private Queue<IARecordBuilder> recordBuilderPool = new ArrayDeque<IARecordBuilder>();
+ private Queue<IAOrderedListBuilder> orderedListBuilderPool = new ArrayDeque<IAOrderedListBuilder>();
+ private Queue<IAUnorderedListBuilder> unorderedListBuilderPool = new ArrayDeque<IAUnorderedListBuilder>();
+
+ private String mismatchErrorMessage = "Mismatch Type, expecting a value of type ";
+
+
+ public AdmTupleParser(IHyracksTaskContext ctx, ARecordType recType) {
+ appender = new FrameTupleAppender(ctx.getFrameSize());
+ frame = ctx.allocateFrame();
+ this.recType = recType;
+
+ }
+
+ @Override
+ public void parse(InputStream in, IFrameWriter writer)
+ throws HyracksDataException {
+ admLexer = new AdmLexer(in);
+ appender.reset(frame, true);
+ int tupleNum = 0;
+ try {
+ while (true) {
+ tb.reset();
+ if (!parseAdmInstance(recType, true, dos)) {
+ break;
+ }
+ tb.addFieldEndOffset();
+ if (!appender.append(tb.getFieldEndOffsets(),
+ tb.getByteArray(), 0, tb.getSize())) {
+ FrameUtils.flushFrame(frame, writer);
+ appender.reset(frame, true);
+ if (!appender.append(tb.getFieldEndOffsets(),
+ tb.getByteArray(), 0, tb.getSize())) {
+ throw new IllegalStateException();
+ }
+ }
+ tupleNum++;
+ }
+ if (appender.getTupleCount() > 0) {
+ FrameUtils.flushFrame(frame, writer);
+ }
+ } catch (AsterixException ae) {
+ throw new HyracksDataException(ae);
+ } catch (IOException ioe) {
+ throw new HyracksDataException(ioe);
+ }
+ }
+
+ protected boolean parseAdmInstance(IAType objectType, Boolean datasetRec,
+ DataOutput out) throws AsterixException, IOException {
+ Token token;
+ try {
+ token = admLexer.next();
+ } catch (ParseException pe) {
+ throw new AsterixException(pe);
+ }
+ if (token.kind == AdmLexerConstants.EOF) {
+ return false;
+ } else {
+ admFromLexerStream(token, objectType, out, datasetRec);
+ return true;
+ }
+ }
+
+ private void admFromLexerStream(Token token, IAType objectType,
+ DataOutput out, Boolean datasetRec) throws AsterixException,
+ IOException {
+
+ switch (token.kind) {
+ case AdmLexerConstants.NULL_LITERAL: {
+ if (checkType(ATypeTag.NULL, objectType, out)) {
+ nullSerde.serialize(ANull.NULL, out);
+ } else
+ throw new AsterixException(" This field can not be null ");
+ break;
+ }
+ case AdmLexerConstants.TRUE_LITERAL: {
+ if (checkType(ATypeTag.BOOLEAN, objectType, out)) {
+ booleanSerde.serialize(ABoolean.TRUE, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.BOOLEAN_CONS: {
+ parseConstructor(ATypeTag.BOOLEAN, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.FALSE_LITERAL: {
+ if (checkType(ATypeTag.BOOLEAN, objectType, out)) {
+ booleanSerde.serialize(ABoolean.FALSE, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.DOUBLE_LITERAL: {
+ if (checkType(ATypeTag.DOUBLE, objectType, out)) {
+ aDouble.setValue(Double.parseDouble(token.image));
+ doubleSerde.serialize(aDouble, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.DOUBLE_CONS: {
+ parseConstructor(ATypeTag.DOUBLE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.FLOAT_LITERAL: {
+ if (checkType(ATypeTag.FLOAT, objectType, out)) {
+ aFloat.setValue(Float.parseFloat(token.image));
+ floatSerde.serialize(aFloat, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.FLOAT_CONS: {
+ parseConstructor(ATypeTag.FLOAT, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.INT8_LITERAL: {
+ if (checkType(ATypeTag.INT8, objectType, out)) {
+ parseInt8(token.image, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.INT8_CONS: {
+ parseConstructor(ATypeTag.INT8, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.INT16_LITERAL: {
+ if (checkType(ATypeTag.INT16, objectType, out)) {
+ parseInt16(token.image, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.INT16_CONS: {
+ parseConstructor(ATypeTag.INT16, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.INT_LITERAL:
+ case AdmLexerConstants.INT32_LITERAL: {
+ if (checkType(ATypeTag.INT32, objectType, out)) {
+ parseInt32(token.image, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.INT32_CONS: {
+ parseConstructor(ATypeTag.INT32, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.INT64_LITERAL: {
+ if (checkType(ATypeTag.INT64, objectType, out)) {
+ parseInt64(token.image, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.INT64_CONS: {
+ parseConstructor(ATypeTag.INT64, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.STRING_LITERAL: {
+ if (checkType(ATypeTag.STRING, objectType, out)) {
+ aString.setValue(token.image.substring(1,
+ token.image.length() - 1));
+ stringSerde.serialize(aString, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ break;
+ }
+ case AdmLexerConstants.STRING_CONS: {
+ parseConstructor(ATypeTag.STRING, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.DATE_CONS: {
+ parseConstructor(ATypeTag.DATE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.TIME_CONS: {
+ parseConstructor(ATypeTag.TIME, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.DATETIME_CONS: {
+ parseConstructor(ATypeTag.DATETIME, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.DURATION_CONS: {
+ parseConstructor(ATypeTag.DURATION, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.POINT_CONS: {
+ parseConstructor(ATypeTag.POINT, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.POINT3D_CONS: {
+ parseConstructor(ATypeTag.POINT3D, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.CIRCLE_CONS: {
+ parseConstructor(ATypeTag.CIRCLE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.RECTANGLE_CONS: {
+ parseConstructor(ATypeTag.RECTANGLE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.LINE_CONS: {
+ parseConstructor(ATypeTag.LINE, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.POLYGON_CONS: {
+ parseConstructor(ATypeTag.POLYGON, objectType, out);
+ break;
+ }
+ case AdmLexerConstants.START_UNORDERED_LIST: {
+ if (checkType(ATypeTag.UNORDEREDLIST, objectType, out)) {
+ objectType = getComplexType(objectType, ATypeTag.UNORDEREDLIST);
+ parseUnorderedList((AUnorderedListType) objectType, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeTag());
+ break;
+ }
+
+ case AdmLexerConstants.START_ORDERED_LIST: {
+ if (checkType(ATypeTag.ORDEREDLIST, objectType, out)) {
+ objectType = getComplexType(objectType, ATypeTag.ORDEREDLIST);
+ parseOrderedList((AOrderedListType) objectType, out);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeTag());
+ break;
+ }
+ case AdmLexerConstants.START_RECORD: {
+ if (checkType(ATypeTag.RECORD, objectType, out)) {
+ objectType = getComplexType(objectType, ATypeTag.RECORD);
+ parseRecord((ARecordType) objectType, out, datasetRec);
+ } else
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeTag());
+ break;
+ }
+ case AdmLexerConstants.EOF: {
+ break;
+ }
+ default: {
+ throw new AsterixException("Unexpected ADM token kind: "
+ + admLexer.tokenKindToString(token.kind) + ".");
+ }
+ }
+ }
+
+ private void parseDatetime(String datetime, DataOutput out)
+ throws AsterixException, IOException {
+ try {
+ ADateTimeSerializerDeserializer.parse(datetime, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseDuration(String duration, DataOutput out)
+ throws AsterixException {
+ try {
+ ADurationSerializerDeserializer.parse(duration, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+
+ }
+
+ private IAType getComplexType(IAType aObjectType, ATypeTag tag) {
+
+ if (aObjectType == null) {
+ return null;
+ }
+
+ if (aObjectType.getTypeTag() == tag)
+ return aObjectType;
+
+ if (aObjectType.getTypeTag() == ATypeTag.UNION) {
+ unionList = ((AUnionType) aObjectType).getUnionList();
+ for (int i = 0; i < unionList.size(); i++)
+ if (unionList.get(i).getTypeTag() == tag) {
+ return unionList.get(i);
+ }
+ }
+ return null; // wont get here
+ }
+
+ List<IAType> unionList;
+
+ private boolean checkType(ATypeTag expectedTypeTag, IAType aObjectType,
+ DataOutput out) throws IOException {
+
+ if (aObjectType == null)
+ return true;
+
+ if (aObjectType.getTypeTag() != ATypeTag.UNION) {
+ if (expectedTypeTag == aObjectType.getTypeTag())
+ return true;
+ } else { // union
+ unionList = ((AUnionType) aObjectType).getUnionList();
+ for (int i = 0; i < unionList.size(); i++)
+ if (unionList.get(i).getTypeTag() == expectedTypeTag)
+ return true;
+ }
+ return false;
+ }
+
+ private void parseRecord(ARecordType recType, DataOutput out,
+ Boolean datasetRec) throws IOException, AsterixException {
+
+ ArrayBackedValueStorage fieldValueBuffer = getTempBuffer();
+ ArrayBackedValueStorage fieldNameBuffer = getTempBuffer();
+ IARecordBuilder recBuilder = getRecordBuilder();
+
+ // Boolean[] nulls = null;
+ BitSet nulls = null;
+ if (datasetRec) {
+ if (recType != null) {
+ nulls = new BitSet(recType.getFieldNames().length);
+ recBuilder.reset(recType);
+ } else
+ recBuilder.reset(null);
+ } else if (recType != null) {
+ nulls = new BitSet(recType.getFieldNames().length);
+ recBuilder.reset(recType);
+ } else
+ recBuilder.reset(null);
+
+ recBuilder.init();
+ Token token = null;
+ boolean inRecord = true;
+ boolean expectingRecordField = false;
+ boolean first = true;
+
+ Boolean openRecordField = false;
+ int fieldId = 0;
+ IAType fieldType = null;
+ do {
+ token = nextToken();
+ switch (token.kind) {
+ case AdmLexerConstants.END_RECORD: {
+ if (expectingRecordField) {
+ throw new AsterixException(
+ "Found END_RECORD while expecting a record field.");
+ }
+ inRecord = false;
+ break;
+ }
+ case AdmLexerConstants.STRING_LITERAL: {
+ // we've read the name of the field
+ // now read the content
+ fieldNameBuffer.reset();
+ fieldValueBuffer.reset();
+ expectingRecordField = false;
+
+ if (recType != null) {
+ String fldName = token.image.substring(1,
+ token.image.length() - 1);
+ fieldId = recBuilder.getFieldId(fldName);
+ if (fieldId < 0 && !recType.isOpen()) {
+ throw new AsterixException(
+ "This record is closed, you can not add extra fields !!");
+ } else if (fieldId < 0 && recType.isOpen()) {
+ aStringFieldName.setValue(token.image.substring(1,
+ token.image.length() - 1));
+ stringSerde.serialize(aStringFieldName,
+ fieldNameBuffer.getDataOutput());
+ openRecordField = true;
+ fieldType = null;
+ } else {
+ // a closed field
+ nulls.set(fieldId);
+ fieldType = recType.getFieldTypes()[fieldId];
+ openRecordField = false;
+ }
+ } else {
+ aStringFieldName.setValue(token.image.substring(1,
+ token.image.length() - 1));
+ stringSerde.serialize(aStringFieldName,
+ fieldNameBuffer.getDataOutput());
+ openRecordField = true;
+ fieldType = null;
+ }
+
+ token = nextToken();
+ if (token.kind != AdmLexerConstants.COLON) {
+ throw new AsterixException("Unexpected ADM token kind: "
+ + admLexer.tokenKindToString(token.kind)
+ + " while expecting \":\".");
+ }
+
+ token = nextToken();
+ this.admFromLexerStream(token, fieldType,
+ fieldValueBuffer.getDataOutput(), false);
+ if (openRecordField) {
+ if (fieldValueBuffer.getBytes()[0] != ATypeTag.NULL
+ .serialize())
+ recBuilder.addField(fieldNameBuffer, fieldValueBuffer);
+ } else if (recType.getFieldTypes()[fieldId].getTypeTag() == ATypeTag.UNION) {
+ if (NonTaggedFormatUtil
+ .isOptionalField((AUnionType) recType
+ .getFieldTypes()[fieldId])) {
+ if (fieldValueBuffer.getBytes()[0] != ATypeTag.NULL
+ .serialize()) {
+ recBuilder.addField(fieldId, fieldValueBuffer);
+ }
+ }
+ } else {
+ recBuilder.addField(fieldId, fieldValueBuffer);
+ }
+
+ break;
+ }
+ case AdmLexerConstants.COMMA: {
+ if (first) {
+ throw new AsterixException(
+ "Found COMMA before any record field.");
+ }
+ if (expectingRecordField) {
+ throw new AsterixException(
+ "Found COMMA while expecting a record field.");
+ }
+ expectingRecordField = true;
+ break;
+ }
+ default: {
+ throw new AsterixException("Unexpected ADM token kind: "
+ + admLexer.tokenKindToString(token.kind)
+ + " while parsing record fields.");
+ }
+ }
+ first = false;
+ } while (inRecord);
+
+ if (recType != null) {
+ nullableFieldId = checkNullConstraints(recType, nulls);
+ if (nullableFieldId != -1)
+ throw new AsterixException("Field " + nullableFieldId
+ + " can not be null");
+ }
+ recBuilder.write(out, true);
+ returnRecordBuilder(recBuilder);
+ returnTempBuffer(fieldNameBuffer);
+ returnTempBuffer(fieldValueBuffer);
+ }
+
+ private int checkNullConstraints(ARecordType recType, BitSet nulls) {
+
+ boolean isNull = false;
+ for (int i = 0; i < recType.getFieldTypes().length; i++)
+ if (nulls.get(i) == false) {
+ IAType type = recType.getFieldTypes()[i];
+ if (type.getTypeTag() != ATypeTag.NULL
+ && type.getTypeTag() != ATypeTag.UNION)
+ return i;
+
+ if (type.getTypeTag() == ATypeTag.UNION) { // union
+ unionList = ((AUnionType) type).getUnionList();
+ for (int j = 0; j < unionList.size(); j++)
+ if (unionList.get(j).getTypeTag() == ATypeTag.NULL) {
+ isNull = true;
+ break;
+ }
+ if (!isNull)
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private void parseOrderedList(AOrderedListType oltype, DataOutput out)
+ throws IOException, AsterixException {
+
+ ArrayBackedValueStorage itemBuffer = getTempBuffer();
+ OrderedListBuilder orderedListBuilder = (OrderedListBuilder) getOrderedListBuilder();
+
+ IAType itemType = null;
+ if (oltype != null)
+ itemType = oltype.getItemType();
+ orderedListBuilder.reset(oltype);
+
+ Token token = null;
+ boolean inList = true;
+ boolean expectingListItem = false;
+ boolean first = true;
+ do {
+ token = nextToken();
+ if (token.kind == AdmLexerConstants.END_ORDERED_LIST) {
+ if (expectingListItem) {
+ throw new AsterixException(
+ "Found END_COLLECTION while expecting a list item.");
+ }
+ inList = false;
+ } else if (token.kind == AdmLexerConstants.COMMA) {
+ if (first) {
+ throw new AsterixException(
+ "Found COMMA before any list item.");
+ }
+ if (expectingListItem) {
+ throw new AsterixException(
+ "Found COMMA while expecting a list item.");
+ }
+ expectingListItem = true;
+ } else {
+ expectingListItem = false;
+ itemBuffer.reset();
+
+ admFromLexerStream(token, itemType, itemBuffer.getDataOutput(),
+ false);
+ orderedListBuilder.addItem(itemBuffer);
+ }
+ first = false;
+ } while (inList);
+ orderedListBuilder.write(out, true);
+ returnOrderedListBuilder(orderedListBuilder);
+ returnTempBuffer(itemBuffer);
+ }
+
+ private void parseUnorderedList(AUnorderedListType uoltype, DataOutput out)
+ throws IOException, AsterixException {
+
+ ArrayBackedValueStorage itemBuffer = getTempBuffer();
+ UnorderedListBuilder unorderedListBuilder = (UnorderedListBuilder) getUnorderedListBuilder();
+
+ IAType itemType = null;
+
+ if (uoltype != null)
+ itemType = uoltype.getItemType();
+ unorderedListBuilder.reset(uoltype);
+
+ Token token = null;
+ boolean inList = true;
+ boolean expectingListItem = false;
+ boolean first = true;
+ do {
+ token = nextToken();
+ if (token.kind == AdmLexerConstants.END_UNORDERED_LIST) {
+ if (expectingListItem) {
+ throw new AsterixException(
+ "Found END_COLLECTION while expecting a list item.");
+ }
+ inList = false;
+ } else if (token.kind == AdmLexerConstants.COMMA) {
+ if (first) {
+ throw new AsterixException(
+ "Found COMMA before any list item.");
+ }
+ if (expectingListItem) {
+ throw new AsterixException(
+ "Found COMMA while expecting a list item.");
+ }
+ expectingListItem = true;
+ } else {
+ expectingListItem = false;
+ itemBuffer.reset();
+ admFromLexerStream(token, itemType, itemBuffer.getDataOutput(),
+ false);
+ unorderedListBuilder.addItem(itemBuffer);
+ }
+ first = false;
+ } while (inList);
+ unorderedListBuilder.write(out, true);
+ returnUnorderedListBuilder(unorderedListBuilder);
+ returnTempBuffer(itemBuffer);
+ }
+
+ private Token nextToken() throws AsterixException {
+ try {
+ return admLexer.next();
+ } catch (ParseException pe) {
+ throw new AsterixException(pe);
+ }
+ }
+
+ private IARecordBuilder getRecordBuilder() {
+ RecordBuilder recBuilder = (RecordBuilder) recordBuilderPool.poll();
+ if (recBuilder != null)
+ return recBuilder;
+ else
+ return new RecordBuilder();
+ }
+
+ private void returnRecordBuilder(IARecordBuilder recBuilder) {
+ this.recordBuilderPool.add(recBuilder);
+ }
+
+ private IAOrderedListBuilder getOrderedListBuilder() {
+ OrderedListBuilder orderedListBuilder = (OrderedListBuilder) orderedListBuilderPool
+ .poll();
+ if (orderedListBuilder != null)
+ return orderedListBuilder;
+ else
+ return new OrderedListBuilder();
+ }
+
+ private void returnOrderedListBuilder(
+ IAOrderedListBuilder orderedListBuilder) {
+ this.orderedListBuilderPool.add(orderedListBuilder);
+ }
+
+ private IAUnorderedListBuilder getUnorderedListBuilder() {
+ UnorderedListBuilder unorderedListBuilder = (UnorderedListBuilder) unorderedListBuilderPool
+ .poll();
+ if (unorderedListBuilder != null)
+ return unorderedListBuilder;
+ else
+ return new UnorderedListBuilder();
+ }
+
+ private void returnUnorderedListBuilder(
+ IAUnorderedListBuilder unorderedListBuilder) {
+ this.unorderedListBuilderPool.add(unorderedListBuilder);
+ }
+
+ private ArrayBackedValueStorage getTempBuffer() {
+ ArrayBackedValueStorage tmpBaaos = baaosPool.poll();
+ if (tmpBaaos != null) {
+ return tmpBaaos;
+ } else {
+ return new ArrayBackedValueStorage();
+ }
+ }
+
+ private void returnTempBuffer(ArrayBackedValueStorage tempBaaos) {
+ baaosPool.add(tempBaaos);
+ }
+
+ private void parseConstructor(ATypeTag typeTag, IAType objectType,
+ DataOutput out) throws AsterixException {
+ try {
+ Token token = admLexer.next();
+ if (token.kind == AdmLexerConstants.CONSTRUCTOR_OPEN) {
+ if (checkType(typeTag, objectType, out)) {
+ token = admLexer.next();
+ if (token.kind == AdmLexerConstants.STRING_LITERAL) {
+ switch (typeTag) {
+ case BOOLEAN:
+ parseBoolean(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case INT8:
+ parseInt8(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case INT16:
+ parseInt16(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case INT32:
+ parseInt32(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case INT64:
+ parseInt64(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case FLOAT:
+ aFloat.setValue(Float.parseFloat(token.image
+ .substring(1, token.image.length() - 1)));
+ floatSerde.serialize(aFloat, out);
+ break;
+ case DOUBLE:
+ aDouble.setValue(Double.parseDouble(token.image
+ .substring(1, token.image.length() - 1)));
+ doubleSerde.serialize(aDouble, out);
+ break;
+ case STRING:
+ aString.setValue(token.image.substring(1,
+ token.image.length() - 1));
+ stringSerde.serialize(aString, out);
+ break;
+ case TIME:
+ parseTime(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case DATE:
+ parseDate(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case DATETIME:
+ parseDatetime(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case DURATION:
+ parseDuration(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case POINT:
+ parsePoint(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case POINT3D:
+ parsePoint3d(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case CIRCLE:
+ parseCircle(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case RECTANGLE:
+ parseRectangle(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case LINE:
+ parseLine(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+ case POLYGON:
+ parsePolygon(
+ token.image.substring(1,
+ token.image.length() - 1), out);
+ break;
+
+ }
+ token = admLexer.next();
+ if (token.kind == AdmLexerConstants.CONSTRUCTOR_CLOSE)
+ return;
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new AsterixException(e);
+ }
+ throw new AsterixException(mismatchErrorMessage
+ + objectType.getTypeName());
+ }
+
+ private void parseBoolean(String bool, DataOutput out)
+ throws AsterixException {
+ String errorMessage = "This can not be an instance of boolean";
+ try {
+ if (bool.equals("true"))
+ booleanSerde.serialize(ABoolean.TRUE, out);
+ else if (bool.equals("false"))
+ booleanSerde.serialize(ABoolean.FALSE, out);
+ else
+ throw new AsterixException(errorMessage);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parseInt8(String int8, DataOutput out) throws AsterixException {
+ String errorMessage = "This can not be an instance of int8";
+ try {
+ boolean positive = true;
+ byte value = 0;
+ int offset = 0;
+
+ if (int8.charAt(offset) == '+')
+ offset++;
+ else if (int8.charAt(offset) == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < int8.length(); offset++) {
+ if (int8.charAt(offset) >= '0' && int8.charAt(offset) <= '9')
+ value = (byte) (value * 10 + int8.charAt(offset) - '0');
+ else if (int8.charAt(offset) == 'i'
+ && int8.charAt(offset + 1) == '8'
+ && offset + 2 == int8.length())
+ break;
+ else
+ throw new AsterixException(errorMessage);
+ }
+ if (value < 0)
+ throw new AsterixException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+ aInt8.setValue(value);
+ int8Serde.serialize(aInt8, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parseInt16(String int16, DataOutput out)
+ throws AsterixException {
+ String errorMessage = "This can not be an instance of int16";
+ try {
+ boolean positive = true;
+ short value = 0;
+ int offset = 0;
+
+ if (int16.charAt(offset) == '+')
+ offset++;
+ else if (int16.charAt(offset) == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < int16.length(); offset++) {
+ if (int16.charAt(offset) >= '0' && int16.charAt(offset) <= '9')
+ value = (short) (value * 10 + int16.charAt(offset) - '0');
+ else if (int16.charAt(offset) == 'i'
+ && int16.charAt(offset + 1) == '1'
+ && int16.charAt(offset + 2) == '6'
+ && offset + 3 == int16.length())
+ break;
+ else
+ throw new AsterixException(errorMessage);
+ }
+ if (value < 0)
+ throw new AsterixException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+ aInt16.setValue(value);
+ int16Serde.serialize(aInt16, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parseInt32(String int32, DataOutput out)
+ throws AsterixException {
+
+ String errorMessage = "This can not be an instance of int32";
+ try {
+ boolean positive = true;
+ int value = 0;
+ int offset = 0;
+
+ if (int32.charAt(offset) == '+')
+ offset++;
+ else if (int32.charAt(offset) == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < int32.length(); offset++) {
+ if (int32.charAt(offset) >= '0' && int32.charAt(offset) <= '9')
+ value = (value * 10 + int32.charAt(offset) - '0');
+ else if (int32.charAt(offset) == 'i'
+ && int32.charAt(offset + 1) == '3'
+ && int32.charAt(offset + 2) == '2'
+ && offset + 3 == int32.length())
+ break;
+ else
+ throw new AsterixException(errorMessage);
+ }
+ if (value < 0)
+ throw new AsterixException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+
+ aInt32.setValue(value);
+ int32Serde.serialize(aInt32, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parseInt64(String int64, DataOutput out)
+ throws AsterixException {
+ String errorMessage = "This can not be an instance of int64";
+ try {
+ boolean positive = true;
+ long value = 0;
+ int offset = 0;
+
+ if (int64.charAt(offset) == '+')
+ offset++;
+ else if (int64.charAt(offset) == '-') {
+ offset++;
+ positive = false;
+ }
+ for (; offset < int64.length(); offset++) {
+ if (int64.charAt(offset) >= '0' && int64.charAt(offset) <= '9')
+ value = (value * 10 + int64.charAt(offset) - '0');
+ else if (int64.charAt(offset) == 'i'
+ && int64.charAt(offset + 1) == '6'
+ && int64.charAt(offset + 2) == '4'
+ && offset + 3 == int64.length())
+ break;
+ else
+ throw new AsterixException(errorMessage);
+ }
+ if (value < 0)
+ throw new AsterixException(errorMessage);
+ if (value > 0 && !positive)
+ value *= -1;
+
+ aInt64.setValue(value);
+ int64Serde.serialize(aInt64, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(errorMessage);
+ }
+ }
+
+ private void parsePoint(String point, DataOutput out)
+ throws AsterixException {
+ try {
+ APointSerializerDeserializer.parse(point, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parsePoint3d(String point3d, DataOutput out)
+ throws AsterixException {
+ try {
+ APoint3DSerializerDeserializer.parse(point3d, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseCircle(String circle, DataOutput out)
+ throws AsterixException {
+ try {
+ ACircleSerializerDeserializer.parse(circle, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseRectangle(String rectangle, DataOutput out)
+ throws AsterixException {
+ try {
+ ARectangleSerializerDeserializer.parse(rectangle, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseLine(String line, DataOutput out) throws AsterixException {
+ try {
+ ALineSerializerDeserializer.parse(line, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parsePolygon(String polygon, DataOutput out)
+ throws AsterixException, IOException {
+ try {
+ APolygonSerializerDeserializer.parse(polygon, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseTime(String time, DataOutput out) throws AsterixException {
+ try {
+ ATimeSerializerDeserializer.parse(time, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+ private void parseDate(String date, DataOutput out)
+ throws AsterixException, IOException {
+ try {
+ ADateSerializerDeserializer.parse(date, out);
+ } catch (HyracksDataException e) {
+ throw new AsterixException(e);
+ }
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/DelimitedDataTupleParser.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/DelimitedDataTupleParser.java
new file mode 100644
index 0000000..db46578
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/DelimitedDataTupleParser.java
@@ -0,0 +1,331 @@
+package edu.uci.ics.asterix.runtime.operators.file;
+
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import edu.uci.ics.asterix.builders.IARecordBuilder;
+import edu.uci.ics.asterix.builders.RecordBuilder;
+import edu.uci.ics.asterix.om.base.AMutableString;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.api.comm.IFrameWriter;
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender;
+import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+
+public class DelimitedDataTupleParser extends AbstractTupleParser {
+
+ protected final IValueParserFactory[] valueParserFactories;
+ protected final char fieldDelimiter;
+ protected final IHyracksTaskContext ctx;
+ protected final ARecordType recType;
+ protected ArrayTupleBuilder tb = new ArrayTupleBuilder(1);
+ protected DataOutput recDos = tb.getDataOutput();
+ protected final FrameTupleAppender appender;
+ protected final ByteBuffer frame;
+
+
+ public DelimitedDataTupleParser(IHyracksTaskContext ctx,
+ ARecordType recType, IValueParserFactory[] valueParserFactories,
+ char fieldDelimter) {
+ this.valueParserFactories = valueParserFactories;
+ this.fieldDelimiter = fieldDelimter;
+ this.ctx = ctx;
+ this.recType = recType;
+ appender = new FrameTupleAppender(ctx.getFrameSize());
+ frame = ctx.allocateFrame();
+ }
+
+ @Override
+ public void parse(InputStream in, IFrameWriter writer)
+ throws HyracksDataException {
+ try {
+ IValueParser[] valueParsers = new IValueParser[valueParserFactories.length];
+ for (int i = 0; i < valueParserFactories.length; ++i) {
+ valueParsers[i] = valueParserFactories[i].createValueParser();
+ }
+
+ appender.reset(frame, true);
+
+
+ ArrayBackedValueStorage fieldValueBuffer = new ArrayBackedValueStorage();
+ DataOutput fieldValueBufferOutput = fieldValueBuffer
+ .getDataOutput();
+ IARecordBuilder recBuilder = new RecordBuilder();
+ recBuilder.reset(recType);
+ recBuilder.init();
+
+ int n = recType.getFieldNames().length;
+ byte[] fieldTypeTags = new byte[n];
+ for (int i = 0; i < n; i++) {
+ ATypeTag tag = recType.getFieldTypes()[i].getTypeTag();
+ fieldTypeTags[i] = tag.serialize();
+ }
+
+ int[] fldIds = new int[n];
+ ArrayBackedValueStorage[] nameBuffers = new ArrayBackedValueStorage[n];
+ AMutableString str = new AMutableString(null);
+ for (int i = 0; i < n; i++) {
+ String name = recType.getFieldNames()[i];
+ fldIds[i] = recBuilder.getFieldId(name);
+ if (fldIds[i] < 0) {
+ if (!recType.isOpen()) {
+ throw new HyracksDataException("Illegal field " + name
+ + " in closed type " + recType);
+ } else {
+ nameBuffers[i] = new ArrayBackedValueStorage();
+ fieldNameToBytes(name, str, nameBuffers[i]);
+ }
+ }
+ }
+
+ FieldCursor cursor = new FieldCursor(new InputStreamReader(in));
+ while (cursor.nextRecord()) {
+ tb.reset();
+ recBuilder.reset(recType);
+ recBuilder.init();
+
+ for (int i = 0; i < valueParsers.length; ++i) {
+ if (!cursor.nextField()) {
+ break;
+ }
+ fieldValueBuffer.reset();
+ fieldValueBufferOutput.writeByte(fieldTypeTags[i]);
+ valueParsers[i]
+ .parse(cursor.buffer, cursor.fStart, cursor.fEnd
+ - cursor.fStart, fieldValueBufferOutput);
+ if (fldIds[i] < 0) {
+ recBuilder.addField(nameBuffers[i], fieldValueBuffer);
+ } else {
+ recBuilder.addField(fldIds[i], fieldValueBuffer);
+ }
+ }
+ recBuilder.write(recDos, true);
+ tb.addFieldEndOffset();
+
+ if (!appender.append(tb.getFieldEndOffsets(),
+ tb.getByteArray(), 0, tb.getSize())) {
+ FrameUtils.flushFrame(frame, writer);
+ appender.reset(frame, true);
+ if (!appender.append(tb.getFieldEndOffsets(),
+ tb.getByteArray(), 0, tb.getSize())) {
+ throw new IllegalStateException();
+ }
+ }
+ }
+ if (appender.getTupleCount() > 0) {
+ FrameUtils.flushFrame(frame, writer);
+ }
+ } catch (IOException e) {
+ throw new HyracksDataException(e);
+ }
+ }
+
+ protected void fieldNameToBytes(String fieldName, AMutableString str,
+ ArrayBackedValueStorage buffer) throws HyracksDataException {
+ buffer.reset();
+ DataOutput out = buffer.getDataOutput();
+ str.setValue(fieldName);
+ try {
+ stringSerde.serialize(str, out);
+ } catch (IOException e) {
+ throw new HyracksDataException(e);
+ }
+ }
+
+ protected enum State {
+ INIT, IN_RECORD, EOR, CR, EOF
+ }
+
+ protected class FieldCursor {
+ private static final int INITIAL_BUFFER_SIZE = 4096;
+ private static final int INCREMENT = 4096;
+
+ private final Reader in;
+
+ private char[] buffer;
+ private int start;
+ private int end;
+ private State state;
+
+ private int fStart;
+ private int fEnd;
+
+ public FieldCursor(Reader in) {
+ this.in = in;
+ buffer = new char[INITIAL_BUFFER_SIZE];
+ start = 0;
+ end = 0;
+ state = State.INIT;
+ }
+
+ public boolean nextRecord() throws IOException {
+ while (true) {
+ switch (state) {
+ case INIT:
+ boolean eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return false;
+ } else {
+ state = State.IN_RECORD;
+ return true;
+ }
+
+ case IN_RECORD:
+ int p = start;
+ while (true) {
+ if (p >= end) {
+ int s = start;
+ eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return start < end;
+ }
+ p -= (s - start);
+ }
+ char ch = buffer[p];
+ if (ch == '\n') {
+ start = p + 1;
+ state = State.EOR;
+ break;
+ } else if (ch == '\r') {
+ start = p + 1;
+ state = State.CR;
+ break;
+ }
+ ++p;
+ }
+ break;
+
+ case CR:
+ if (start >= end) {
+ eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return false;
+ }
+ }
+ char ch = buffer[start];
+ if (ch == '\n') {
+ ++start;
+ state = State.EOR;
+ } else {
+ state = State.IN_RECORD;
+ return true;
+ }
+
+ case EOR:
+ if (start >= end) {
+ eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return false;
+ }
+ }
+ state = State.IN_RECORD;
+ return start < end;
+
+ case EOF:
+ return false;
+ }
+ }
+ }
+
+ public boolean nextField() throws IOException {
+ switch (state) {
+ case INIT:
+ case EOR:
+ case EOF:
+ case CR:
+ return false;
+
+ case IN_RECORD:
+ boolean eof;
+ int p = start;
+ while (true) {
+ if (p >= end) {
+ int s = start;
+ eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return true;
+ }
+ p -= (s - start);
+ }
+ char ch = buffer[p];
+ if (ch == fieldDelimiter) {
+ fStart = start;
+ fEnd = p;
+ start = p + 1;
+ return true;
+ } else if (ch == '\n') {
+ fStart = start;
+ fEnd = p;
+ start = p + 1;
+ state = State.EOR;
+ return true;
+ } else if (ch == '\r') {
+ fStart = start;
+ fEnd = p;
+ start = p + 1;
+ state = State.CR;
+ return true;
+ }
+ ++p;
+ }
+ }
+ throw new IllegalStateException();
+ }
+
+ protected boolean readMore() throws IOException {
+ if (start > 0) {
+ System.arraycopy(buffer, start, buffer, 0, end - start);
+ }
+ end -= start;
+ start = 0;
+
+ if (end == buffer.length) {
+ buffer = Arrays.copyOf(buffer, buffer.length + INCREMENT);
+ }
+
+ int n = in.read(buffer, end, buffer.length - end);
+ if (n < 0) {
+ return false;
+ }
+ end += n;
+ return true;
+ }
+
+ public int getfStart() {
+ return fStart;
+ }
+
+ public void setfStart(int fStart) {
+ this.fStart = fStart;
+ }
+
+ public int getfEnd() {
+ return fEnd;
+ }
+
+ public void setfEnd(int fEnd) {
+ this.fEnd = fEnd;
+ }
+
+ public char[] getBuffer() {
+ return buffer;
+ }
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/NtDelimitedDataTupleParserFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/NtDelimitedDataTupleParserFactory.java
new file mode 100644
index 0000000..0c93d86
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/NtDelimitedDataTupleParserFactory.java
@@ -0,0 +1,317 @@
+package edu.uci.ics.asterix.runtime.operators.file;
+
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import edu.uci.ics.asterix.builders.IARecordBuilder;
+import edu.uci.ics.asterix.builders.RecordBuilder;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableString;
+import edu.uci.ics.asterix.om.base.AString;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.hyracks.api.comm.IFrameWriter;
+import edu.uci.ics.hyracks.api.context.IHyracksTaskContext;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
+import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender;
+import edu.uci.ics.hyracks.dataflow.common.comm.util.FrameUtils;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+import edu.uci.ics.hyracks.dataflow.std.file.ITupleParser;
+import edu.uci.ics.hyracks.dataflow.std.file.ITupleParserFactory;
+
+public class NtDelimitedDataTupleParserFactory implements ITupleParserFactory {
+ private static final long serialVersionUID = 1L;
+ protected ARecordType recordType;
+ protected IValueParserFactory[] valueParserFactories;
+ protected char fieldDelimiter;
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ASTRING);
+
+ public NtDelimitedDataTupleParserFactory(ARecordType recordType, IValueParserFactory[] valueParserFactories,
+ char fieldDelimiter) {
+ this.recordType = recordType;
+ this.valueParserFactories = valueParserFactories;
+ this.fieldDelimiter = fieldDelimiter;
+ }
+
+ @Override
+ public ITupleParser createTupleParser(final IHyracksTaskContext ctx) {
+ return new ITupleParser() {
+ @Override
+ public void parse(InputStream in, IFrameWriter writer) throws HyracksDataException {
+ try {
+ IValueParser[] valueParsers = new IValueParser[valueParserFactories.length];
+ for (int i = 0; i < valueParserFactories.length; ++i) {
+ valueParsers[i] = valueParserFactories[i].createValueParser();
+ }
+ ByteBuffer frame = ctx.allocateFrame();
+ FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
+ appender.reset(frame, true);
+ ArrayTupleBuilder tb = new ArrayTupleBuilder(1);
+ DataOutput recDos = tb.getDataOutput();
+
+ ArrayBackedValueStorage fieldValueBuffer = new ArrayBackedValueStorage();
+ DataOutput fieldValueBufferOutput = fieldValueBuffer.getDataOutput();
+ IARecordBuilder recBuilder = new RecordBuilder();
+ recBuilder.reset(recordType);
+ recBuilder.init();
+
+ int n = recordType.getFieldNames().length;
+ byte[] fieldTypeTags = new byte[n];
+ for (int i = 0; i < n; i++) {
+ ATypeTag tag = recordType.getFieldTypes()[i].getTypeTag();
+ fieldTypeTags[i] = tag.serialize();
+ }
+
+ int[] fldIds = new int[n];
+ ArrayBackedValueStorage[] nameBuffers = new ArrayBackedValueStorage[n];
+ AMutableString str = new AMutableString(null);
+ for (int i = 0; i < n; i++) {
+ String name = recordType.getFieldNames()[i];
+ fldIds[i] = recBuilder.getFieldId(name);
+ if (fldIds[i] < 0) {
+ if (!recordType.isOpen()) {
+ throw new HyracksDataException("Illegal field " + name + " in closed type "
+ + recordType);
+ } else {
+ nameBuffers[i] = new ArrayBackedValueStorage();
+ fieldNameToBytes(name, str, nameBuffers[i]);
+ }
+ }
+ }
+
+ FieldCursor cursor = new FieldCursor(new InputStreamReader(in));
+ while (cursor.nextRecord()) {
+ tb.reset();
+ recBuilder.reset(recordType);
+ recBuilder.init();
+
+ for (int i = 0; i < valueParsers.length; ++i) {
+ if (!cursor.nextField()) {
+ break;
+ }
+ fieldValueBuffer.reset();
+ fieldValueBufferOutput.writeByte(fieldTypeTags[i]);
+ valueParsers[i].parse(cursor.buffer, cursor.fStart, cursor.fEnd - cursor.fStart,
+ fieldValueBufferOutput);
+ if (fldIds[i] < 0) {
+ recBuilder.addField(nameBuffers[i], fieldValueBuffer);
+ } else {
+ recBuilder.addField(fldIds[i], fieldValueBuffer);
+ }
+ }
+ recBuilder.write(recDos, true);
+ tb.addFieldEndOffset();
+
+ if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
+ FrameUtils.flushFrame(frame, writer);
+ appender.reset(frame, true);
+ if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
+ throw new IllegalStateException();
+ }
+ }
+ }
+ if (appender.getTupleCount() > 0) {
+ FrameUtils.flushFrame(frame, writer);
+ }
+ } catch (IOException e) {
+ throw new HyracksDataException(e);
+ }
+ }
+
+ private void fieldNameToBytes(String fieldName, AMutableString str, ArrayBackedValueStorage buffer)
+ throws HyracksDataException {
+ buffer.reset();
+ DataOutput out = buffer.getDataOutput();
+ str.setValue(fieldName);
+ try {
+ stringSerde.serialize(str, out);
+ } catch (IOException e) {
+ throw new HyracksDataException(e);
+ }
+ }
+
+ };
+ }
+
+ private enum State {
+ INIT,
+ IN_RECORD,
+ EOR,
+ CR,
+ EOF
+ }
+
+ private class FieldCursor {
+ private static final int INITIAL_BUFFER_SIZE = 4096;
+ private static final int INCREMENT = 4096;
+
+ private final Reader in;
+
+ private char[] buffer;
+ private int start;
+ private int end;
+ private State state;
+
+ private int fStart;
+ private int fEnd;
+
+ public FieldCursor(Reader in) {
+ this.in = in;
+ buffer = new char[INITIAL_BUFFER_SIZE];
+ start = 0;
+ end = 0;
+ state = State.INIT;
+ }
+
+ public boolean nextRecord() throws IOException {
+ while (true) {
+ switch (state) {
+ case INIT:
+ boolean eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return false;
+ } else {
+ state = State.IN_RECORD;
+ return true;
+ }
+
+ case IN_RECORD:
+ int p = start;
+ while (true) {
+ if (p >= end) {
+ int s = start;
+ eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return start < end;
+ }
+ p -= (s - start);
+ }
+ char ch = buffer[p];
+ if (ch == '\n') {
+ start = p + 1;
+ state = State.EOR;
+ break;
+ } else if (ch == '\r') {
+ start = p + 1;
+ state = State.CR;
+ break;
+ }
+ ++p;
+ }
+ break;
+
+ case CR:
+ if (start >= end) {
+ eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return false;
+ }
+ }
+ char ch = buffer[start];
+ if (ch == '\n') {
+ ++start;
+ state = State.EOR;
+ } else {
+ state = State.IN_RECORD;
+ return true;
+ }
+
+ case EOR:
+ if (start >= end) {
+ eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return false;
+ }
+ }
+ state = State.IN_RECORD;
+ return start < end;
+
+ case EOF:
+ return false;
+ }
+ }
+ }
+
+ public boolean nextField() throws IOException {
+ switch (state) {
+ case INIT:
+ case EOR:
+ case EOF:
+ case CR:
+ return false;
+
+ case IN_RECORD:
+ boolean eof;
+ int p = start;
+ while (true) {
+ if (p >= end) {
+ int s = start;
+ eof = !readMore();
+ if (eof) {
+ state = State.EOF;
+ return true;
+ }
+ p -= (s - start);
+ }
+ char ch = buffer[p];
+ if (ch == fieldDelimiter) {
+ fStart = start;
+ fEnd = p;
+ start = p + 1;
+ return true;
+ } else if (ch == '\n') {
+ fStart = start;
+ fEnd = p;
+ start = p + 1;
+ state = State.EOR;
+ return true;
+ } else if (ch == '\r') {
+ fStart = start;
+ fEnd = p;
+ start = p + 1;
+ state = State.CR;
+ return true;
+ }
+ ++p;
+ }
+ }
+ throw new IllegalStateException();
+ }
+
+ private boolean readMore() throws IOException {
+ if (start > 0) {
+ System.arraycopy(buffer, start, buffer, 0, end - start);
+ }
+ end -= start;
+ start = 0;
+
+ if (end == buffer.length) {
+ buffer = Arrays.copyOf(buffer, buffer.length + INCREMENT);
+ }
+
+ int n = in.read(buffer, end, buffer.length - end);
+ if (n < 0) {
+ return false;
+ }
+ end += n;
+ return true;
+ }
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/std/NoTupleSourceRuntimeFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/std/NoTupleSourceRuntimeFactory.java
new file mode 100644
index 0000000..11ea141
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/std/NoTupleSourceRuntimeFactory.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.runtime.operators.std;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IPushRuntime;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IPushRuntimeFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.context.RuntimeContext;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.operators.base.AbstractOneInputSourcePushRuntime;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+
+public class NoTupleSourceRuntimeFactory implements IPushRuntimeFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String toString() {
+ return "nts";
+ }
+
+ @Override
+ public IPushRuntime createPushRuntime(final RuntimeContext context) {
+ return new AbstractOneInputSourcePushRuntime() {
+
+ @Override
+ public void open() throws HyracksDataException {
+ writer.open();
+ writer.close();
+ }
+
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/runningaggregates/base/AbstractRunningAggregateFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/runningaggregates/base/AbstractRunningAggregateFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..c8f12f0
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/runningaggregates/base/AbstractRunningAggregateFunctionDynamicDescriptor.java
@@ -0,0 +1,13 @@
+package edu.uci.ics.asterix.runtime.runningaggregates.base;
+
+import edu.uci.ics.asterix.common.functions.FunctionDescriptorTag;
+import edu.uci.ics.asterix.runtime.base.IRunningAggregateFunctionDynamicDescriptor;
+
+public abstract class AbstractRunningAggregateFunctionDynamicDescriptor implements
+ IRunningAggregateFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ public FunctionDescriptorTag getFunctionDescriptorTag() {
+ return FunctionDescriptorTag.RUNNINGAGGREGATE;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/runningaggregates/std/TidRunningAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/runningaggregates/std/TidRunningAggregateDescriptor.java
new file mode 100644
index 0000000..34c6da9
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/runningaggregates/std/TidRunningAggregateDescriptor.java
@@ -0,0 +1,74 @@
+package edu.uci.ics.asterix.runtime.runningaggregates.std;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.runningaggregates.base.AbstractRunningAggregateFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IRunningAggregateFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IRunningAggregateFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class TidRunningAggregateDescriptor extends AbstractRunningAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "tid", 0, true);
+
+ @Override
+ public IRunningAggregateFunctionFactory createRunningAggregateFunctionFactory(IEvaluatorFactory[] args)
+ throws AlgebricksException {
+
+ return new IRunningAggregateFunctionFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public IRunningAggregateFunction createRunningAggregateFunction(IDataOutputProvider provider)
+ throws AlgebricksException {
+
+ final DataOutput out = provider.getDataOutput();
+
+ return new IRunningAggregateFunction() {
+
+ int cnt;
+ ISerializerDeserializer<AInt32> serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ AMutableInt32 m = new AMutableInt32(0);
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ m.setValue(cnt);
+ serde.serialize(m, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+
+ ++cnt;
+ }
+
+ @Override
+ public void init() throws AlgebricksException {
+ cnt = 0;
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/base/AbstractUnnestingFunctionDynamicDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/base/AbstractUnnestingFunctionDynamicDescriptor.java
new file mode 100644
index 0000000..52a44ae
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/base/AbstractUnnestingFunctionDynamicDescriptor.java
@@ -0,0 +1,12 @@
+package edu.uci.ics.asterix.runtime.unnestingfunctions.base;
+
+import edu.uci.ics.asterix.common.functions.FunctionDescriptorTag;
+import edu.uci.ics.asterix.runtime.base.IUnnestingFunctionDynamicDescriptor;
+
+public abstract class AbstractUnnestingFunctionDynamicDescriptor implements IUnnestingFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ public FunctionDescriptorTag getFunctionDescriptorTag() {
+ return FunctionDescriptorTag.UNNEST;
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/RangeDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/RangeDescriptor.java
new file mode 100644
index 0000000..1865017
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/RangeDescriptor.java
@@ -0,0 +1,88 @@
+package edu.uci.ics.asterix.runtime.unnestingfunctions.std;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.unnestingfunctions.base.AbstractUnnestingFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IUnnestingFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IUnnestingFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class RangeDescriptor extends AbstractUnnestingFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "range", 2, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IUnnestingFunctionFactory createUnnestingFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IUnnestingFunctionFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IUnnestingFunction createUnnestingFunction(final IDataOutputProvider provider)
+ throws AlgebricksException {
+ return new IUnnestingFunction() {
+
+ private DataOutput out = provider.getDataOutput();
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator eval0 = args[0].createEvaluator(inputVal);
+ private IEvaluator eval1 = args[1].createEvaluator(inputVal);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+ private int current;
+ private int max;
+
+ @Override
+ public void init(IFrameTupleReference tuple) throws AlgebricksException {
+ inputVal.reset();
+ eval0.evaluate(tuple);
+ current = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ inputVal.reset();
+ eval1.evaluate(tuple);
+ max = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean step() throws AlgebricksException {
+ if (current > max) {
+ return false;
+ }
+ aInt32.setValue(current);
+ try {
+ serde.serialize(aInt32, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ current++;
+ return true;
+ }
+
+ };
+ }
+ };
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/ScanCollectionDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/ScanCollectionDescriptor.java
new file mode 100644
index 0000000..a325d96
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/ScanCollectionDescriptor.java
@@ -0,0 +1,151 @@
+package edu.uci.ics.asterix.runtime.unnestingfunctions.std;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AUnorderedListSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.unnestingfunctions.base.AbstractUnnestingFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IUnnestingFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IUnnestingFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ScanCollectionDescriptor extends AbstractUnnestingFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "scan-collection", 1, true);
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+ @Override
+ public IUnnestingFunctionFactory createUnnestingFunctionFactory(final IEvaluatorFactory[] args) {
+ return new ScanCollectionUnnestingFunctionFactory(args[0]);
+ }
+
+ private static class ScanCollectionUnnestingFunctionFactory implements IUnnestingFunctionFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ private IEvaluatorFactory listEvalFactory;
+ private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+ private final static byte SER_UNORDEREDLIST_TYPE_TAG = ATypeTag.UNORDEREDLIST.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private ATypeTag itemTag;
+ private byte serItemTypeTag;
+ private boolean selfDescList = false;
+
+ public ScanCollectionUnnestingFunctionFactory(IEvaluatorFactory arg) {
+ this.listEvalFactory = arg;
+ }
+
+ @Override
+ public IUnnestingFunction createUnnestingFunction(IDataOutputProvider provider) throws AlgebricksException {
+
+ final DataOutput out = provider.getDataOutput();
+
+ return new IUnnestingFunction() {
+
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator argEval = listEvalFactory.createEvaluator(inputVal);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private int numItems;
+ private int pos;
+ private int itemOffset;
+ private int itemLength;
+ private byte serListTag;
+
+ @Override
+ public void init(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ inputVal.reset();
+ argEval.evaluate(tuple);
+ byte[] serList = inputVal.getBytes();
+
+ if (serList[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (serList[0] != SER_ORDEREDLIST_TYPE_TAG && serList[0] != SER_UNORDEREDLIST_TYPE_TAG) {
+ throw new AlgebricksException("Scan collection is not defined for values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[0]));
+ }
+
+ serListTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(inputVal.getBytes()[0])
+ .serialize();
+ if (serListTag == SER_ORDEREDLIST_TYPE_TAG)
+ numItems = AOrderedListSerializerDeserializer.getNumberOfItems(inputVal.getBytes());
+ else
+ numItems = AUnorderedListSerializerDeserializer.getNumberOfItems(inputVal.getBytes());
+
+ itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[1]);
+ if (itemTag == ATypeTag.ANY)
+ selfDescList = true;
+ else
+ serItemTypeTag = serList[1];
+
+ pos = 0;
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public boolean step() throws AlgebricksException {
+
+ try {
+ if (pos < numItems) {
+ byte[] serList = inputVal.getBytes();
+
+ try {
+ if (serListTag == SER_ORDEREDLIST_TYPE_TAG) {
+ itemOffset = AOrderedListSerializerDeserializer.getItemOffset(serList, pos);
+ } else {
+ itemOffset = AUnorderedListSerializerDeserializer.getItemOffset(serList, pos);
+ }
+ if (selfDescList)
+ itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[itemOffset]);
+ itemLength = NonTaggedFormatUtil.getFieldValueLength(serList, itemOffset, itemTag,
+ selfDescList);
+ if (!selfDescList)
+ out.writeByte(serItemTypeTag);
+ out.write(serList, itemOffset, itemLength + (!selfDescList ? 0 : 1));
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ ++pos;
+ return true;
+ } else
+ return false;
+
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ };
+ }
+
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/SubsetCollectionDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/SubsetCollectionDescriptor.java
new file mode 100644
index 0000000..9ca8512
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/unnestingfunctions/std/SubsetCollectionDescriptor.java
@@ -0,0 +1,139 @@
+package edu.uci.ics.asterix.runtime.unnestingfunctions.std;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AUnorderedListSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.unnestingfunctions.base.AbstractUnnestingFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IUnnestingFunction;
+import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IUnnestingFunctionFactory;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IDataOutputProvider;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
+
+public class SubsetCollectionDescriptor extends AbstractUnnestingFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "subset-collection", 3, true);
+
+ private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+ private final static byte SER_UNORDEREDLIST_TYPE_TAG = ATypeTag.UNORDEREDLIST.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+ @Override
+ public IUnnestingFunctionFactory createUnnestingFunctionFactory(final IEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IUnnestingFunctionFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IUnnestingFunction createUnnestingFunction(IDataOutputProvider provider) throws AlgebricksException {
+
+ final DataOutput out = provider.getDataOutput();
+
+ return new IUnnestingFunction() {
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+ private IEvaluator evalList = args[0].createEvaluator(inputVal);
+ private IEvaluator evalStart = args[1].createEvaluator(inputVal);
+ private IEvaluator evalLen = args[2].createEvaluator(inputVal);
+ private int numItems;
+ private int numItemsMax;
+ private int posStart;
+ private int posCrt;
+ private ATypeTag itemTag;
+ private boolean selfDescList = false;
+
+ @Override
+ public void init(IFrameTupleReference tuple) throws AlgebricksException {
+ try {
+ inputVal.reset();
+ evalStart.evaluate(tuple);
+ posStart = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ inputVal.reset();
+ evalLen.evaluate(tuple);
+ numItems = IntegerSerializerDeserializer.getInt(inputVal.getBytes(), 1);
+
+ inputVal.reset();
+ evalList.evaluate(tuple);
+
+ byte[] serList = inputVal.getBytes();
+
+ if (serList[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (serList[0] != SER_ORDEREDLIST_TYPE_TAG && serList[0] != SER_UNORDEREDLIST_TYPE_TAG) {
+ throw new AlgebricksException("Subset-collection is not defined for values of type"
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[0]));
+ }
+ if (serList[0] == SER_ORDEREDLIST_TYPE_TAG)
+ numItemsMax = AOrderedListSerializerDeserializer.getNumberOfItems(serList);
+ else
+ numItemsMax = AUnorderedListSerializerDeserializer.getNumberOfItems(serList);
+
+ itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[1]);
+ if (itemTag == ATypeTag.ANY)
+ selfDescList = true;
+
+ posCrt = posStart;
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public boolean step() throws AlgebricksException {
+ if (posCrt < posStart + numItems && posCrt < numItemsMax) {
+ byte[] serList = inputVal.getBytes();
+ int itemLength = 0;
+ try {
+ int itemOffset = AOrderedListSerializerDeserializer.getItemOffset(serList, posCrt);
+ if (selfDescList)
+ itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serList[itemOffset]);
+ itemLength = NonTaggedFormatUtil.getFieldValueLength(serList, itemOffset, itemTag,
+ selfDescList);
+ if (!selfDescList)
+ out.writeByte(itemTag.serialize());
+ out.write(serList, itemOffset, itemLength + (!selfDescList ? 0 : 1));
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ ++posCrt;
+ return true;
+ }
+ return false;
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/javacc/AdmLexer.jj b/asterix-runtime/src/main/javacc/AdmLexer.jj
new file mode 100644
index 0000000..fbab62f
--- /dev/null
+++ b/asterix-runtime/src/main/javacc/AdmLexer.jj
@@ -0,0 +1,150 @@
+options {
+
+
+ STATIC = false;
+
+}
+
+PARSER_BEGIN(AdmLexer)
+
+package edu.uci.ics.asterix.adm.parser;
+
+import java.io.*;
+
+public class AdmLexer {
+
+ public static void main(String args[]) throws ParseException, TokenMgrError, IOException, FileNotFoundException {
+ File file = new File(args[0]);
+ Reader freader = new BufferedReader(new InputStreamReader
+ (new FileInputStream(file), "UTF-8"));
+ AdmLexer flexer = new AdmLexer(freader);
+ Token t = null;
+ do {
+ t = flexer.next();
+ System.out.println(AdmLexerConstants.tokenImage[t.kind]);
+ } while (t.kind != EOF);
+ freader.close();
+ }
+
+ public Token next() throws ParseException {
+ return getNextToken();
+ }
+
+ public String tokenKindToString(int tokenKind) {
+ return AdmLexerConstants.tokenImage[tokenKind];
+ }
+}
+
+PARSER_END(AdmLexer)
+
+<DEFAULT>
+TOKEN :
+{
+ <NULL_LITERAL : "null">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <TRUE_LITERAL : "true">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <FALSE_LITERAL : "false">
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+ <INTEGER_LITERAL : ("-")? (<DIGIT>)+ >
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+ <#DIGIT : ["0" - "9"]>
+}
+
+
+TOKEN:
+{
+ < DOUBLE_LITERAL:
+ ("-")? <INTEGER> ( "." <INTEGER> )? (<EXPONENT>)?
+ | ("-")? "." <INTEGER>
+ >
+ | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+ | <INTEGER : (<DIGIT>)+ >
+ | <FLOAT_LITERAL: <DOUBLE_LITERAL>("f"|"F")>
+ }
+
+<DEFAULT>
+TOKEN :
+{
+ <STRING_LITERAL : ("\"" (<EscapeQuot> | ~["\""])* "\"") >
+ |
+ < #EscapeQuot: "\\\"" >
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <START_RECORD : "{">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <END_RECORD : "}">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <COMMA : ",">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <COLON : ":">
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+ <START_ORDERED_LIST : "[">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <END_ORDERED_LIST : "]">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <START_UNORDERED_LIST : "{{">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <END_UNORDERED_LIST : "}}">
+}
+
+
+
+
+SKIP:
+{
+ " "
+| "\t"
+| "\r"
+| "\n"
+}
diff --git a/asterix-runtime/src/main/javacc/nontagged/AdmLexer.jj b/asterix-runtime/src/main/javacc/nontagged/AdmLexer.jj
new file mode 100644
index 0000000..f556d54
--- /dev/null
+++ b/asterix-runtime/src/main/javacc/nontagged/AdmLexer.jj
@@ -0,0 +1,362 @@
+options {
+
+
+ STATIC = false;
+
+}
+
+PARSER_BEGIN(AdmLexer)
+
+package edu.uci.ics.asterix.adm.parser.nontagged;
+
+import java.io.*;
+
+public class AdmLexer {
+
+ public static void main(String args[]) throws ParseException, TokenMgrError, IOException, FileNotFoundException {
+ File file = new File(args[0]);
+ Reader freader = new BufferedReader(new InputStreamReader
+ (new FileInputStream(file), "UTF-8"));
+ AdmLexer flexer = new AdmLexer(freader);
+ Token t = null;
+ do {
+ t = flexer.next();
+ System.out.println(AdmLexerConstants.tokenImage[t.kind]);
+ } while (t.kind != EOF);
+ freader.close();
+ }
+
+ public Token next() throws ParseException {
+ return getNextToken();
+ }
+
+ public String tokenKindToString(int tokenKind) {
+ return AdmLexerConstants.tokenImage[tokenKind];
+ }
+}
+
+PARSER_END(AdmLexer)
+
+<DEFAULT>
+TOKEN :
+{
+ <NULL_LITERAL : "null">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <TRUE_LITERAL : "true">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <FALSE_LITERAL : "false">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <BOOLEAN_CONS : ("boolean") >
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <CONSTRUCTOR_OPEN : ("(")>
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+ <CONSTRUCTOR_CLOSE : (")")>
+}
+
+<DEFAULT>
+TOKEN:
+{
+ <INT8_LITERAL : ("-" | "+")? (<DIGIT>)+ ("i8")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <INT8_CONS : ("int8") >
+}
+
+<DEFAULT>
+TOKEN:
+{
+ <INT16_LITERAL : ("-" | "+")? (<DIGIT>)+ ("i16")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <INT16_CONS : ("int16") >
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <INT32_LITERAL : ("-" | "+")? (<DIGIT>)+ ("i32")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <INT32_CONS : ("int32")>
+}
+
+<DEFAULT>
+TOKEN:
+{
+ <INT64_LITERAL : ("-" | "+")? (<DIGIT>)+ ("i64")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <INT64_CONS : ("int64") >
+}
+
+<DEFAULT>
+TOKEN:
+{
+ <INT_LITERAL : ("-" | "+")? (<DIGIT>)+>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <CIRCLE_LITERAL : "P"<DOUBLE_LITERAL>(",") <DOUBLE_LITERAL> ("R") <DOUBLE_LITERAL> >
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <CIRCLE_CONS : ("circle") >
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+ <TIMEZONE_LITERAL : (("+"|"-")<INTEGER>(":")<INTEGER>) | ("Z") >
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <DATE_LITERAL : ("-")?<INTEGER>("-")<INTEGER>("-")<INTEGER> (<TIMEZONE_LITERAL>)? >
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <DATE_CONS : ("date")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <TIME_LITERAL : <INTEGER>(":")<INTEGER>(":")<INTEGER> ( (":")<INTEGER>)? (<TIMEZONE_LITERAL>)? >
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <TIME_CONS : ("time")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <DATETIME_LITERAL : ("-")? <INTEGER>("-")<INTEGER>("-")<INTEGER>("T")<INTEGER>(":")<INTEGER>(":")<INTEGER> ( (":")<INTEGER>)? (<TIMEZONE_LITERAL>)?>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <DATETIME_CONS : ("datetime")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <DURATION_LITERAL : ("-")? ("D")(<INTEGER>("Y"))?(<INTEGER>("M"))?(<INTEGER>("D"))?(("T")(<INTEGER>("H"))?(<INTEGER>("M"))?(<INTEGER>("S"))?)?>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <DURATION_CONS : ("duration")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <#DIGIT : ["0" - "9"]>
+}
+
+TOKEN:
+{
+ < DOUBLE_LITERAL:
+ ("-" | "+")? <INTEGER> ( "." <INTEGER> )? (<EXPONENT>)?
+ | ("-" | "+")? "." <INTEGER>
+ >
+ | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+ | <INTEGER : (<DIGIT>)+ >
+ | <FLOAT_LITERAL: <DOUBLE_LITERAL>("f"|"F")>
+ }
+
+
+<DEFAULT>
+TOKEN :
+{
+ <FLOAT_CONS : ("float")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <DOUBLE_CONS : ("double")>
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+ <STRING_LITERAL : ("\"" (<EscapeQuot> | ~["\""])* "\"") >
+ |
+ < #EscapeQuot: "\\\"" >
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <STRING_CONS : ("string")>
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+ <POINT_LITERAL : "P"<DOUBLE_LITERAL>(",")<DOUBLE_LITERAL>>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <POINT_CONS : ("point")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <POINT3D_LITERAL : "P" <DOUBLE_LITERAL>(",") <DOUBLE_LITERAL> (",") <DOUBLE_LITERAL>>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <POINT3D_CONS : ("point3d")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <LINE_LITERAL : "P"<DOUBLE_LITERAL>(",") <DOUBLE_LITERAL> ("P") <DOUBLE_LITERAL> (",") <DOUBLE_LITERAL>>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <LINE_CONS : ("line")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <POLYGON_LITERAL : "P"<DOUBLE_LITERAL>(",") <DOUBLE_LITERAL> ("P") <DOUBLE_LITERAL> (",") <DOUBLE_LITERAL> (("P") <DOUBLE_LITERAL> (",") <DOUBLE_LITERAL>)+>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <POLYGON_CONS : ("polygon")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <RECTANGLE_CONS : ("rectangle")>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <RECTANGLE_LITERAL : "P"<DOUBLE_LITERAL>(",") <DOUBLE_LITERAL> ("P") <DOUBLE_LITERAL> (",") <DOUBLE_LITERAL>>
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <START_RECORD : "{">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <END_RECORD : "}">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <COMMA : ",">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <COLON : ":">
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+ <START_ORDERED_LIST : "[">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <END_ORDERED_LIST : "]">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <START_UNORDERED_LIST : "{{">
+}
+
+<DEFAULT>
+TOKEN :
+{
+ <END_UNORDERED_LIST : "}}">
+}
+
+
+
+
+SKIP:
+{
+ " "
+| "\t"
+| "\r"
+| "\n"
+}