diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java
index 47e957b..bc61c49 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java
@@ -28,6 +28,7 @@
 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.AqlBinaryHashFunctionFamilyProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlBinaryIntegerInspector;
 import edu.uci.ics.asterix.formats.nontagged.AqlPrinterFactoryProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
@@ -106,8 +107,8 @@
 
     private static final JobGenContext _jobGenCtx = new JobGenContext(null, null, null,
             AqlSerializerDeserializerProvider.INSTANCE, AqlBinaryHashFunctionFactoryProvider.INSTANCE,
-            AqlBinaryComparatorFactoryProvider.INSTANCE, AqlTypeTraitProvider.INSTANCE,
-            AqlBinaryBooleanInspectorImpl.FACTORY, AqlBinaryIntegerInspector.FACTORY,
+            AqlBinaryHashFunctionFamilyProvider.INSTANCE, AqlBinaryComparatorFactoryProvider.INSTANCE,
+            AqlTypeTraitProvider.INSTANCE, AqlBinaryBooleanInspectorImpl.FACTORY, AqlBinaryIntegerInspector.FACTORY,
             AqlPrinterFactoryProvider.INSTANCE, AqlNullWriterFactory.INSTANCE, null,
             new LogicalExpressionJobGenToExpressionRuntimeProviderAdapter(AqlLogicalExpressionJobGen.INSTANCE),
             AqlExpressionTypeComputer.INSTANCE, AqlNullableTypeComputer.INSTANCE, null, null, null,
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java b/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java
index 1aad2ec..c207153 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java
@@ -131,8 +131,9 @@
         HTML
     }
 
-    public static Pair<Query, Integer> reWriteQuery(List<FunctionDecl> declaredFunctions, AqlMetadataProvider metadataProvider,
-            Query q, SessionConfig pc, PrintWriter out, DisplayFormat pdf) throws AsterixException {
+    public static Pair<Query, Integer> reWriteQuery(List<FunctionDecl> declaredFunctions,
+            AqlMetadataProvider metadataProvider, Query q, SessionConfig pc, PrintWriter out, DisplayFormat pdf)
+            throws AsterixException {
         if (!pc.isPrintPhysicalOpsOnly() && pc.isPrintExprParam()) {
             out.println();
             switch (pdf) {
@@ -261,7 +262,7 @@
 
         OptimizationConfUtil.getPhysicalOptimizationConfig().setFrameSize(frameSize);
         builder.setPhysicalOptimizationConfig(OptimizationConfUtil.getPhysicalOptimizationConfig());
-        
+
         ICompiler compiler = compilerFactory.createCompiler(plan, queryMetadataProvider, t.getVarCounter());
         if (pc.isOptimize()) {
             compiler.optimize();
@@ -310,6 +311,7 @@
         builder.setExpressionRuntimeProvider(new LogicalExpressionJobGenToExpressionRuntimeProviderAdapter(
                 AqlLogicalExpressionJobGen.INSTANCE));
         builder.setHashFunctionFactoryProvider(format.getBinaryHashFunctionFactoryProvider());
+        builder.setHashFunctionFamilyProvider(format.getBinaryHashFunctionFamilyProvider());
         builder.setNullWriterFactory(format.getNullWriterFactory());
         builder.setPrinterProvider(format.getPrinterFactoryProvider());
         builder.setSerializerDeserializerProvider(format.getSerdeProvider());
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java
index c1df096..813c3a0 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java
@@ -14,6 +14,7 @@
 import edu.uci.ics.hyracks.algebricks.data.IBinaryBooleanInspectorFactory;
 import edu.uci.ics.hyracks.algebricks.data.IBinaryComparatorFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.data.IBinaryHashFunctionFactoryProvider;
+import edu.uci.ics.hyracks.algebricks.data.IBinaryHashFunctionFamilyProvider;
 import edu.uci.ics.hyracks.algebricks.data.IBinaryIntegerInspectorFactory;
 import edu.uci.ics.hyracks.algebricks.data.INormalizedKeyComputerFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.data.IPrinterFactoryProvider;
@@ -63,4 +64,6 @@
     public IExpressionEvalSizeComputer getExpressionEvalSizeComputer();
 
     public INormalizedKeyComputerFactoryProvider getNormalizedKeyComputerFactoryProvider();
+
+    public IBinaryHashFunctionFamilyProvider getBinaryHashFunctionFamilyProvider();
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
index e4db8da..09c99b8 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
@@ -19,8 +19,8 @@
 import edu.uci.ics.hyracks.data.std.primitive.FloatPointable;
 import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
 import edu.uci.ics.hyracks.data.std.primitive.LongPointable;
+import edu.uci.ics.hyracks.data.std.primitive.RawUTF8StringPointable;
 import edu.uci.ics.hyracks.data.std.primitive.ShortPointable;
-import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
 
 public class AqlBinaryComparatorFactoryProvider implements IBinaryComparatorFactoryProvider, Serializable {
 
@@ -39,7 +39,7 @@
     public static final PointableBinaryComparatorFactory DOUBLE_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
             DoublePointable.FACTORY);
     public static final PointableBinaryComparatorFactory UTF8STRING_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
-            UTF8StringPointable.FACTORY);
+            RawUTF8StringPointable.FACTORY);
     // Equivalent to UTF8STRING_POINTABLE_INSTANCE but all characters are considered lower case to implement case-insensitive comparisons.    
     public static final PointableBinaryComparatorFactory UTF8STRING_LOWERCASE_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
             UTF8StringLowercasePointable.FACTORY);
@@ -64,11 +64,11 @@
     public IBinaryComparatorFactory getBinaryComparatorFactory(Object type, boolean ascending) {
         if (type == null) {
             return anyBinaryComparatorFactory(ascending);
-        }        
+        }
         IAType aqlType = (IAType) type;
         return getBinaryComparatorFactory(aqlType.getTypeTag(), ascending);
     }
-    
+
     public IBinaryComparatorFactory getBinaryComparatorFactory(ATypeTag type, boolean ascending) {
         switch (type) {
             case ANY:
@@ -125,8 +125,7 @@
                 return addOffset(ADateTimeAscBinaryComparatorFactory.INSTANCE, ascending);
             }
             default: {
-                throw new NotImplementedException("No binary comparator factory implemented for type "
-                        + type + " .");
+                throw new NotImplementedException("No binary comparator factory implemented for type " + type + " .");
             }
         }
     }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFactoryProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFactoryProvider.java
index cab8ded..1afdbf8 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFactoryProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFactoryProvider.java
@@ -16,20 +16,25 @@
 import edu.uci.ics.hyracks.data.std.primitive.DoublePointable;
 import edu.uci.ics.hyracks.data.std.primitive.FloatPointable;
 import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
+import edu.uci.ics.hyracks.data.std.primitive.RawUTF8StringPointable;
 import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
 
-
 public class AqlBinaryHashFunctionFactoryProvider implements IBinaryHashFunctionFactoryProvider, Serializable {
 
     private static final long serialVersionUID = 1L;
     public static final AqlBinaryHashFunctionFactoryProvider INSTANCE = new AqlBinaryHashFunctionFactoryProvider();
-    public static final PointableBinaryHashFunctionFactory INTEGER_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(IntegerPointable.FACTORY);
-    public static final PointableBinaryHashFunctionFactory FLOAT_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(FloatPointable.FACTORY);
-    public static final PointableBinaryHashFunctionFactory DOUBLE_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(DoublePointable.FACTORY);
-    public static final PointableBinaryHashFunctionFactory UTF8STRING_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(UTF8StringPointable.FACTORY);
+    public static final PointableBinaryHashFunctionFactory INTEGER_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+            IntegerPointable.FACTORY);
+    public static final PointableBinaryHashFunctionFactory FLOAT_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+            FloatPointable.FACTORY);
+    public static final PointableBinaryHashFunctionFactory DOUBLE_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+            DoublePointable.FACTORY);
+    public static final PointableBinaryHashFunctionFactory UTF8STRING_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+            RawUTF8StringPointable.FACTORY);
     // Equivalent to UTF8STRING_POINTABLE_INSTANCE but all characters are considered lower case to implement case-insensitive hashing.    
-    public static final PointableBinaryHashFunctionFactory UTF8STRING_LOWERCASE_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(UTF8StringLowercasePointable.FACTORY);
-    
+    public static final PointableBinaryHashFunctionFactory UTF8STRING_LOWERCASE_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+            UTF8StringLowercasePointable.FACTORY);
+
     private AqlBinaryHashFunctionFactoryProvider() {
     }
 
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFamilyProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFamilyProvider.java
new file mode 100644
index 0000000..37d7ac6
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFamilyProvider.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2009-2010 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.formats.nontagged;
+
+import java.io.Serializable;
+
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IBinaryHashFunctionFamilyProvider;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunctionFamily;
+import edu.uci.ics.hyracks.data.std.accessors.MurmurHash3BinaryHashFunctionFamily;
+
+/**
+ * We use a type-independent binary hash function family from the hyracks codebase
+ */
+public class AqlBinaryHashFunctionFamilyProvider implements IBinaryHashFunctionFamilyProvider, Serializable {
+
+    private static final long serialVersionUID = 1L;
+    public static final AqlBinaryHashFunctionFamilyProvider INSTANCE = new AqlBinaryHashFunctionFamilyProvider();
+
+    private AqlBinaryHashFunctionFamilyProvider() {
+
+    }
+
+    @Override
+    public IBinaryHashFunctionFamily getBinaryHashFunctionFamily(Object type) throws AlgebricksException {
+        return new MurmurHash3BinaryHashFunctionFamily();
+    }
+
+}
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
index 92d4294..9e5ae39 100644
--- 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
@@ -17,6 +17,7 @@
 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.AqlBinaryHashFunctionFamilyProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlBinaryIntegerInspector;
 import edu.uci.ics.asterix.formats.nontagged.AqlNormalizedKeyComputerFactoryProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlPrinterFactoryProvider;
@@ -197,6 +198,7 @@
 import edu.uci.ics.hyracks.algebricks.data.IBinaryBooleanInspectorFactory;
 import edu.uci.ics.hyracks.algebricks.data.IBinaryComparatorFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.data.IBinaryHashFunctionFactoryProvider;
+import edu.uci.ics.hyracks.algebricks.data.IBinaryHashFunctionFamilyProvider;
 import edu.uci.ics.hyracks.algebricks.data.IBinaryIntegerInspectorFactory;
 import edu.uci.ics.hyracks.algebricks.data.INormalizedKeyComputerFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.data.IPrinterFactoryProvider;
@@ -218,564 +220,627 @@
 
 public class NonTaggedDataFormat implements IDataFormat {
 
-    private static boolean registered = false;
+	private static boolean registered = false;
 
-    public static final NonTaggedDataFormat INSTANCE = new NonTaggedDataFormat();
+	public static final NonTaggedDataFormat INSTANCE = new NonTaggedDataFormat();
 
-    private static LogicalVariable METADATA_DUMMY_VAR = new LogicalVariable(-1);
+	private static LogicalVariable METADATA_DUMMY_VAR = new LogicalVariable(-1);
 
-    private static final HashMap<ATypeTag, IValueParserFactory> typeToValueParserFactMap = new HashMap<ATypeTag, IValueParserFactory>();
+	private static final HashMap<ATypeTag, IValueParserFactory> typeToValueParserFactMap = new HashMap<ATypeTag, IValueParserFactory>();
 
-    public static final String NON_TAGGED_DATA_FORMAT = "edu.uci.ics.asterix.runtime.formats.NonTaggedDataFormat";
+	public static final String NON_TAGGED_DATA_FORMAT = "edu.uci.ics.asterix.runtime.formats.NonTaggedDataFormat";
 
-    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);
-    }
+	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 NonTaggedDataFormat() {
+	}
 
-    public void registerRuntimeFunctions() throws AlgebricksException {
+	public void registerRuntimeFunctions() throws AlgebricksException {
 
-        if (registered) {
-            return;
-        }
-        registered = true;
+		if (registered) {
+			return;
+		}
+		registered = true;
 
-        if (FunctionManagerHolder.getFunctionManager() != null) {
-            return;
-        }
+		if (FunctionManagerHolder.getFunctionManager() != null) {
+			return;
+		}
 
-        List<IFunctionDescriptorFactory> temp = new ArrayList<IFunctionDescriptorFactory>();
+		List<IFunctionDescriptorFactory> temp = new ArrayList<IFunctionDescriptorFactory>();
 
-        // format-independent
-        temp.add(ContainsDescriptor.FACTORY);
-        temp.add(EndsWithDescriptor.FACTORY);
-        temp.add(StartsWithDescriptor.FACTORY);
-        temp.add(SubstringDescriptor.FACTORY);
-        temp.add(TidRunningAggregateDescriptor.FACTORY);
+		// format-independent
+		temp.add(ContainsDescriptor.FACTORY);
+		temp.add(EndsWithDescriptor.FACTORY);
+		temp.add(StartsWithDescriptor.FACTORY);
+		temp.add(SubstringDescriptor.FACTORY);
+		temp.add(TidRunningAggregateDescriptor.FACTORY);
 
-        // format-dependent
-        temp.add(AndDescriptor.FACTORY);
-        temp.add(OrDescriptor.FACTORY);
-        temp.add(LikeDescriptor.FACTORY);
-        temp.add(YearDescriptor.FACTORY);
-        temp.add(ScanCollectionDescriptor.FACTORY);
-        temp.add(AnyCollectionMemberDescriptor.FACTORY);
-        temp.add(ClosedRecordConstructorDescriptor.FACTORY);
-        temp.add(FieldAccessByIndexDescriptor.FACTORY);
-        temp.add(FieldAccessByNameDescriptor.FACTORY);
-        temp.add(GetItemDescriptor.FACTORY);
-        temp.add(NumericUnaryMinusDescriptor.FACTORY);
-        temp.add(OpenRecordConstructorDescriptor.FACTORY);
-        temp.add(OrderedListConstructorDescriptor.FACTORY);
-        temp.add(UnorderedListConstructorDescriptor.FACTORY);
-        temp.add(EmbedTypeDescriptor.FACTORY);
+		// format-dependent
+		temp.add(AndDescriptor.FACTORY);
+		temp.add(OrDescriptor.FACTORY);
+		temp.add(LikeDescriptor.FACTORY);
+		temp.add(YearDescriptor.FACTORY);
+		temp.add(ScanCollectionDescriptor.FACTORY);
+		temp.add(AnyCollectionMemberDescriptor.FACTORY);
+		temp.add(ClosedRecordConstructorDescriptor.FACTORY);
+		temp.add(FieldAccessByIndexDescriptor.FACTORY);
+		temp.add(FieldAccessByNameDescriptor.FACTORY);
+		temp.add(GetItemDescriptor.FACTORY);
+		temp.add(NumericUnaryMinusDescriptor.FACTORY);
+		temp.add(OpenRecordConstructorDescriptor.FACTORY);
+		temp.add(OrderedListConstructorDescriptor.FACTORY);
+		temp.add(UnorderedListConstructorDescriptor.FACTORY);
+		temp.add(EmbedTypeDescriptor.FACTORY);
 
-        temp.add(NumericAddDescriptor.FACTORY);
-        temp.add(NumericDivideDescriptor.FACTORY);
-        temp.add(NumericMultiplyDescriptor.FACTORY);
-        temp.add(NumericSubtractDescriptor.FACTORY);
-        temp.add(NumericModuloDescriptor.FACTORY);
-        temp.add(IsNullDescriptor.FACTORY);
-        temp.add(NotDescriptor.FACTORY);
-        temp.add(LenDescriptor.FACTORY);
-        temp.add(EmptyStreamAggregateDescriptor.FACTORY);
-        temp.add(NonEmptyStreamAggregateDescriptor.FACTORY);
-        temp.add(RangeDescriptor.FACTORY);
+		temp.add(NumericAddDescriptor.FACTORY);
+		temp.add(NumericDivideDescriptor.FACTORY);
+		temp.add(NumericMultiplyDescriptor.FACTORY);
+		temp.add(NumericSubtractDescriptor.FACTORY);
+		temp.add(NumericModuloDescriptor.FACTORY);
+		temp.add(IsNullDescriptor.FACTORY);
+		temp.add(NotDescriptor.FACTORY);
+		temp.add(LenDescriptor.FACTORY);
+		temp.add(EmptyStreamAggregateDescriptor.FACTORY);
+		temp.add(NonEmptyStreamAggregateDescriptor.FACTORY);
+		temp.add(RangeDescriptor.FACTORY);
 
-        temp.add(NumericAbsDescriptor.FACTORY);
-        temp.add(NumericCeilingDescriptor.FACTORY);
-        temp.add(NumericFloorDescriptor.FACTORY);
-        temp.add(NumericRoundDescriptor.FACTORY);
-        temp.add(NumericRoundHalfToEvenDescriptor.FACTORY);
-        temp.add(NumericRoundHalfToEven2Descriptor.FACTORY);
-        // String functions
-        temp.add(StringEqualDescriptor.FACTORY);
-        temp.add(StringStartWithDescrtiptor.FACTORY);
-        temp.add(StringEndWithDescrtiptor.FACTORY);
-        temp.add(StringMatchesDescriptor.FACTORY);
-        temp.add(StringLowerCaseDescriptor.FACTORY);
-        temp.add(StringMatchesWithFlagDescriptor.FACTORY);
-        temp.add(StringReplaceDescriptor.FACTORY);
-        temp.add(StringReplaceWithFlagsDescriptor.FACTORY);
-        temp.add(StringLengthDescriptor.FACTORY);
-        temp.add(Substring2Descriptor.FACTORY);
-        temp.add(SubstringBeforeDescriptor.FACTORY);
-        temp.add(SubstringAfterDescriptor.FACTORY);
-        temp.add(StringToCodePointDescriptor.FACTORY);
-        temp.add(CodePointToStringDescriptor.FACTORY);
-        temp.add(StringConcatDescriptor.FACTORY);
-        temp.add(StringJoinDescriptor.FACTORY);
+		temp.add(NumericAbsDescriptor.FACTORY);
+		temp.add(NumericCeilingDescriptor.FACTORY);
+		temp.add(NumericFloorDescriptor.FACTORY);
+		temp.add(NumericRoundDescriptor.FACTORY);
+		temp.add(NumericRoundHalfToEvenDescriptor.FACTORY);
+		temp.add(NumericRoundHalfToEven2Descriptor.FACTORY);
+		// String functions
+		temp.add(StringEqualDescriptor.FACTORY);
+		temp.add(StringStartWithDescrtiptor.FACTORY);
+		temp.add(StringEndWithDescrtiptor.FACTORY);
+		temp.add(StringMatchesDescriptor.FACTORY);
+		temp.add(StringLowerCaseDescriptor.FACTORY);
+		temp.add(StringMatchesWithFlagDescriptor.FACTORY);
+		temp.add(StringReplaceDescriptor.FACTORY);
+		temp.add(StringReplaceWithFlagsDescriptor.FACTORY);
+		temp.add(StringLengthDescriptor.FACTORY);
+		temp.add(Substring2Descriptor.FACTORY);
+		temp.add(SubstringBeforeDescriptor.FACTORY);
+		temp.add(SubstringAfterDescriptor.FACTORY);
+		temp.add(StringToCodePointDescriptor.FACTORY);
+		temp.add(CodePointToStringDescriptor.FACTORY);
+		temp.add(StringConcatDescriptor.FACTORY);
+		temp.add(StringJoinDescriptor.FACTORY);
 
-        // aggregates
-        temp.add(ListifyAggregateDescriptor.FACTORY);
-        temp.add(CountAggregateDescriptor.FACTORY);
-        temp.add(AvgAggregateDescriptor.FACTORY);
-        temp.add(LocalAvgAggregateDescriptor.FACTORY);
-        temp.add(GlobalAvgAggregateDescriptor.FACTORY);
-        temp.add(SumAggregateDescriptor.FACTORY);
-        temp.add(LocalSumAggregateDescriptor.FACTORY);
-        temp.add(MaxAggregateDescriptor.FACTORY);
-        temp.add(LocalMaxAggregateDescriptor.FACTORY);
-        temp.add(MinAggregateDescriptor.FACTORY);
-        temp.add(LocalMinAggregateDescriptor.FACTORY);
+		// aggregates
+		temp.add(ListifyAggregateDescriptor.FACTORY);
+		temp.add(CountAggregateDescriptor.FACTORY);
+		temp.add(AvgAggregateDescriptor.FACTORY);
+		temp.add(LocalAvgAggregateDescriptor.FACTORY);
+		temp.add(GlobalAvgAggregateDescriptor.FACTORY);
+		temp.add(SumAggregateDescriptor.FACTORY);
+		temp.add(LocalSumAggregateDescriptor.FACTORY);
+		temp.add(MaxAggregateDescriptor.FACTORY);
+		temp.add(LocalMaxAggregateDescriptor.FACTORY);
+		temp.add(MinAggregateDescriptor.FACTORY);
+		temp.add(LocalMinAggregateDescriptor.FACTORY);
 
-        // serializable aggregates
-        temp.add(SerializableCountAggregateDescriptor.FACTORY);
-        temp.add(SerializableAvgAggregateDescriptor.FACTORY);
-        temp.add(SerializableLocalAvgAggregateDescriptor.FACTORY);
-        temp.add(SerializableGlobalAvgAggregateDescriptor.FACTORY);
-        temp.add(SerializableSumAggregateDescriptor.FACTORY);
-        temp.add(SerializableLocalSumAggregateDescriptor.FACTORY);
+		// serializable aggregates
+		temp.add(SerializableCountAggregateDescriptor.FACTORY);
+		temp.add(SerializableAvgAggregateDescriptor.FACTORY);
+		temp.add(SerializableLocalAvgAggregateDescriptor.FACTORY);
+		temp.add(SerializableGlobalAvgAggregateDescriptor.FACTORY);
+		temp.add(SerializableSumAggregateDescriptor.FACTORY);
+		temp.add(SerializableLocalSumAggregateDescriptor.FACTORY);
 
-        // scalar aggregates
-        temp.add(ScalarCountAggregateDescriptor.FACTORY);
-        temp.add(ScalarAvgAggregateDescriptor.FACTORY);
-        temp.add(ScalarSumAggregateDescriptor.FACTORY);
-        temp.add(ScalarMaxAggregateDescriptor.FACTORY);
-        temp.add(ScalarMinAggregateDescriptor.FACTORY);
+		// scalar aggregates
+		temp.add(ScalarCountAggregateDescriptor.FACTORY);
+		temp.add(ScalarAvgAggregateDescriptor.FACTORY);
+		temp.add(ScalarSumAggregateDescriptor.FACTORY);
+		temp.add(ScalarMaxAggregateDescriptor.FACTORY);
+		temp.add(ScalarMinAggregateDescriptor.FACTORY);
 
-        // new functions - constructors
-        temp.add(ABooleanConstructorDescriptor.FACTORY);
-        temp.add(ANullConstructorDescriptor.FACTORY);
-        temp.add(AStringConstructorDescriptor.FACTORY);
-        temp.add(AInt8ConstructorDescriptor.FACTORY);
-        temp.add(AInt16ConstructorDescriptor.FACTORY);
-        temp.add(AInt32ConstructorDescriptor.FACTORY);
-        temp.add(AInt64ConstructorDescriptor.FACTORY);
-        temp.add(AFloatConstructorDescriptor.FACTORY);
-        temp.add(ADoubleConstructorDescriptor.FACTORY);
-        temp.add(APointConstructorDescriptor.FACTORY);
-        temp.add(APoint3DConstructorDescriptor.FACTORY);
-        temp.add(ALineConstructorDescriptor.FACTORY);
-        temp.add(APolygonConstructorDescriptor.FACTORY);
-        temp.add(ACircleConstructorDescriptor.FACTORY);
-        temp.add(ARectangleConstructorDescriptor.FACTORY);
-        temp.add(ATimeConstructorDescriptor.FACTORY);
-        temp.add(ADateConstructorDescriptor.FACTORY);
-        temp.add(ADateTimeConstructorDescriptor.FACTORY);
-        temp.add(ADurationConstructorDescriptor.FACTORY);
+		// new functions - constructors
+		temp.add(ABooleanConstructorDescriptor.FACTORY);
+		temp.add(ANullConstructorDescriptor.FACTORY);
+		temp.add(AStringConstructorDescriptor.FACTORY);
+		temp.add(AInt8ConstructorDescriptor.FACTORY);
+		temp.add(AInt16ConstructorDescriptor.FACTORY);
+		temp.add(AInt32ConstructorDescriptor.FACTORY);
+		temp.add(AInt64ConstructorDescriptor.FACTORY);
+		temp.add(AFloatConstructorDescriptor.FACTORY);
+		temp.add(ADoubleConstructorDescriptor.FACTORY);
+		temp.add(APointConstructorDescriptor.FACTORY);
+		temp.add(APoint3DConstructorDescriptor.FACTORY);
+		temp.add(ALineConstructorDescriptor.FACTORY);
+		temp.add(APolygonConstructorDescriptor.FACTORY);
+		temp.add(ACircleConstructorDescriptor.FACTORY);
+		temp.add(ARectangleConstructorDescriptor.FACTORY);
+		temp.add(ATimeConstructorDescriptor.FACTORY);
+		temp.add(ADateConstructorDescriptor.FACTORY);
+		temp.add(ADateTimeConstructorDescriptor.FACTORY);
+		temp.add(ADurationConstructorDescriptor.FACTORY);
 
-        // Spatial
-        temp.add(CreatePointDescriptor.FACTORY);
-        temp.add(CreateLineDescriptor.FACTORY);
-        temp.add(CreatePolygonDescriptor.FACTORY);
-        temp.add(CreateCircleDescriptor.FACTORY);
-        temp.add(CreateRectangleDescriptor.FACTORY);
-        temp.add(SpatialAreaDescriptor.FACTORY);
-        temp.add(SpatialDistanceDescriptor.FACTORY);
-        temp.add(SpatialIntersectDescriptor.FACTORY);
-        temp.add(CreateMBRDescriptor.FACTORY);
-        temp.add(SpatialCellDescriptor.FACTORY);
-        temp.add(PointXCoordinateAccessor.FACTORY);
-        temp.add(PointYCoordinateAccessor.FACTORY);
-        temp.add(CircleRadiusAccessor.FACTORY);
-        temp.add(CircleCenterAccessor.FACTORY);
-        temp.add(LineRectanglePolygonAccessor.FACTORY);
+		// Spatial
+		temp.add(CreatePointDescriptor.FACTORY);
+		temp.add(CreateLineDescriptor.FACTORY);
+		temp.add(CreatePolygonDescriptor.FACTORY);
+		temp.add(CreateCircleDescriptor.FACTORY);
+		temp.add(CreateRectangleDescriptor.FACTORY);
+		temp.add(SpatialAreaDescriptor.FACTORY);
+		temp.add(SpatialDistanceDescriptor.FACTORY);
+		temp.add(SpatialIntersectDescriptor.FACTORY);
+		temp.add(CreateMBRDescriptor.FACTORY);
+		temp.add(SpatialCellDescriptor.FACTORY);
+		temp.add(PointXCoordinateAccessor.FACTORY);
+		temp.add(PointYCoordinateAccessor.FACTORY);
+		temp.add(CircleRadiusAccessor.FACTORY);
+		temp.add(CircleCenterAccessor.FACTORY);
+		temp.add(LineRectanglePolygonAccessor.FACTORY);
 
-        // fuzzyjoin function
-        temp.add(FuzzyEqDescriptor.FACTORY);
-        temp.add(SubsetCollectionDescriptor.FACTORY);
-        temp.add(PrefixLenJaccardDescriptor.FACTORY);
+		// fuzzyjoin function
+		temp.add(FuzzyEqDescriptor.FACTORY);
+		temp.add(SubsetCollectionDescriptor.FACTORY);
+		temp.add(PrefixLenJaccardDescriptor.FACTORY);
 
-        temp.add(WordTokensDescriptor.FACTORY);
-        temp.add(HashedWordTokensDescriptor.FACTORY);
-        temp.add(CountHashedWordTokensDescriptor.FACTORY);
+		temp.add(WordTokensDescriptor.FACTORY);
+		temp.add(HashedWordTokensDescriptor.FACTORY);
+		temp.add(CountHashedWordTokensDescriptor.FACTORY);
 
-        temp.add(GramTokensDescriptor.FACTORY);
-        temp.add(HashedGramTokensDescriptor.FACTORY);
-        temp.add(CountHashedGramTokensDescriptor.FACTORY);
+		temp.add(GramTokensDescriptor.FACTORY);
+		temp.add(HashedGramTokensDescriptor.FACTORY);
+		temp.add(CountHashedGramTokensDescriptor.FACTORY);
 
-        temp.add(EditDistanceDescriptor.FACTORY);
-        temp.add(EditDistanceCheckDescriptor.FACTORY);
-        temp.add(EditDistanceStringIsFilterable.FACTORY);
-        temp.add(EditDistanceListIsFilterable.FACTORY);
+		temp.add(EditDistanceDescriptor.FACTORY);
+		temp.add(EditDistanceCheckDescriptor.FACTORY);
+		temp.add(EditDistanceStringIsFilterable.FACTORY);
+		temp.add(EditDistanceListIsFilterable.FACTORY);
 
-        temp.add(SimilarityJaccardDescriptor.FACTORY);
-        temp.add(SimilarityJaccardCheckDescriptor.FACTORY);
-        temp.add(SimilarityJaccardSortedDescriptor.FACTORY);
-        temp.add(SimilarityJaccardSortedCheckDescriptor.FACTORY);
-        temp.add(SimilarityJaccardPrefixDescriptor.FACTORY);
-        temp.add(SimilarityJaccardPrefixCheckDescriptor.FACTORY);
+		temp.add(SimilarityJaccardDescriptor.FACTORY);
+		temp.add(SimilarityJaccardCheckDescriptor.FACTORY);
+		temp.add(SimilarityJaccardSortedDescriptor.FACTORY);
+		temp.add(SimilarityJaccardSortedCheckDescriptor.FACTORY);
+		temp.add(SimilarityJaccardPrefixDescriptor.FACTORY);
+		temp.add(SimilarityJaccardPrefixCheckDescriptor.FACTORY);
 
-        temp.add(SwitchCaseDescriptor.FACTORY);
-        temp.add(RegExpDescriptor.FACTORY);
-        temp.add(InjectFailureDescriptor.FACTORY);
-        temp.add(CastRecordDescriptor.FACTORY);
+		temp.add(SwitchCaseDescriptor.FACTORY);
+		temp.add(RegExpDescriptor.FACTORY);
+		temp.add(InjectFailureDescriptor.FACTORY);
+		temp.add(CastRecordDescriptor.FACTORY);
 
-        IFunctionManager mgr = new FunctionManagerImpl();
-        for (IFunctionDescriptorFactory fdFactory : temp) {
-            mgr.registerFunction(fdFactory);
-        }
-        FunctionManagerHolder.setFunctionManager(mgr);
-    }
+		IFunctionManager mgr = new FunctionManagerImpl();
+		for (IFunctionDescriptorFactory fdFactory : temp) {
+			mgr.registerFunction(fdFactory);
+		}
+		FunctionManagerHolder.setFunctionManager(mgr);
+	}
 
-    @Override
-    public IBinaryBooleanInspectorFactory getBinaryBooleanInspectorFactory() {
-        return AqlBinaryBooleanInspectorImpl.FACTORY;
-    }
+	@Override
+	public IBinaryBooleanInspectorFactory getBinaryBooleanInspectorFactory() {
+		return AqlBinaryBooleanInspectorImpl.FACTORY;
+	}
 
-    @Override
-    public IBinaryComparatorFactoryProvider getBinaryComparatorFactoryProvider() {
-        return AqlBinaryComparatorFactoryProvider.INSTANCE;
-    }
+	@Override
+	public IBinaryComparatorFactoryProvider getBinaryComparatorFactoryProvider() {
+		return AqlBinaryComparatorFactoryProvider.INSTANCE;
+	}
 
-    @Override
-    public IBinaryHashFunctionFactoryProvider getBinaryHashFunctionFactoryProvider() {
-        return AqlBinaryHashFunctionFactoryProvider.INSTANCE;
-    }
+	@Override
+	public IBinaryHashFunctionFactoryProvider getBinaryHashFunctionFactoryProvider() {
+		return AqlBinaryHashFunctionFactoryProvider.INSTANCE;
+	}
 
-    @Override
-    public ISerializerDeserializerProvider getSerdeProvider() {
-        return AqlSerializerDeserializerProvider.INSTANCE; // done
-    }
+	@Override
+	public ISerializerDeserializerProvider getSerdeProvider() {
+		return AqlSerializerDeserializerProvider.INSTANCE; // done
+	}
 
-    @Override
-    public ITypeTraitProvider getTypeTraitProvider() {
-        return AqlTypeTraitProvider.INSTANCE;
-    }
+	@Override
+	public ITypeTraitProvider getTypeTraitProvider() {
+		return AqlTypeTraitProvider.INSTANCE;
+	}
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public ICopyEvaluatorFactory 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)) {
-                ICopyEvaluatorFactory 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);
-                }
-                ICopyEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs.getByteArray(),
-                        abvs.getLength()));
-                ICopyEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory,
-                        fldIndexEvalFactory, recType);
-                return evalFactory;
-            }
-        }
-        throw new AlgebricksException("Could not find field " + fldName + " in the schema.");
-    }
+	@SuppressWarnings("unchecked")
+	@Override
+	public ICopyEvaluatorFactory 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)) {
+				ICopyEvaluatorFactory 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);
+				}
+				ICopyEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(
+						Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
+				ICopyEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(
+						recordEvalFactory, fldIndexEvalFactory, recType);
+				return evalFactory;
+			}
+		}
+		throw new AlgebricksException("Could not find field " + fldName
+				+ " in the schema.");
+	}
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public ICopyEvaluatorFactory[] createMBRFactory(ARecordType recType, String fldName, int recordColumn, int dimension)
-            throws AlgebricksException {
-        ICopyEvaluatorFactory evalFactory = getFieldAccessEvaluatorFactory(recType, fldName, recordColumn);
-        int numOfFields = dimension * 2;
-        ICopyEvaluatorFactory[] evalFactories = new ICopyEvaluatorFactory[numOfFields];
+	@SuppressWarnings("unchecked")
+	@Override
+	public ICopyEvaluatorFactory[] createMBRFactory(ARecordType recType,
+			String fldName, int recordColumn, int dimension)
+			throws AlgebricksException {
+		ICopyEvaluatorFactory evalFactory = getFieldAccessEvaluatorFactory(
+				recType, fldName, recordColumn);
+		int numOfFields = dimension * 2;
+		ICopyEvaluatorFactory[] evalFactories = new ICopyEvaluatorFactory[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);
-        }
-        ICopyEvaluatorFactory dimensionEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs1.getByteArray(),
-                abvs1.getLength()));
+		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);
+		}
+		ICopyEvaluatorFactory dimensionEvalFactory = new ConstantEvalFactory(
+				Arrays.copyOf(abvs1.getByteArray(), 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);
-            }
-            ICopyEvaluatorFactory coordinateEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs2.getByteArray(),
-                    abvs2.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);
+			}
+			ICopyEvaluatorFactory coordinateEvalFactory = new ConstantEvalFactory(
+					Arrays.copyOf(abvs2.getByteArray(), abvs2.getLength()));
 
-            evalFactories[i] = new CreateMBREvalFactory(evalFactory, dimensionEvalFactory, coordinateEvalFactory);
-        }
-        return evalFactories;
-    }
+			evalFactories[i] = new CreateMBREvalFactory(evalFactory,
+					dimensionEvalFactory, coordinateEvalFactory);
+		}
+		return evalFactories;
+	}
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public Triple<ICopyEvaluatorFactory, 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)) {
-                ICopyEvaluatorFactory 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);
-                }
-                ICopyEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs.getByteArray(),
-                        abvs.getLength()));
-                ICopyEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory,
-                        fldIndexEvalFactory, recType);
-                IFunctionInfo finfoAccess = AsterixBuiltinFunctions
-                        .getAsterixFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX);
+	@SuppressWarnings("unchecked")
+	@Override
+	public Triple<ICopyEvaluatorFactory, 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)) {
+				ICopyEvaluatorFactory 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);
+				}
+				ICopyEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(
+						Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
+				ICopyEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(
+						recordEvalFactory, fldIndexEvalFactory, recType);
+				IFunctionInfo finfoAccess = AsterixBuiltinFunctions
+						.getAsterixFunctionInfo(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<ICopyEvaluatorFactory, ScalarFunctionCallExpression, IAType>(evalFactory,
-                        partitionFun, recType.getFieldTypes()[i]);
-            }
-        }
-        throw new AlgebricksException("Could not find field " + fldName + " in the schema.");
-    }
+				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<ICopyEvaluatorFactory, 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;
-    }
+	@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());
-                // Convert UNION types into ANY.
-                if (itemType instanceof AUnionType) {
-                    itemType = BuiltinType.ANY;
-                }
-                ((ListifyAggregateDescriptor) fd).reset(new AOrderedListType(itemType, null));
-            }
-        }
-        if (fd.getIdentifier().equals(AsterixBuiltinFunctions.CAST_RECORD)) {
-            ARecordType rt = (ARecordType) TypeComputerUtilities.getRequiredType((AbstractFunctionCallExpression) expr);
-            ARecordType it = (ARecordType) TypeComputerUtilities.getInputType((AbstractFunctionCallExpression) expr);
-            ((CastRecordDescriptor) fd).reset(rt, it);
-        }
-        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 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());
+				// Convert UNION types into ANY.
+				if (itemType instanceof AUnionType) {
+					itemType = BuiltinType.ANY;
+				}
+				((ListifyAggregateDescriptor) fd).reset(new AOrderedListType(
+						itemType, null));
+			}
+		}
+		if (fd.getIdentifier().equals(AsterixBuiltinFunctions.CAST_RECORD)) {
+			ARecordType rt = (ARecordType) TypeComputerUtilities
+					.getRequiredType((AbstractFunctionCallExpression) expr);
+			ARecordType it = (ARecordType) TypeComputerUtilities
+					.getInputType((AbstractFunctionCallExpression) expr);
+			((CastRecordDescriptor) fd).reset(rt, it);
+		}
+		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;
-    }
+	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;
-    }
+	@Override
+	public IPrinterFactoryProvider getPrinterFactoryProvider() {
+		return AqlPrinterFactoryProvider.INSTANCE;
+	}
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public ICopyEvaluatorFactory 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.getByteArray(), abvs.getLength()));
-    }
+	@SuppressWarnings("unchecked")
+	@Override
+	public ICopyEvaluatorFactory 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.getByteArray(),
+				abvs.getLength()));
+	}
 
-    @Override
-    public IBinaryIntegerInspectorFactory getBinaryIntegerInspectorFactory() {
-        return AqlBinaryIntegerInspector.FACTORY;
-    }
+	@Override
+	public IBinaryIntegerInspectorFactory getBinaryIntegerInspectorFactory() {
+		return AqlBinaryIntegerInspector.FACTORY;
+	}
 
-    @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,
+			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 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 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 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;
-    }
+	@Override
+	public INormalizedKeyComputerFactoryProvider getNormalizedKeyComputerFactoryProvider() {
+		return AqlNormalizedKeyComputerFactoryProvider.INSTANCE;
+	}
+
+	@Override
+	public IBinaryHashFunctionFamilyProvider getBinaryHashFunctionFamilyProvider() {
+		return AqlBinaryHashFunctionFamilyProvider.INSTANCE;
+	}
 
 }
