merge with r500

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_function_merge@501 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
index 06765d6..35fb3ae 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
@@ -389,9 +389,9 @@
 			break;
 		}
 		default: {
+			v = context.newVar(lc.getVarExpr());
 			Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = aqlExprToAlgExpression(
 					lc.getBindingExpr(), tupSource);
-			v = context.newVar(lc.getVarExpr());
 			returnedOp = new AssignOperator(v,
 					new MutableObject<ILogicalExpression>(eo.first));
 			returnedOp.getInputs().add(eo.second);
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/ConstantHelper.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/ConstantHelper.java
index e010d3c..bf2b64a 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/ConstantHelper.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/ConstantHelper.java
@@ -1,21 +1,23 @@
 package edu.uci.ics.asterix.translator;
 
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 import edu.uci.ics.asterix.aql.literal.DoubleLiteral;
 import edu.uci.ics.asterix.aql.literal.FloatLiteral;
 import edu.uci.ics.asterix.aql.literal.IntegerLiteral;
+import edu.uci.ics.asterix.aql.literal.LongIntegerLiteral;
 import edu.uci.ics.asterix.aql.literal.StringLiteral;
 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.AInt32;
+import edu.uci.ics.asterix.om.base.AInt64;
 import edu.uci.ics.asterix.om.base.ANull;
 import edu.uci.ics.asterix.om.base.AString;
 import edu.uci.ics.asterix.om.base.IAObject;
 
 public final class ConstantHelper {
 
-    public static IAObject objectFromLiteral(ILiteral valLiteral) {
+    public static IAObject objectFromLiteral(Literal valLiteral) {
         switch (valLiteral.getLiteralType()) {
             case DOUBLE: {
                 DoubleLiteral d = (DoubleLiteral) valLiteral;
@@ -32,6 +34,10 @@
                 IntegerLiteral il = (IntegerLiteral) valLiteral;
                 return new AInt32(il.getValue());
             }
+            case LONG: {
+                LongIntegerLiteral il = (LongIntegerLiteral) valLiteral;
+                return new AInt64(il.getValue());                
+            }
             case NULL: {
                 return ANull.NULL;
             }
diff --git a/asterix-algebra/src/main/javacc/AQLPlus.jj b/asterix-algebra/src/main/javacc/AQLPlus.jj
index 9a8f783..3422652 100644
--- a/asterix-algebra/src/main/javacc/AQLPlus.jj
+++ b/asterix-algebra/src/main/javacc/AQLPlus.jj
@@ -20,8 +20,9 @@
 import edu.uci.ics.asterix.aql.literal.FloatLiteral;
 import edu.uci.ics.asterix.aql.literal.DoubleLiteral;
 import edu.uci.ics.asterix.aql.literal.FalseLiteral;
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 import edu.uci.ics.asterix.aql.literal.IntegerLiteral;
+import edu.uci.ics.asterix.aql.literal.LongIntegerLiteral;
 import edu.uci.ics.asterix.aql.literal.NullLiteral;
 import edu.uci.ics.asterix.aql.literal.StringLiteral;
 import edu.uci.ics.asterix.aql.literal.TrueLiteral;
@@ -778,8 +779,9 @@
 	{
 		if(expr.getKind() == Expression.Kind.LITERAL_EXPRESSION)
 		{
-			ILiteral lit = ((LiteralExpr)expr).getValue();
-			if(lit.getLiteralType() == ILiteral.Type.INTEGER) {
+			Literal lit = ((LiteralExpr)expr).getValue();
+			if(lit.getLiteralType() == Literal.Type.INTEGER || 
+ 			   lit.getLiteralType() == Literal.Type.LONG) {
 				idx = Integer.valueOf(lit.getStringValue());
 			}	
 			else {
@@ -809,7 +811,7 @@
   Expression expr = null;
 }
 {
-  //ILiteral | VariableRef | ListConstructor | RecordConstructor | FunctionCallExpr | ParenthesizedExpression
+  //Literal | VariableRef | ListConstructor | RecordConstructor | FunctionCallExpr | ParenthesizedExpression
 	(
 	  expr =Literal() 
 	   | expr = FunctionCallExpr()
@@ -846,7 +848,11 @@
  	 | <INTEGER_LITERAL>
     {
       t= getToken(0);
-	  lit.setValue(new IntegerLiteral(new Integer(t.image)));
+	  try {
+	      lit.setValue(new IntegerLiteral(new Integer(t.image)));
+	  } catch(NumberFormatException ex) {
+	      lit.setValue(new LongIntegerLiteral(new Long(t.image)));
+	  }
 	}
      | < FLOAT_LITERAL >
     {
@@ -1231,12 +1237,9 @@
 	extendCurrentScope();
 }
 {
-    "let" varExp = Variable()
+    "let" varExp = Variable() ":=" beExp = Expression()
     {
       getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
-	}
-     ":=" beExp = Expression()
-    {
       lc.setVarExpr(varExp);
       lc.setBeExpr(beExp);
       return lc;
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/abs0.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/abs0.aql
new file mode 100644
index 0000000..3908231
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/abs0.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_abs0.adm";
+
+
+let $c0 := int8("-0")
+let $c1 := int16("-0")
+let $c2 := int32("-0")
+let $c3 := int64("-0")
+let $c4 := int8("0")
+let $c5 := int16("0")
+let $c6 := int32("0")
+let $c7 := int64("0")
+return {"f0": numeric-abs($c0), "f1": numeric-abs($c1),"f2": numeric-abs($c2), "f3": numeric-abs($c3),
+	"f4": numeric-abs($c4),"f5": numeric-abs($c5) ,"f6": numeric-abs($c6), "f7": numeric-abs($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/abs1.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/abs1.aql
new file mode 100644
index 0000000..9d36528
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/abs1.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_abs1.adm";
+
+
+let $c0 := int8("-20")
+let $c1 := int16("-23")
+let $c2 := int32("-29")
+let $c3 := int64("-21")
+let $c4 := int8("20")
+let $c5 := int16("22")
+let $c6 := int32("23")
+let $c7 := int64("27")
+return {"f0": numeric-abs($c0), "f1": numeric-abs($c1),"f2": numeric-abs($c2), "f3": numeric-abs($c3),
+	"f4": numeric-abs($c4),"f5": numeric-abs($c5) ,"f6": numeric-abs($c6), "f7": numeric-abs($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/abs2.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/abs2.aql
new file mode 100644
index 0000000..411ae00
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/abs2.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_abs2.adm";
+
+
+let $c0 := float("-20.1")
+let $c1 := float("-20.56e-30")
+let $c2 := float("NaN")
+let $c3 := float("INF")
+let $c4 := float("-INF")
+let $c5 := float("-0.0")
+let $c6 := float("0.0")
+return {"f0": numeric-abs($c0), "f1": numeric-abs($c1),"f2": numeric-abs($c2),
+        "f3": numeric-abs($c3),"f4": numeric-abs($c4),"f5": numeric-abs($c5), "f6": numeric-abs($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/abs3.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/abs3.aql
new file mode 100644
index 0000000..4364409
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/abs3.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_abs3.adm";
+
+
+let $c0 := double("-20.1")
+let $c1 := double("-20.56e-30")
+let $c2 := double("NaN")
+let $c3 := double("INF")
+let $c4 := double("-INF")
+let $c5 := double("-0.0")
+let $c6 := double("0.0")
+return {"d0": numeric-abs($c0), "d1": numeric-abs($c1),"d2": numeric-abs($c2),
+        "d3": numeric-abs($c3),"d4": numeric-abs($c4),"d5": numeric-abs($c5), "d6": numeric-abs($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/abs4.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/abs4.aql
new file mode 100644
index 0000000..b2db5fd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/abs4.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_abs4.adm";
+
+let $c0 := int8("-20")
+return {"f0": numeric-abs($c0), "f1": numeric-abs(-1.11),"f2": numeric-abs(12.9), "f3": numeric-abs(1.11)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling0.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling0.aql
new file mode 100644
index 0000000..82e314f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling0.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_ceiling0.adm";
+
+
+let $c0 := int8("-0")
+let $c1 := int16("-0")
+let $c2 := int32("-0")
+let $c3 := int64("-0")
+let $c4 := int8("0")
+let $c5 := int16("0")
+let $c6 := int32("0")
+let $c7 := int64("0")
+return {"f0": numeric-ceiling($c0), "f1": numeric-ceiling($c1),"f2": numeric-ceiling($c2), "f3": numeric-ceiling($c3),
+	"f4": numeric-ceiling($c4),"f5": numeric-ceiling($c5) ,"f6": numeric-ceiling($c6), "f7": numeric-ceiling($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling1.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling1.aql
new file mode 100644
index 0000000..88e8d63
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling1.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_ceiling1.adm";
+
+
+let $c0 := int8("-20")
+let $c1 := int16("-23")
+let $c2 := int32("-29")
+let $c3 := int64("-21")
+let $c4 := int8("20")
+let $c5 := int16("22")
+let $c6 := int32("23")
+let $c7 := int64("27")
+return {"f0": numeric-ceiling($c0), "f1": numeric-ceiling($c1),"f2": numeric-ceiling($c2), "f3": numeric-ceiling($c3),
+	"f4": numeric-ceiling($c4),"f5": numeric-ceiling($c5) ,"f6": numeric-ceiling($c6), "f7": numeric-ceiling($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling2.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling2.aql
new file mode 100644
index 0000000..8f71213
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling2.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_ceiling2.adm";
+
+
+let $c0 := float("20.1")
+let $c1 := float("-20.56e-30")
+let $c2 := float("NaN")
+let $c3 := float("INF")
+let $c4 := float("-INF")
+let $c5 := float("-0.0")
+let $c6 := float("0.0")
+return {"f0": numeric-ceiling($c0), "f1": numeric-ceiling($c1),"f2": numeric-ceiling($c2),
+        "f3": numeric-ceiling($c3),"f4": numeric-ceiling($c4),"f5": numeric-ceiling($c5), "f6": numeric-ceiling($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling3.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling3.aql
new file mode 100644
index 0000000..67ad9db
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling3.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_ceiling3.adm";
+
+
+let $c0 := double("20.1")
+let $c1 := double("-20.56e-30")
+let $c2 := double("NaN")
+let $c3 := double("INF")
+let $c4 := double("-INF")
+let $c5 := double("-0.0")
+let $c6 := double("0.0")
+return {"d0": numeric-ceiling($c0), "d1": numeric-ceiling($c1),"d2": numeric-ceiling($c2),
+        "d3": numeric-ceiling($c3),"d4": numeric-ceiling($c4),"d5": numeric-ceiling($c5), "d6": numeric-ceiling($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling4.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling4.aql
new file mode 100644
index 0000000..a90851c
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/ceiling4.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_ceiling4.adm";
+
+let $c0 := int8("-20")
+return {"f0": numeric-ceiling($c0), "f1": numeric-ceiling(-1.11),"f2": numeric-ceiling(12.9), "f3": numeric-ceiling(1.11)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/floor0.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/floor0.aql
new file mode 100644
index 0000000..adfab71
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/floor0.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_floor0.adm";
+
+
+let $c0 := int8("-0")
+let $c1 := int16("-0")
+let $c2 := int32("-0")
+let $c3 := int64("-0")
+let $c4 := int8("0")
+let $c5 := int16("0")
+let $c6 := int32("0")
+let $c7 := int64("0")
+return {"f0": numeric-floor($c0), "f1": numeric-floor($c1),"f2": numeric-floor($c2), "f3": numeric-floor($c3),
+	"f4": numeric-floor($c4),"f5": numeric-floor($c5) ,"f6": numeric-floor($c6), "f7": numeric-floor($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/floor1.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/floor1.aql
new file mode 100644
index 0000000..a119b67
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/floor1.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_floor1.adm";
+
+
+let $c0 := int8("-20")
+let $c1 := int16("-23")
+let $c2 := int32("-29")
+let $c3 := int64("-21")
+let $c4 := int8("20")
+let $c5 := int16("22")
+let $c6 := int32("23")
+let $c7 := int64("27")
+return {"f0": numeric-floor($c0), "f1": numeric-floor($c1),"f2": numeric-floor($c2), "f3": numeric-floor($c3),
+	"f4": numeric-floor($c4),"f5": numeric-floor($c5) ,"f6": numeric-floor($c6), "f7": numeric-floor($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/floor2.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/floor2.aql
new file mode 100644
index 0000000..7e575dd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/floor2.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_floor2.adm";
+
+
+let $c0 := float("20.1")
+let $c1 := float("-20.56e-30")
+let $c2 := float("NaN")
+let $c3 := float("INF")
+let $c4 := float("-INF")
+let $c5 := float("-0.0")
+let $c6 := float("0.0")
+return {"f0": numeric-floor($c0), "f1": numeric-floor($c1),"f2": numeric-floor($c2),
+        "f3": numeric-floor($c3),"f4": numeric-floor($c4),"f5": numeric-floor($c5), "f6": numeric-floor($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/floor3.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/floor3.aql
new file mode 100644
index 0000000..d975dfc
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/floor3.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_floor3.adm";
+
+
+let $c0 := double("20.1")
+let $c1 := double("-20.56e-30")
+let $c2 := double("NaN")
+let $c3 := double("INF")
+let $c4 := double("-INF")
+let $c5 := double("-0.0")
+let $c6 := double("0.0")
+return {"d0": numeric-floor($c0), "d1": numeric-floor($c1),"d2": numeric-floor($c2),
+        "d3": numeric-floor($c3),"d4": numeric-floor($c4),"d5": numeric-floor($c5), "d6": numeric-floor($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/floor4.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/floor4.aql
new file mode 100644
index 0000000..eae917d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/floor4.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_floor4.adm";
+
+let $c0 := int8("-20")
+return {"f0": numeric-floor($c0), "f1": numeric-floor(-1.11),"f2": numeric-floor(12.9), "f3": numeric-floor(1.11)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even0.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even0.aql
new file mode 100644
index 0000000..25232d0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even0.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even0.adm";
+
+
+let $c0 := int8("-0")
+let $c1 := int16("-0")
+let $c2 := int32("-0")
+let $c3 := int64("-0")
+let $c4 := int8("0")
+let $c5 := int16("0")
+let $c6 := int32("0")
+let $c7 := int64("0")
+return {"f0": numeric-round-half-to-even($c0), "f1": numeric-round-half-to-even($c1),"f2": numeric-round-half-to-even($c2), "f3": numeric-round-half-to-even($c3),
+	"f4": numeric-round-half-to-even($c4),"f5": numeric-round-half-to-even($c5) ,"f6": numeric-round-half-to-even($c6), "f7": numeric-round-half-to-even($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even1.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even1.aql
new file mode 100644
index 0000000..eeccdd7
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even1.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even1.adm";
+
+
+let $c0 := int8("-20")
+let $c1 := int16("-23")
+let $c2 := int32("-29")
+let $c3 := int64("-21")
+let $c4 := int8("20")
+let $c5 := int16("22")
+let $c6 := int32("23")
+let $c7 := int64("27")
+return {"f0": numeric-round-half-to-even($c0), "f1": numeric-round-half-to-even($c1),"f2": numeric-round-half-to-even($c2), "f3": numeric-round-half-to-even($c3),
+	"f4": numeric-round-half-to-even($c4),"f5": numeric-round-half-to-even($c5) ,"f6": numeric-round-half-to-even($c6), "f7": numeric-round-half-to-even($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even2.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even2.aql
new file mode 100644
index 0000000..8b339ba
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even2.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even2.adm";
+
+
+let $c0 := float("0.5")
+let $c1 := float("-20.5")
+let $c2 := float("NaN")
+let $c3 := float("INF")
+let $c4 := float("-INF")
+let $c5 := float("-0.0")
+let $c6 := float("0.0")
+return {"f0": numeric-round-half-to-even($c0), "f1": numeric-round-half-to-even($c1),"f2": numeric-round-half-to-even($c2),
+        "f3": numeric-round-half-to-even($c3),"f4": numeric-round-half-to-even($c4),"f5": numeric-round-half-to-even($c5), "f6": numeric-round-half-to-even($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even20.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even20.aql
new file mode 100644
index 0000000..92088b4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even20.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even20.adm";
+
+
+let $c0 := int8("-0")
+let $c1 := int16("-0")
+let $c2 := int32("-0")
+let $c3 := int64("-0")
+let $c4 := int8("0")
+let $c5 := int16("0")
+let $c6 := int32("0")
+let $c7 := int64("0")
+return {"f0": numeric-round-half-to-even2($c0,2), "f1": numeric-round-half-to-even2($c1,2),"f2": numeric-round-half-to-even2($c2,2), "f3": numeric-round-half-to-even2($c3,2),
+	"f4": numeric-round-half-to-even2($c4,2),"f5": numeric-round-half-to-even2($c5,2) ,"f6": numeric-round-half-to-even2($c6,2), "f7": numeric-round-half-to-even2($c7,2)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even21.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even21.aql
new file mode 100644
index 0000000..c00cc25
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even21.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even21.adm";
+
+
+let $c0 := int8("-20")
+let $c1 := int16("-23")
+let $c2 := int32("-29")
+let $c3 := int64("-21")
+let $c4 := int8("20")
+let $c5 := int16("22")
+let $c6 := int32("23")
+let $c7 := int64("27")
+return {"f0": numeric-round-half-to-even2($c0,2), "f1": numeric-round-half-to-even2($c1,2),"f2": numeric-round-half-to-even2($c2,2), "f3": numeric-round-half-to-even2($c3,2),
+	"f4": numeric-round-half-to-even2($c4,2),"f5": numeric-round-half-to-even2($c5,2) ,"f6": numeric-round-half-to-even2($c6,2), "f7": numeric-round-half-to-even2($c7,2)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even22.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even22.aql
new file mode 100644
index 0000000..22ff5ad
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even22.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even22.adm";
+
+
+let $c0 := float("0.555")
+let $c1 := float("0.322")
+let $c2 := float("NaN")
+let $c3 := float("INF")
+let $c4 := float("-INF")
+let $c5 := float("-0.0")
+let $c6 := float("0.0")
+return {"d0": numeric-round-half-to-even2($c0,2), "d1": numeric-round-half-to-even2($c1,2),"d2": numeric-round-half-to-even2($c2,3),
+        "d3": numeric-round-half-to-even2($c3,4),"d4": numeric-round-half-to-even2($c4,5),"d5": numeric-round-half-to-even2($c5,6), "d6": numeric-round-half-to-even2($c6,0)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even23.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even23.aql
new file mode 100644
index 0000000..cbbcd10
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even23.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even23.adm";
+
+
+let $c0 := double("0.555")
+let $c1 := double("0.322")
+let $c2 := double("NaN")
+let $c3 := double("INF")
+let $c4 := double("-INF")
+let $c5 := double("-0.0")
+let $c6 := double("0.0")
+return {"d0": numeric-round-half-to-even2($c0,2), "d1": numeric-round-half-to-even2($c1,2),"d2": numeric-round-half-to-even2($c2,3),
+        "d3": numeric-round-half-to-even2($c3,4),"d4": numeric-round-half-to-even2($c4,5),"d5": numeric-round-half-to-even2($c5,6), "d6": numeric-round-half-to-even2($c6,0)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even24.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even24.aql
new file mode 100644
index 0000000..8fe21fe
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even24.aql
@@ -0,0 +1,14 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even24.adm";
+
+
+let $c0 := double("0.015")
+let $c1 := double("0.025")
+let $c2 := double("3.567812E+3")
+let $c3 := double("4.7564E-3")
+let $c4 := double("35612.25")
+return {"d0": numeric-round-half-to-even2($c0,2), "d1": numeric-round-half-to-even2($c1,2),"d2": numeric-round-half-to-even2($c2,2),
+        "d3": numeric-round-half-to-even2($c3,2),"d4": numeric-round-half-to-even2($c4,-2)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even3.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even3.aql
new file mode 100644
index 0000000..6d10ae1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even3.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even3.adm";
+
+
+let $c0 := double("0.5")
+let $c1 := double("-20.5")
+let $c2 := double("NaN")
+let $c3 := double("INF")
+let $c4 := double("-INF")
+let $c5 := double("-0.0")
+let $c6 := double("0.0")
+return {"d0": numeric-round-half-to-even($c0), "d1": numeric-round-half-to-even($c1), "d2": numeric-round-half-to-even($c2),
+        "d3": numeric-round-half-to-even($c3), "d4": numeric-round-half-to-even($c4), "d5": numeric-round-half-to-even($c5), "d6": numeric-round-half-to-even($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even4.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even4.aql
new file mode 100644
index 0000000..3c24b0b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even4.aql
@@ -0,0 +1,10 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even4.adm";
+
+
+let $c0 := double("1.5")
+let $c1 := double("2.5")
+return {"d0": numeric-round-half-to-even($c0), "d1": numeric-round-half-to-even($c1)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even5.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even5.aql
new file mode 100644
index 0000000..b89388f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round-half-to-even5.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round-half-to-even5.adm";
+
+let $c0 := int8("-20")
+return {"f0": numeric-round-half-to-even($c0), "f1": numeric-round-half-to-even(-1.5),"f2": numeric-round-half-to-even(12.5), "f3": numeric-round-half-to-even(1.5)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round0.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round0.aql
new file mode 100644
index 0000000..37887e5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round0.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round0.adm";
+
+
+let $c0 := int8("-0")
+let $c1 := int16("-0")
+let $c2 := int32("-0")
+let $c3 := int64("-0")
+let $c4 := int8("0")
+let $c5 := int16("0")
+let $c6 := int32("0")
+let $c7 := int64("0")
+return {"f0": numeric-round($c0), "f1": numeric-round($c1),"f2": numeric-round($c2), "f3": numeric-round($c3),
+	"f4": numeric-round($c4),"f5": numeric-round($c5) ,"f6": numeric-round($c6), "f7": numeric-round($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round1.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round1.aql
new file mode 100644
index 0000000..5c25bf8
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round1.aql
@@ -0,0 +1,17 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round1.adm";
+
+
+let $c0 := int8("-20")
+let $c1 := int16("-23")
+let $c2 := int32("-29")
+let $c3 := int64("-21")
+let $c4 := int8("20")
+let $c5 := int16("22")
+let $c6 := int32("23")
+let $c7 := int64("27")
+return {"f0": numeric-round($c0), "f1": numeric-round($c1),"f2": numeric-round($c2), "f3": numeric-round($c3),
+	"f4": numeric-round($c4),"f5": numeric-round($c5) ,"f6": numeric-round($c6), "f7": numeric-round($c7)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round2.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round2.aql
new file mode 100644
index 0000000..e5e75bb
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round2.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round2.adm";
+
+
+let $c0 := float("20.1")
+let $c1 := float("-20.56e-30")
+let $c2 := float("NaN")
+let $c3 := float("INF")
+let $c4 := float("-INF")
+let $c5 := float("-0.0")
+let $c6 := float("0.0")
+return {"f0": numeric-round($c0), "f1": numeric-round($c1),"f2": numeric-round($c2),
+        "f3": numeric-round($c3),"f4": numeric-round($c4),"f5": numeric-round($c5), "f6": numeric-round($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round3.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round3.aql
new file mode 100644
index 0000000..54e2685
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round3.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round3.adm";
+
+
+let $c0 := double("20.1")
+let $c1 := double("-20.56e-30")
+let $c2 := double("NaN")
+let $c3 := double("INF")
+let $c4 := double("-INF")
+let $c5 := double("-0.0")
+let $c6 := double("0.0")
+return {"d0": numeric-round($c0), "d1": numeric-round($c1),"d2": numeric-round($c2),
+        "d3": numeric-round($c3),"d4": numeric-round($c4),"d5": numeric-round($c5), "d6": numeric-round($c6)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/round4.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/round4.aql
new file mode 100644
index 0000000..5dccfd7
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/round4.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/numeric_round4.adm";
+
+let $c0 := int8("-20")
+return {"f0": numeric-round($c0), "f1": numeric-round(-1.11),"f2": numeric-round(12.9), "f3": numeric-round(1.11)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/codepoint-to-string1.aql b/asterix-app/src/test/resources/runtimets/queries/string/codepoint-to-string1.aql
new file mode 100644
index 0000000..a97e441
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/codepoint-to-string1.aql
@@ -0,0 +1,9 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_codepoint-to-string1.adm";
+
+let $x :=  [20013, 25991, 23383, 31526]
+let $c := codepoint-to-string($x)
+return {"result1": $c}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/codepoint-to-string2.aql b/asterix-app/src/test/resources/runtimets/queries/string/codepoint-to-string2.aql
new file mode 100644
index 0000000..829a082
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/codepoint-to-string2.aql
@@ -0,0 +1,12 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_codepoint-to-string2.adm";
+
+let $x1 :=  []
+let $c1 := codepoint-to-string($x1)
+
+let $x2 :=  [97,98,99]
+let $c2 := codepoint-to-string($x2)
+return {"f1": $c1, "f2" : $c2}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/concat1.aql b/asterix-app/src/test/resources/runtimets/queries/string/concat1.aql
new file mode 100644
index 0000000..a6ce63b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/concat1.aql
@@ -0,0 +1,12 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_concat1.adm";
+
+let $x :=  ["aa", "25991", "bb", "31526"]
+let $c := string-concat($x)
+
+let $x1 :=  []
+let $c1 := string-concat($x1)
+return {"result1": $c,"result2": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/end-with1.aql b/asterix-app/src/test/resources/runtimets/queries/string/end-with1.aql
new file mode 100644
index 0000000..98e0624
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/end-with1.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_end-with1.adm";
+
+let $c1 := end-with("hello world","werld")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/end-with2.aql b/asterix-app/src/test/resources/runtimets/queries/string/end-with2.aql
new file mode 100644
index 0000000..0e53f94
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/end-with2.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_end-with2.adm";
+
+let $c1 := end-with("hello world"," world")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/end-with3.aql b/asterix-app/src/test/resources/runtimets/queries/string/end-with3.aql
new file mode 100644
index 0000000..f71c320
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/end-with3.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_end-with3.adm";
+
+let $c1 := end-with("ends","")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/end-with4.aql b/asterix-app/src/test/resources/runtimets/queries/string/end-with4.aql
new file mode 100644
index 0000000..ca02d57
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/end-with4.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_end-with4.adm";
+
+let $c1 := end-with("ends","ss")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/end-with5.aql b/asterix-app/src/test/resources/runtimets/queries/string/end-with5.aql
new file mode 100644
index 0000000..510beb3
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/end-with5.aql
@@ -0,0 +1,14 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_end-with5.adm";
+
+let $c1 := end-with("ends","s")
+let $c2 := end-with("start",null)
+let $c3 := end-with(null,null)
+let $c4 := end-with("",null)
+let $c5 := end-with("","")
+let $c6 := end-with(null,"")
+
+return {"f1": $c1, "f2": $c2, "f3": $c3, "f4": $c4, "f5": $c5, "f6": $c6}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/length.aql b/asterix-app/src/test/resources/runtimets/queries/string/length.aql
new file mode 100644
index 0000000..d78d986
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/length.aql
@@ -0,0 +1,10 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_length.adm";
+
+let $c1 := string-length("hellow")
+let $c2 := string-length("")
+let $c3 := string-length(null)
+return {"result1": $c1, "result2": $c2, "result3": $c3}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/lowercase.aql b/asterix-app/src/test/resources/runtimets/queries/string/lowercase.aql
new file mode 100644
index 0000000..4c45007
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/lowercase.aql
@@ -0,0 +1,10 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_lowercase.adm";
+
+let $c1 := lowercase("HEllow")
+let $c2 := lowercase("")
+let $c3 := lowercase(null)
+return {"result1": $c1, "result2": $c2, "result3": $c3}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/matches1.aql b/asterix-app/src/test/resources/runtimets/queries/string/matches1.aql
new file mode 100644
index 0000000..f81932a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/matches1.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_matches1.adm";
+
+let $c1 := matches("abracadabra","bra")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/matches2.aql b/asterix-app/src/test/resources/runtimets/queries/string/matches2.aql
new file mode 100644
index 0000000..af5246e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/matches2.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_matches2.adm";
+
+let $c1 := matches("abracadabra","^a.*a$")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/matches21.aql b/asterix-app/src/test/resources/runtimets/queries/string/matches21.aql
new file mode 100644
index 0000000..19f9591
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/matches21.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_matches21.adm";
+
+let $c1 := matches2("abracadabra","Bra","")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/matches22.aql b/asterix-app/src/test/resources/runtimets/queries/string/matches22.aql
new file mode 100644
index 0000000..b8d7b96
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/matches22.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_matches22.adm";
+
+let $c1 := matches2("abracadabra","Bra","i")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/matches23.aql b/asterix-app/src/test/resources/runtimets/queries/string/matches23.aql
new file mode 100644
index 0000000..508699d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/matches23.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_matches23.adm";
+
+let $c1 := matches2("helloworld","hello world","x")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/matches3.aql b/asterix-app/src/test/resources/runtimets/queries/string/matches3.aql
new file mode 100644
index 0000000..19c6350
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/matches3.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_matches3.adm";
+
+let $c1 := matches("abracadabra","^bra")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/matchesnull.aql b/asterix-app/src/test/resources/runtimets/queries/string/matchesnull.aql
new file mode 100644
index 0000000..8e2f1a1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/matchesnull.aql
@@ -0,0 +1,13 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_matchesnull.adm";
+
+let $c1 := matches("helloworld",null)
+let $c2 := matches("",null)
+let $c3 := matches(null,null)
+let $c4 := matches2("helloworld",null, "")
+let $c5 := matches2("",null, "i")
+let $c6 := matches2(null,null, null)
+return {"result1": $c1, "result2": $c2, "result3": $c3, "result4": $c4, "result5": $c5, "result6": $c6}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/replace1.aql b/asterix-app/src/test/resources/runtimets/queries/string/replace1.aql
new file mode 100644
index 0000000..3a9e932
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/replace1.aql
@@ -0,0 +1,10 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_replace1.adm";
+
+let $c1 := replace("abracadabra", "a", "")
+let $c2 := replace("abracadabra", "a(.)", "a$1$1")
+let $c3 := replace("darted", "^(.*?)d(.*)$", "$1c$2")
+return {"result1": $c1, "result2": $c2, "result3": $c3}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/replace2.aql b/asterix-app/src/test/resources/runtimets/queries/string/replace2.aql
new file mode 100644
index 0000000..9b924f2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/replace2.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_replace2.adm";
+
+let $c1 := replace("abracadabra", "bra", "*")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/replace21.aql b/asterix-app/src/test/resources/runtimets/queries/string/replace21.aql
new file mode 100644
index 0000000..77c0c90
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/replace21.aql
@@ -0,0 +1,10 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_replace21.adm";
+
+let $c1 := replace2("abracadabra","Bra", "kkk" , "")
+let $c2 := replace2("abracadabra","Bra", "kkk" ,"i")
+let $c3 := replace2("helloworld","hello world", "kkk" , "x")
+return {"result1": $c1,"result2": $c2,"result3": $c3}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/replace22.aql b/asterix-app/src/test/resources/runtimets/queries/string/replace22.aql
new file mode 100644
index 0000000..2a0d5d6
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/replace22.aql
@@ -0,0 +1,15 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_replace22.adm";
+
+let $c1 := replace2("abracadabra","", null , null)
+let $c2 := replace2("abracadabra","bra", "XXX" ,"")
+let $c3 := replace2(null,"hello world", "XxXx" , "x")
+let $c4 := replace2("abracadabra","bra", "XXX" ,null)
+let $c5 := replace2("abracadabra",null, "XXX" ,null)
+let $c6 := replace2("abracadabra","Bra", null ,"i")
+let $c7 := replace2("abracadabra","Bra", "" ,"i")
+let $c8 := replace2("abracadabra","", "XXX" ,"")
+return {"result1": $c1,"result2": $c2,"result3": $c3,"result4": $c4,"result5": $c5,"result6": $c6,"result7": $c7,"result8": $c8}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/replace3.aql b/asterix-app/src/test/resources/runtimets/queries/string/replace3.aql
new file mode 100644
index 0000000..c1892dd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/replace3.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_replace3.adm";
+
+let $c1 := replace("abracadabra", "a.*a", "*")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/start-with1.aql b/asterix-app/src/test/resources/runtimets/queries/string/start-with1.aql
new file mode 100644
index 0000000..11ac150
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/start-with1.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_start-with1.adm";
+
+let $c1 := start-with("start","st")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/start-with2.aql b/asterix-app/src/test/resources/runtimets/queries/string/start-with2.aql
new file mode 100644
index 0000000..6d02c9a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/start-with2.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_start-with2.adm";
+
+let $c1 := start-with("start","t")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/start-with3.aql b/asterix-app/src/test/resources/runtimets/queries/string/start-with3.aql
new file mode 100644
index 0000000..a70dc33
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/start-with3.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_start-with3.adm";
+
+let $c1 := start-with("start","start")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/start-with4.aql b/asterix-app/src/test/resources/runtimets/queries/string/start-with4.aql
new file mode 100644
index 0000000..3629093
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/start-with4.aql
@@ -0,0 +1,14 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_start-with4.adm";
+
+let $c1 := start-with("start","")
+let $c2 := start-with("start",null)
+let $c3 := start-with(null,null)
+let $c4 := start-with("",null)
+let $c5 := start-with("","")
+let $c6 := start-with(null,"")
+
+return {"f1": $c1, "f2": $c2, "f3": $c3, "f4": $c4, "f5": $c5, "f6": $c6}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/start-with5.aql b/asterix-app/src/test/resources/runtimets/queries/string/start-with5.aql
new file mode 100644
index 0000000..33a0b8e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/start-with5.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_start-with5.adm";
+
+let $c1 := start-with("","s")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/string-concat1.aql b/asterix-app/src/test/resources/runtimets/queries/string/string-concat1.aql
new file mode 100644
index 0000000..b31e33c
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/string-concat1.aql
@@ -0,0 +1,9 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_string-concat1.adm";
+
+let $x :=  ["aa", "25991", "bb", "31526"]
+let $c := string-concat($x)
+return {"result1": $c}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/string-equal1.aql b/asterix-app/src/test/resources/runtimets/queries/string/string-equal1.aql
new file mode 100644
index 0000000..62ec56d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/string-equal1.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_string-equal1.adm";
+
+let $c1 := string-equal("test","tess")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/string-equal2.aql b/asterix-app/src/test/resources/runtimets/queries/string/string-equal2.aql
new file mode 100644
index 0000000..a102802
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/string-equal2.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_string-equal2.adm";
+
+let $c1 := string-equal("test","test")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/string-equal3.aql b/asterix-app/src/test/resources/runtimets/queries/string/string-equal3.aql
new file mode 100644
index 0000000..2749390
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/string-equal3.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_string-equal3.adm";
+
+let $c1 := string-equal("test11","test")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/string-equal4.aql b/asterix-app/src/test/resources/runtimets/queries/string/string-equal4.aql
new file mode 100644
index 0000000..f1cf243
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/string-equal4.aql
@@ -0,0 +1,11 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_string-equal4.adm";
+
+let $c1 := string-equal("","")
+let $c3 := string-equal(null,"")
+let $c4 := string-equal("",null)
+let $c5 := string-equal(null,null)
+return {"result1": $c1, "result3": $c3, "result4": $c4, "result5": $c5}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/string-join1.aql b/asterix-app/src/test/resources/runtimets/queries/string/string-join1.aql
new file mode 100644
index 0000000..0ea2bdd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/string-join1.aql
@@ -0,0 +1,11 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_string-join1.adm";
+
+let $x :=  ["aa", "25991", "bb", "31526"]
+let $s := "::"
+let $c := string-join($x,$s)
+let $c1 := string-join($x,"")
+return {"result0": $c,"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/string-to-codepoint.aql b/asterix-app/src/test/resources/runtimets/queries/string/string-to-codepoint.aql
new file mode 100644
index 0000000..2f1daba
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/string-to-codepoint.aql
@@ -0,0 +1,9 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_string-to-codepoint.adm";
+
+let $x :=  "abcd"
+let $c := string-to-codepoint($x)
+return {"result1": $c}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/string-to-codepoint1.aql b/asterix-app/src/test/resources/runtimets/queries/string/string-to-codepoint1.aql
new file mode 100644
index 0000000..5bcfd16
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/string-to-codepoint1.aql
@@ -0,0 +1,10 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_string-to-codepoint1.adm";
+
+let $x :=  ""
+let $c := string-to-codepoint($x)
+
+return {"result1": $c}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring-after-1.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring-after-1.aql
new file mode 100644
index 0000000..6c45bc8
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring-after-1.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring-after-1.adm";
+
+let $c1 := substring-after("HEllow","El")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring-after-2.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring-after-2.aql
new file mode 100644
index 0000000..78d6cad
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring-after-2.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring-after-2.adm";
+
+let $c1 := substring-after("HEllow","1")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring-after-3.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring-after-3.aql
new file mode 100644
index 0000000..91c3cab
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring-after-3.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring-after-3.adm";
+
+let $c1 := substring-after("HEllow","HEllow")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring-after-4.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring-after-4.aql
new file mode 100644
index 0000000..73a983f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring-after-4.aql
@@ -0,0 +1,12 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring-after-4.adm";
+
+let $c1 := substring-after("HEllow","")
+let $c2 := substring-after("HEllow",null)
+let $c3 := substring-after("",null)
+let $c4 := substring-after("","")
+let $c5 := substring-after(null,null)
+return {"result1": $c1, "result2": $c2, "result3": $c3, "result4": $c4, "result5": $c5}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring-before-1.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring-before-1.aql
new file mode 100644
index 0000000..1fe3a36
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring-before-1.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring-before-1.adm";
+
+let $c1 := substring-before("HEllow","ll")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring-before-2.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring-before-2.aql
new file mode 100644
index 0000000..4f59c43
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring-before-2.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring-before-2.adm";
+
+let $c1 := substring-before("HEllow","HEllow")
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring-before-3.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring-before-3.aql
new file mode 100644
index 0000000..9e40615
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring-before-3.aql
@@ -0,0 +1,12 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring-before-3.adm";
+
+let $c1 := substring-before("HEllow","")
+let $c2 := substring-before("HEllow",null)
+let $c3 := substring-before("",null)
+let $c4 := substring-before("","")
+let $c5 := substring-before(null,null)
+return {"result1": $c1, "result2": $c2, "result3": $c3, "result4": $c4, "result5": $c5}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring2-1.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring2-1.aql
new file mode 100644
index 0000000..78beb56
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring2-1.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring2-1.adm";
+
+let $c1 := substring2("HEllow",2)
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring2-2.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring2-2.aql
new file mode 100644
index 0000000..b310c9f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring2-2.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring2-2.adm";
+
+let $c1 := substring2("HEllow",0)
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring2-3.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring2-3.aql
new file mode 100644
index 0000000..70725b6
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring2-3.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring2-3.adm";
+
+let $c1 := substring2("HEllow",10)
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/substring2-4.aql b/asterix-app/src/test/resources/runtimets/queries/string/substring2-4.aql
new file mode 100644
index 0000000..1a1065a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/substring2-4.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_substring2-4.adm";
+
+let $c1 := substring2("HEllow",-1)
+return {"result1": $c1}
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/abs0.adm b/asterix-app/src/test/resources/runtimets/results/numeric/abs0.adm
new file mode 100644
index 0000000..61c5048
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/abs0.adm
@@ -0,0 +1 @@
+{ "f0": 0i8, "f1": 0i16, "f2": 0, "f3": 0i64, "f4": 0i8, "f5": 0i16, "f6": 0, "f7": 0i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/abs1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/abs1.adm
new file mode 100644
index 0000000..263ae97
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/abs1.adm
@@ -0,0 +1 @@
+{ "f0": 20i8, "f1": 23i16, "f2": 29, "f3": 21i64, "f4": 20i8, "f5": 22i16, "f6": 23, "f7": 27i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/abs2.adm b/asterix-app/src/test/resources/runtimets/results/numeric/abs2.adm
new file mode 100644
index 0000000..a4bcbe8
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/abs2.adm
@@ -0,0 +1 @@
+{ "f0": 20.1f, "f1": 2.056E-29f, "f2": NaNf, "f3": Infinityf, "f4": Infinityf, "f5": 0.0f, "f6": 0.0f }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/abs3.adm b/asterix-app/src/test/resources/runtimets/results/numeric/abs3.adm
new file mode 100644
index 0000000..4da3272
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/abs3.adm
@@ -0,0 +1 @@
+{ "d0": 20.1d, "d1": 2.056E-29d, "d2": NaNd, "d3": Infinityd, "d4": Infinityd, "d5": 0.0d, "d6": 0.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/abs4.adm b/asterix-app/src/test/resources/runtimets/results/numeric/abs4.adm
new file mode 100644
index 0000000..f365181
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/abs4.adm
@@ -0,0 +1 @@
+{ "f0": 20i8, "f1": 1.11d, "f2": 12.9d, "f3": 1.11d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/ceiling0.adm b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling0.adm
new file mode 100644
index 0000000..61c5048
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling0.adm
@@ -0,0 +1 @@
+{ "f0": 0i8, "f1": 0i16, "f2": 0, "f3": 0i64, "f4": 0i8, "f5": 0i16, "f6": 0, "f7": 0i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/ceiling1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling1.adm
new file mode 100644
index 0000000..bf278a1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling1.adm
@@ -0,0 +1 @@
+{ "f0": -20i8, "f1": -23i16, "f2": -29, "f3": -21i64, "f4": 20i8, "f5": 22i16, "f6": 23, "f7": 27i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/ceiling2.adm b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling2.adm
new file mode 100644
index 0000000..96e5d3d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling2.adm
@@ -0,0 +1 @@
+{ "f0": 21.0f, "f1": -0.0f, "f2": NaNf, "f3": Infinityf, "f4": -Infinityf, "f5": -0.0f, "f6": 0.0f }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/ceiling3.adm b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling3.adm
new file mode 100644
index 0000000..bf497d4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling3.adm
@@ -0,0 +1 @@
+{ "d0": 21.0d, "d1": -0.0d, "d2": NaNd, "d3": Infinityd, "d4": -Infinityd, "d5": -0.0d, "d6": 0.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/ceiling4.adm b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling4.adm
new file mode 100644
index 0000000..dcc17c0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/ceiling4.adm
@@ -0,0 +1 @@
+{ "f0": -20i8, "f1": -1.0d, "f2": 13.0d, "f3": 2.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/floor0.adm b/asterix-app/src/test/resources/runtimets/results/numeric/floor0.adm
new file mode 100644
index 0000000..61c5048
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/floor0.adm
@@ -0,0 +1 @@
+{ "f0": 0i8, "f1": 0i16, "f2": 0, "f3": 0i64, "f4": 0i8, "f5": 0i16, "f6": 0, "f7": 0i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/floor1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/floor1.adm
new file mode 100644
index 0000000..bf278a1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/floor1.adm
@@ -0,0 +1 @@
+{ "f0": -20i8, "f1": -23i16, "f2": -29, "f3": -21i64, "f4": 20i8, "f5": 22i16, "f6": 23, "f7": 27i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/floor2.adm b/asterix-app/src/test/resources/runtimets/results/numeric/floor2.adm
new file mode 100644
index 0000000..078d159
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/floor2.adm
@@ -0,0 +1 @@
+{ "f0": 20.0f, "f1": -1.0f, "f2": NaNf, "f3": Infinityf, "f4": -Infinityf, "f5": -0.0f, "f6": 0.0f }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/floor3.adm b/asterix-app/src/test/resources/runtimets/results/numeric/floor3.adm
new file mode 100644
index 0000000..58bdd79
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/floor3.adm
@@ -0,0 +1 @@
+{ "d0": 20.0d, "d1": -1.0d, "d2": NaNd, "d3": Infinityd, "d4": -Infinityd, "d5": -0.0d, "d6": 0.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/floor4.adm b/asterix-app/src/test/resources/runtimets/results/numeric/floor4.adm
new file mode 100644
index 0000000..3e972b3
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/floor4.adm
@@ -0,0 +1 @@
+{ "f0": -20i8, "f1": -2.0d, "f2": 12.0d, "f3": 1.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even0.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even0.adm
new file mode 100644
index 0000000..61c5048
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even0.adm
@@ -0,0 +1 @@
+{ "f0": 0i8, "f1": 0i16, "f2": 0, "f3": 0i64, "f4": 0i8, "f5": 0i16, "f6": 0, "f7": 0i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even1.adm
new file mode 100644
index 0000000..bf278a1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even1.adm
@@ -0,0 +1 @@
+{ "f0": -20i8, "f1": -23i16, "f2": -29, "f3": -21i64, "f4": 20i8, "f5": 22i16, "f6": 23, "f7": 27i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even2.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even2.adm
new file mode 100644
index 0000000..f5f9e3f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even2.adm
@@ -0,0 +1 @@
+{ "f0": 0.0f, "f1": -20.0f, "f2": NaNf, "f3": Infinityf, "f4": -Infinityf, "f5": -0.0f, "f6": 0.0f }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even20.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even20.adm
new file mode 100644
index 0000000..61c5048
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even20.adm
@@ -0,0 +1 @@
+{ "f0": 0i8, "f1": 0i16, "f2": 0, "f3": 0i64, "f4": 0i8, "f5": 0i16, "f6": 0, "f7": 0i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even21.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even21.adm
new file mode 100644
index 0000000..bf278a1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even21.adm
@@ -0,0 +1 @@
+{ "f0": -20i8, "f1": -23i16, "f2": -29, "f3": -21i64, "f4": 20i8, "f5": 22i16, "f6": 23, "f7": 27i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even22.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even22.adm
new file mode 100644
index 0000000..3f0cead
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even22.adm
@@ -0,0 +1 @@
+{ "d0": 0.56f, "d1": 0.32f, "d2": NaNf, "d3": Infinityf, "d4": -Infinityf, "d5": -0.0f, "d6": 0.0f }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even23.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even23.adm
new file mode 100644
index 0000000..914a79e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even23.adm
@@ -0,0 +1 @@
+{ "d0": 0.56d, "d1": 0.32d, "d2": NaNd, "d3": Infinityd, "d4": -Infinityd, "d5": -0.0d, "d6": 0.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even24.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even24.adm
new file mode 100644
index 0000000..956f0ac
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even24.adm
@@ -0,0 +1 @@
+{ "d0": 0.02d, "d1": 0.02d, "d2": 3567.81d, "d3": 0.0d, "d4": 35600.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even3.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even3.adm
new file mode 100644
index 0000000..60b7c52
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even3.adm
@@ -0,0 +1 @@
+{ "d0": 0.0d, "d1": -20.0d, "d2": NaNd, "d3": Infinityd, "d4": -Infinityd, "d5": -0.0d, "d6": 0.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even4.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even4.adm
new file mode 100644
index 0000000..5620cde
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even4.adm
@@ -0,0 +1 @@
+{ "d0": 2.0d, "d1": 2.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even5.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even5.adm
new file mode 100644
index 0000000..a53f62f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round-half-to-even5.adm
@@ -0,0 +1 @@
+{ "f0": -20i8, "f1": -2.0d, "f2": 12.0d, "f3": 2.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round0.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round0.adm
new file mode 100644
index 0000000..61c5048
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round0.adm
@@ -0,0 +1 @@
+{ "f0": 0i8, "f1": 0i16, "f2": 0, "f3": 0i64, "f4": 0i8, "f5": 0i16, "f6": 0, "f7": 0i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round1.adm
new file mode 100644
index 0000000..bf278a1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round1.adm
@@ -0,0 +1 @@
+{ "f0": -20i8, "f1": -23i16, "f2": -29, "f3": -21i64, "f4": 20i8, "f5": 22i16, "f6": 23, "f7": 27i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round2.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round2.adm
new file mode 100644
index 0000000..791c1da
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round2.adm
@@ -0,0 +1 @@
+{ "f0": 20.0f, "f1": 0.0f, "f2": 0.0f, "f3": 2.14748365E9f, "f4": -2.14748365E9f, "f5": 0.0f, "f6": 0.0f }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round3.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round3.adm
new file mode 100644
index 0000000..1b1936d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round3.adm
@@ -0,0 +1 @@
+{ "d0": 20.0d, "d1": 0.0d, "d2": 0.0d, "d3": 9.223372036854776E18d, "d4": -9.223372036854776E18d, "d5": 0.0d, "d6": 0.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/round4.adm b/asterix-app/src/test/resources/runtimets/results/numeric/round4.adm
new file mode 100644
index 0000000..ce70363
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/round4.adm
@@ -0,0 +1 @@
+{ "f0": -20i8, "f1": -1.0d, "f2": 13.0d, "f3": 1.0d }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/codepoint-to-string1.adm b/asterix-app/src/test/resources/runtimets/results/string/codepoint-to-string1.adm
new file mode 100644
index 0000000..fdbb861
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/codepoint-to-string1.adm
@@ -0,0 +1 @@
+{ "result1": "中文字符" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/codepoint-to-string2.adm b/asterix-app/src/test/resources/runtimets/results/string/codepoint-to-string2.adm
new file mode 100644
index 0000000..8ab1bd7
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/codepoint-to-string2.adm
@@ -0,0 +1 @@
+{ "f1": "", "f2": "abc" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/concat1.adm b/asterix-app/src/test/resources/runtimets/results/string/concat1.adm
new file mode 100644
index 0000000..cea6e76
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/concat1.adm
@@ -0,0 +1 @@
+{ "result1": "aa25991bb31526", "result2": "" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/end-with1.adm b/asterix-app/src/test/resources/runtimets/results/string/end-with1.adm
new file mode 100644
index 0000000..ea9ca72
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/end-with1.adm
@@ -0,0 +1 @@
+{ "result1": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/end-with2.adm b/asterix-app/src/test/resources/runtimets/results/string/end-with2.adm
new file mode 100644
index 0000000..538da31
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/end-with2.adm
@@ -0,0 +1 @@
+{ "result1": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/end-with3.adm b/asterix-app/src/test/resources/runtimets/results/string/end-with3.adm
new file mode 100644
index 0000000..538da31
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/end-with3.adm
@@ -0,0 +1 @@
+{ "result1": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/end-with4.adm b/asterix-app/src/test/resources/runtimets/results/string/end-with4.adm
new file mode 100644
index 0000000..ea9ca72
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/end-with4.adm
@@ -0,0 +1 @@
+{ "result1": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/end-with5.adm b/asterix-app/src/test/resources/runtimets/results/string/end-with5.adm
new file mode 100644
index 0000000..c13d3dc
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/end-with5.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": false, "f3": true, "f4": false, "f5": true, "f6": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/length.adm b/asterix-app/src/test/resources/runtimets/results/string/length.adm
new file mode 100644
index 0000000..45a976e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/length.adm
@@ -0,0 +1 @@
+{ "result1": 6, "result2": 0, "result3": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/lowercase.adm b/asterix-app/src/test/resources/runtimets/results/string/lowercase.adm
new file mode 100644
index 0000000..a20b9aa
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/lowercase.adm
@@ -0,0 +1 @@
+{ "result1": "hellow", "result2": "", "result3": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/matches1.adm b/asterix-app/src/test/resources/runtimets/results/string/matches1.adm
new file mode 100644
index 0000000..538da31
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/matches1.adm
@@ -0,0 +1 @@
+{ "result1": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/matches2.adm b/asterix-app/src/test/resources/runtimets/results/string/matches2.adm
new file mode 100644
index 0000000..538da31
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/matches2.adm
@@ -0,0 +1 @@
+{ "result1": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/matches21.adm b/asterix-app/src/test/resources/runtimets/results/string/matches21.adm
new file mode 100644
index 0000000..ea9ca72
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/matches21.adm
@@ -0,0 +1 @@
+{ "result1": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/matches22.adm b/asterix-app/src/test/resources/runtimets/results/string/matches22.adm
new file mode 100644
index 0000000..538da31
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/matches22.adm
@@ -0,0 +1 @@
+{ "result1": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/matches23.adm b/asterix-app/src/test/resources/runtimets/results/string/matches23.adm
new file mode 100644
index 0000000..538da31
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/matches23.adm
@@ -0,0 +1 @@
+{ "result1": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/matches3.adm b/asterix-app/src/test/resources/runtimets/results/string/matches3.adm
new file mode 100644
index 0000000..ea9ca72
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/matches3.adm
@@ -0,0 +1 @@
+{ "result1": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/matchesnull.adm b/asterix-app/src/test/resources/runtimets/results/string/matchesnull.adm
new file mode 100644
index 0000000..6126426
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/matchesnull.adm
@@ -0,0 +1 @@
+{ "result1": false, "result2": false, "result3": true, "result4": false, "result5": false, "result6": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/replace1.adm b/asterix-app/src/test/resources/runtimets/results/string/replace1.adm
new file mode 100644
index 0000000..5f992ce
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/replace1.adm
@@ -0,0 +1 @@
+{ "result1": "brcdbr", "result2": "abbraccaddabbra", "result3": "carted" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/replace2.adm b/asterix-app/src/test/resources/runtimets/results/string/replace2.adm
new file mode 100644
index 0000000..fa45140
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/replace2.adm
@@ -0,0 +1 @@
+{ "result1": "a*cada*" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/replace21.adm b/asterix-app/src/test/resources/runtimets/results/string/replace21.adm
new file mode 100644
index 0000000..9fd2e6a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/replace21.adm
@@ -0,0 +1 @@
+{ "result1": "abracadabra", "result2": "akkkcadakkk", "result3": "kkk" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/replace22.adm b/asterix-app/src/test/resources/runtimets/results/string/replace22.adm
new file mode 100644
index 0000000..21ca784
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/replace22.adm
@@ -0,0 +1 @@
+{ "result1": "abracadabra", "result2": "aXXXcadaXXX", "result3": null, "result4": "aXXXcadaXXX", "result5": "XXXaXXXbXXXrXXXaXXXcXXXaXXXdXXXaXXXbXXXrXXXaXXX", "result6": "acada", "result7": "acada", "result8": "XXXaXXXbXXXrXXXaXXXcXXXaXXXdXXXaXXXbXXXrXXXaXXX" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/replace3.adm b/asterix-app/src/test/resources/runtimets/results/string/replace3.adm
new file mode 100644
index 0000000..3882682
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/replace3.adm
@@ -0,0 +1 @@
+{ "result1": "*" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/start-with1.adm b/asterix-app/src/test/resources/runtimets/results/string/start-with1.adm
new file mode 100644
index 0000000..538da31
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/start-with1.adm
@@ -0,0 +1 @@
+{ "result1": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/start-with2.adm b/asterix-app/src/test/resources/runtimets/results/string/start-with2.adm
new file mode 100644
index 0000000..ea9ca72
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/start-with2.adm
@@ -0,0 +1 @@
+{ "result1": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/start-with3.adm b/asterix-app/src/test/resources/runtimets/results/string/start-with3.adm
new file mode 100644
index 0000000..538da31
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/start-with3.adm
@@ -0,0 +1 @@
+{ "result1": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/start-with4.adm b/asterix-app/src/test/resources/runtimets/results/string/start-with4.adm
new file mode 100644
index 0000000..c13d3dc
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/start-with4.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": false, "f3": true, "f4": false, "f5": true, "f6": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/start-with5.adm b/asterix-app/src/test/resources/runtimets/results/string/start-with5.adm
new file mode 100644
index 0000000..ea9ca72
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/start-with5.adm
@@ -0,0 +1 @@
+{ "result1": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/string-concat1.adm b/asterix-app/src/test/resources/runtimets/results/string/string-concat1.adm
new file mode 100644
index 0000000..a5becc3
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/string-concat1.adm
@@ -0,0 +1 @@
+{ "result1": "aa25991bb31526" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/string-equal-true1.adm b/asterix-app/src/test/resources/runtimets/results/string/string-equal-true1.adm
new file mode 100644
index 0000000..ea9ca72
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/string-equal-true1.adm
@@ -0,0 +1 @@
+{ "result1": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/string-equal1.adm b/asterix-app/src/test/resources/runtimets/results/string/string-equal1.adm
new file mode 100644
index 0000000..ea9ca72
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/string-equal1.adm
@@ -0,0 +1 @@
+{ "result1": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/string-equal2.adm b/asterix-app/src/test/resources/runtimets/results/string/string-equal2.adm
new file mode 100644
index 0000000..538da31
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/string-equal2.adm
@@ -0,0 +1 @@
+{ "result1": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/string-equal3.adm b/asterix-app/src/test/resources/runtimets/results/string/string-equal3.adm
new file mode 100644
index 0000000..ea9ca72
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/string-equal3.adm
@@ -0,0 +1 @@
+{ "result1": false }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/string-equal4.adm b/asterix-app/src/test/resources/runtimets/results/string/string-equal4.adm
new file mode 100644
index 0000000..71a9bb6
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/string-equal4.adm
@@ -0,0 +1 @@
+{ "result1": true, "result3": false, "result4": false, "result5": true }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/string-join1.adm b/asterix-app/src/test/resources/runtimets/results/string/string-join1.adm
new file mode 100644
index 0000000..7276381
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/string-join1.adm
@@ -0,0 +1 @@
+{ "result0": "aa::25991::bb::31526", "result1": "aa25991bb31526" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/string-to-codepoint.adm b/asterix-app/src/test/resources/runtimets/results/string/string-to-codepoint.adm
new file mode 100644
index 0000000..c67c60e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/string-to-codepoint.adm
@@ -0,0 +1 @@
+{ "result1": [ 97, 98, 99, 100 ] }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/string-to-codepoint1.adm b/asterix-app/src/test/resources/runtimets/results/string/string-to-codepoint1.adm
new file mode 100644
index 0000000..46eca36
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/string-to-codepoint1.adm
@@ -0,0 +1 @@
+{ "result1": [  ] }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring-after-1.adm b/asterix-app/src/test/resources/runtimets/results/string/substring-after-1.adm
new file mode 100644
index 0000000..197a7af
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring-after-1.adm
@@ -0,0 +1 @@
+{ "result1": "low" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring-after-2.adm b/asterix-app/src/test/resources/runtimets/results/string/substring-after-2.adm
new file mode 100644
index 0000000..04393a4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring-after-2.adm
@@ -0,0 +1 @@
+{ "result1": "" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring-after-3.adm b/asterix-app/src/test/resources/runtimets/results/string/substring-after-3.adm
new file mode 100644
index 0000000..04393a4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring-after-3.adm
@@ -0,0 +1 @@
+{ "result1": "" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring-after-4.adm b/asterix-app/src/test/resources/runtimets/results/string/substring-after-4.adm
new file mode 100644
index 0000000..9406ef5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring-after-4.adm
@@ -0,0 +1 @@
+{ "result1": "HEllow", "result2": "HEllow", "result3": "", "result4": "", "result5": "" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring-before-1.adm b/asterix-app/src/test/resources/runtimets/results/string/substring-before-1.adm
new file mode 100644
index 0000000..1c6a7d7
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring-before-1.adm
@@ -0,0 +1 @@
+{ "result1": "HE" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring-before-2.adm b/asterix-app/src/test/resources/runtimets/results/string/substring-before-2.adm
new file mode 100644
index 0000000..04393a4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring-before-2.adm
@@ -0,0 +1 @@
+{ "result1": "" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring-before-3.adm b/asterix-app/src/test/resources/runtimets/results/string/substring-before-3.adm
new file mode 100644
index 0000000..9ce64e4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring-before-3.adm
@@ -0,0 +1 @@
+{ "result1": "", "result2": "", "result3": "", "result4": "", "result5": "" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring2-1.adm b/asterix-app/src/test/resources/runtimets/results/string/substring2-1.adm
new file mode 100644
index 0000000..411e803
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring2-1.adm
@@ -0,0 +1 @@
+{ "result1": "Ellow" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring2-2.adm b/asterix-app/src/test/resources/runtimets/results/string/substring2-2.adm
new file mode 100644
index 0000000..5b0c7b9
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring2-2.adm
@@ -0,0 +1 @@
+{ "result1": "HEllow" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring2-3.adm b/asterix-app/src/test/resources/runtimets/results/string/substring2-3.adm
new file mode 100644
index 0000000..04393a4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring2-3.adm
@@ -0,0 +1 @@
+{ "result1": "" }
diff --git a/asterix-app/src/test/resources/runtimets/results/string/substring2-4.adm b/asterix-app/src/test/resources/runtimets/results/string/substring2-4.adm
new file mode 100644
index 0000000..5b0c7b9
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/substring2-4.adm
@@ -0,0 +1 @@
+{ "result1": "HEllow" }
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/ILiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/ILiteral.java
deleted file mode 100644
index 31cb27e..0000000
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/ILiteral.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.aql.base;
-
-import java.io.Serializable;
-
-public interface ILiteral extends Serializable {
-    public enum Type {
-        STRING,
-        INTEGER,
-        NULL,
-        TRUE,
-        FALSE,
-        FLOAT,
-        DOUBLE
-    }
-
-    public Type getLiteralType();
-
-    public String getStringValue();
-
-}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Literal.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Literal.java
new file mode 100644
index 0000000..f6c779a
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Literal.java
@@ -0,0 +1,61 @@
+/*
+ * 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.aql.base;
+
+import java.io.Serializable;
+
+public abstract class Literal implements Serializable {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -6468144574890768345L;
+
+    public enum Type {
+        STRING,
+        INTEGER,
+        NULL,
+        TRUE,
+        FALSE,
+        FLOAT,
+        DOUBLE,
+        LONG
+    }
+
+    abstract public Object getValue();
+    
+    abstract public Type getLiteralType();
+
+    public String getStringValue() {
+        return getValue().toString();
+    }    
+    
+    @Override
+    public int hashCode() {
+        return getValue().hashCode();
+    }    
+
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Literal)) {
+            return false;
+        }
+        Literal literal = (Literal)obj;
+        return getValue().equals(literal.getValue());
+    } 
+    
+    @Override
+    public String toString() {
+        return getStringValue();
+    }    
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LiteralExpr.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LiteralExpr.java
index ba94cfc..496b0e0 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LiteralExpr.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LiteralExpr.java
@@ -1,26 +1,26 @@
 package edu.uci.ics.asterix.aql.expression;
 
 import edu.uci.ics.asterix.aql.base.Expression;
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlVisitorWithVoidReturn;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 
 public class LiteralExpr implements Expression {
-    private ILiteral value;
+    private Literal value;
 
     public LiteralExpr() {
     }
 
-    public LiteralExpr(ILiteral value) {
+    public LiteralExpr(Literal value) {
         this.value = value;
     }
 
-    public ILiteral getValue() {
+    public Literal getValue() {
         return value;
     }
 
-    public void setValue(ILiteral value) {
+    public void setValue(Literal value) {
         this.value = value;
     }
 
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/AQLPrintVisitor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/AQLPrintVisitor.java
index f01991b..1c681b1 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/AQLPrintVisitor.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/AQLPrintVisitor.java
@@ -6,7 +6,7 @@
 
 import edu.uci.ics.asterix.aql.base.Clause;
 import edu.uci.ics.asterix.aql.base.Expression;
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 import edu.uci.ics.asterix.aql.base.Statement;
 import edu.uci.ics.asterix.aql.expression.BeginFeedStatement;
 import edu.uci.ics.asterix.aql.expression.CallExpr;
@@ -103,9 +103,9 @@
 
     @Override
     public void visit(LiteralExpr l, Integer step) {
-        ILiteral lc = l.getValue();
-        if (lc.getLiteralType().equals(ILiteral.Type.TRUE) || lc.getLiteralType().equals(ILiteral.Type.FALSE)
-                || lc.getLiteralType().equals(ILiteral.Type.NULL)) {
+    	Literal lc = l.getValue();
+        if (lc.getLiteralType().equals(Literal.Type.TRUE) || lc.getLiteralType().equals(Literal.Type.FALSE)
+                || lc.getLiteralType().equals(Literal.Type.NULL)) {
             out.println(skip(step) + "LiteralExpr [" + l.getValue().getLiteralType() + "]");
         } else {
             out.println(skip(step) + "LiteralExpr [" + l.getValue().getLiteralType() + "] ["
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/DoubleLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/DoubleLiteral.java
index d35f5f3..fb0c827 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/DoubleLiteral.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/DoubleLiteral.java
@@ -14,9 +14,9 @@
  */
 package edu.uci.ics.asterix.aql.literal;
 
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 
-public class DoubleLiteral implements ILiteral {
+public class DoubleLiteral extends Literal {
     /**
      * 
      */
@@ -28,10 +28,12 @@
         this.value = value;
     }
 
+    @Override    
     public Double getValue() {
         return value;
     }
 
+
     public void setValue(Double value) {
         this.value = value;
     }
@@ -40,28 +42,4 @@
     public Type getLiteralType() {
         return Type.DOUBLE;
     }
-
-    @Override
-    public String getStringValue() {
-        return value.toString();
-    }
-
-    @Override
-    public String toString() {
-        return getStringValue();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof DoubleLiteral)) {
-            return false;
-        }
-        DoubleLiteral d = (DoubleLiteral) obj;
-        return d.getValue() == value;
-    }
-
-    @Override
-    public int hashCode() {
-        return value.hashCode();
-    }
 }
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FalseLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FalseLiteral.java
index 17b4254..7f19b84 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FalseLiteral.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FalseLiteral.java
@@ -14,9 +14,9 @@
  */
 package edu.uci.ics.asterix.aql.literal;
 
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 
-public class FalseLiteral implements ILiteral {
+public class FalseLiteral extends Literal {
 
     private static final long serialVersionUID = -750814844423165149L;
 
@@ -49,4 +49,9 @@
     public int hashCode() {
         return (int) serialVersionUID;
     }
+
+    @Override
+    public Boolean getValue() {
+        return Boolean.FALSE;
+    }
 }
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FloatLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FloatLiteral.java
index f77ed39..b2db6a1 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FloatLiteral.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FloatLiteral.java
@@ -14,9 +14,9 @@
  */
 package edu.uci.ics.asterix.aql.literal;
 
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 
-public class FloatLiteral implements ILiteral {
+public class FloatLiteral extends Literal {
     /**
      * 
      */
@@ -28,10 +28,12 @@
         this.value = value;
     }
 
+    @Override
     public Float getValue() {
         return value;
     }
 
+    
     public void setValue(Float value) {
         this.value = value;
     }
@@ -40,28 +42,4 @@
     public Type getLiteralType() {
         return Type.FLOAT;
     }
-
-    @Override
-    public String getStringValue() {
-        return value.toString();
-    }
-
-    @Override
-    public String toString() {
-        return getStringValue();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof FloatLiteral)) {
-            return false;
-        }
-        FloatLiteral f = (FloatLiteral) obj;
-        return f.getValue() == value;
-    }
-
-    @Override
-    public int hashCode() {
-        return value.hashCode();
-    }
 }
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/IntegerLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/IntegerLiteral.java
index 52cf7fa..f29feb8 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/IntegerLiteral.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/IntegerLiteral.java
@@ -14,9 +14,9 @@
  */
 package edu.uci.ics.asterix.aql.literal;
 
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 
-public class IntegerLiteral implements ILiteral {
+public class IntegerLiteral extends Literal {
     /**
      * 
      */
@@ -37,32 +37,7 @@
     }
 
     @Override
-    public String toString() {
-        return getStringValue();
-    }
-
-    @Override
     public Type getLiteralType() {
         return Type.INTEGER;
     }
-
-    @Override
-    public String getStringValue() {
-        return value.toString();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof IntegerLiteral)) {
-            return false;
-        }
-        IntegerLiteral i = (IntegerLiteral) obj;
-        return value.equals(i.getValue());
-    }
-
-    @Override
-    public int hashCode() {
-        return value;
-    }
-
 }
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/LongIntegerLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/LongIntegerLiteral.java
new file mode 100644
index 0000000..7e02f04
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/LongIntegerLiteral.java
@@ -0,0 +1,44 @@
+/*
+ * 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.aql.literal;
+
+import edu.uci.ics.asterix.aql.base.Literal;
+
+public class LongIntegerLiteral extends Literal {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -8633520244871361967L;
+    private Long value;
+
+    public LongIntegerLiteral(Long value) {
+        super();
+        this.value = value;
+    }
+
+    @Override
+    public Long getValue() {
+        return value;
+    }
+
+    public void setValue(Long value) {
+        this.value = value;
+    }
+
+    @Override
+    public Type getLiteralType() {
+        return Type.LONG;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/NullLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/NullLiteral.java
index b421afa..efcb9c6 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/NullLiteral.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/NullLiteral.java
@@ -14,9 +14,9 @@
  */
 package edu.uci.ics.asterix.aql.literal;
 
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 
-public class NullLiteral implements ILiteral {
+public class NullLiteral extends Literal {
 
     /**
      * 
@@ -39,11 +39,6 @@
     }
 
     @Override
-    public String toString() {
-        return getStringValue();
-    }
-
-    @Override
     public boolean equals(Object obj) {
         return obj == INSTANCE;
     }
@@ -52,4 +47,9 @@
     public int hashCode() {
         return (int) serialVersionUID;
     }
+
+    @Override
+    public Object getValue() {
+        return null;
+    }    
 }
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/StringLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/StringLiteral.java
index ad5588f..0fd586c 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/StringLiteral.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/StringLiteral.java
@@ -1,8 +1,8 @@
 package edu.uci.ics.asterix.aql.literal;
 
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 
-public class StringLiteral implements ILiteral {
+public class StringLiteral extends Literal {
 
     private static final long serialVersionUID = -6342491706277606168L;
     private String value;
@@ -29,24 +29,4 @@
     public String getStringValue() {
         return value;
     }
-
-    @Override
-    public String toString() {
-        return getStringValue();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof StringLiteral)) {
-            return false;
-        }
-        StringLiteral s = (StringLiteral) obj;
-        return value.equals(s.getValue());
-    }
-
-    @Override
-    public int hashCode() {
-        return value.hashCode();
-    }
-
 }
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/TrueLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/TrueLiteral.java
index dedd52b..80d7966 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/TrueLiteral.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/TrueLiteral.java
@@ -1,8 +1,8 @@
 package edu.uci.ics.asterix.aql.literal;
 
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 
-public class TrueLiteral implements ILiteral {
+public class TrueLiteral extends Literal {
     private static final long serialVersionUID = -8513245514578847512L;
 
     private TrueLiteral() {
@@ -34,4 +34,9 @@
     public int hashCode() {
         return (int) serialVersionUID;
     }
+
+    @Override
+    public Boolean getValue() {
+        return Boolean.TRUE;
+    }
 }
diff --git a/asterix-aql/src/main/javacc/AQL.jj b/asterix-aql/src/main/javacc/AQL.jj
index b59dbd3..0767c4e 100644
--- a/asterix-aql/src/main/javacc/AQL.jj
+++ b/asterix-aql/src/main/javacc/AQL.jj
@@ -20,8 +20,9 @@
 import edu.uci.ics.asterix.aql.literal.FloatLiteral;
 import edu.uci.ics.asterix.aql.literal.DoubleLiteral;
 import edu.uci.ics.asterix.aql.literal.FalseLiteral;
-import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Literal;
 import edu.uci.ics.asterix.aql.literal.IntegerLiteral;
+import edu.uci.ics.asterix.aql.literal.LongIntegerLiteral;
 import edu.uci.ics.asterix.aql.literal.NullLiteral;
 import edu.uci.ics.asterix.aql.literal.StringLiteral;
 import edu.uci.ics.asterix.aql.literal.TrueLiteral;
@@ -1478,10 +1479,11 @@
 	{
 		if(expr.getKind() == Expression.Kind.LITERAL_EXPRESSION)
 		{
-			ILiteral lit = ((LiteralExpr)expr).getValue();
-			if(lit.getLiteralType() == ILiteral.Type.INTEGER) {
+			Literal lit = ((LiteralExpr)expr).getValue();
+			if(lit.getLiteralType() == Literal.Type.INTEGER || 
+			   lit.getLiteralType() == Literal.Type.LONG) {
 				idx = Integer.valueOf(lit.getStringValue());
-			}	
+			}
 			else {
 				throw new ParseException("Index should be an INTEGER");				
             }
@@ -1509,7 +1511,7 @@
   Expression expr = null;
 }
 {
-  //ILiteral | VariableRef | ListConstructor | RecordConstructor | FunctionCallExpr | ParenthesizedExpression
+  //Literal | VariableRef | ListConstructor | RecordConstructor | FunctionCallExpr | ParenthesizedExpression
 	(
 	  expr =Literal() 
 	   | expr = FunctionCallExpr()
@@ -1545,7 +1547,11 @@
  	 | <INTEGER_LITERAL>
     {
       t= getToken(0);
-	  lit.setValue(new IntegerLiteral(new Integer(t.image)));
+	  try {
+	      lit.setValue(new IntegerLiteral(new Integer(t.image)));
+	  } catch(NumberFormatException ex) {
+	      lit.setValue(new LongIntegerLiteral(new Long(t.image)));
+	  }
 	}
      | < FLOAT_LITERAL >
     {
@@ -1859,12 +1865,9 @@
 	extendCurrentScope();
 }
 {
-    "let" varExp = Variable()
+    "let" varExp = Variable() ":=" beExp = Expression()
     {
       getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
-	}
-     ":=" beExp = Expression()
-    {
       lc.setVarExpr(varExp);
       lc.setBeExpr(beExp);
       return lc;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
index 9ebf8d6..417948f 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -22,6 +22,8 @@
 import edu.uci.ics.asterix.om.typecomputer.impl.ARectangleTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.AStringTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.BinaryBooleanOrNullFunctionTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.BinaryStringBoolOrNullTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.BinaryStringStringOrNullTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.CastRecordResultTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.ClosedRecordConstructorResultType;
 import edu.uci.ics.asterix.om.typecomputer.impl.FieldAccessByIndexResultType;
@@ -31,6 +33,8 @@
 import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedGetItemResultType;
 import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedLocalAvgTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedNumericAddSubMulDivTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedNumericRoundHalfToEven2TypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedNumericUnaryFunctionTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedSumTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedSwitchCaseComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedUnaryMinusTypeComputer;
@@ -56,8 +60,15 @@
 import edu.uci.ics.asterix.om.typecomputer.impl.OrderedListOfAInt32TypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.OrderedListOfAStringTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.OrderedListOfAnyTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.QuadStringStringOrNullTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.ScalarVersionOfAggregateResultType;
+import edu.uci.ics.asterix.om.typecomputer.impl.Substring2TypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.SubstringTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.TripleStringBoolOrNullTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.TripleStringStringOrNullTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.UnaryBooleanOrNullFunctionTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.UnaryStringInt32OrNullTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.UnaryStringOrNullTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.UnorderedListConstructorResultType;
 import edu.uci.ics.asterix.om.types.AOrderedListType;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -152,6 +163,52 @@
             "numeric-idiv", 2);
     public final static FunctionIdentifier CARET = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "caret", 2);
 
+	public final static FunctionIdentifier NUMERIC_ABS = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "numeric-abs", 1);
+	public final static FunctionIdentifier NUMERIC_CEILING = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "numeric-ceiling", 1);
+	public final static FunctionIdentifier NUMERIC_FLOOR = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "numeric-floor", 1);
+	public final static FunctionIdentifier NUMERIC_ROUND = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "numeric-round", 1);
+	public final static FunctionIdentifier NUMERIC_ROUND_HALF_TO_EVEN = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "numeric-round-half-to-even", 1);
+	public final static FunctionIdentifier NUMERIC_ROUND_HALF_TO_EVEN2 = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "numeric-round-half-to-even2", 2);
+	// String funcitons
+	public final static FunctionIdentifier STRING_EQUAL = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "string-equal", 2);
+	public final static FunctionIdentifier STRING_START_WITH = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "start-with", 2);
+	public final static FunctionIdentifier STRING_END_WITH = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "end-with", 2);
+	public final static FunctionIdentifier STRING_MATCHES = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "matches", 2);
+	public final static FunctionIdentifier STRING_MATCHES_WITH_FLAG = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "matches2", 3);
+	public final static FunctionIdentifier STRING_LOWERCASE = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "lowercase", 1);
+	public final static FunctionIdentifier STRING_REPLACE = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "replace", 3);
+	public final static FunctionIdentifier STRING_REPLACE_WITH_FLAG = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "replace2", 4);
+	public final static FunctionIdentifier STRING_LENGTH = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "string-length", 1);
+	public final static FunctionIdentifier SUBSTRING2 = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "substring2", 2);
+	public final static FunctionIdentifier SUBSTRING_BEFORE = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "substring-before", 2);
+	public final static FunctionIdentifier SUBSTRING_AFTER = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "substring-after", 2);
+	public final static FunctionIdentifier STRING_TO_CODEPOINT = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "string-to-codepoint", 1);
+	public final static FunctionIdentifier CODEPOINT_TO_STRING = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "codepoint-to-string", 1);
+	public final static FunctionIdentifier STRING_CONCAT = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "string-concat", 1);
+	public final static FunctionIdentifier STRING_JOIN = new FunctionIdentifier(
+			FunctionConstants.ASTERIX_NS, "string-join", 2);
+
     public final static FunctionIdentifier DATASET = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "dataset", 1);
     public final static FunctionIdentifier FEED_INGEST = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "feed-ingest", 1);
@@ -466,6 +523,32 @@
         add(NUMERIC_DIVIDE, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
         add(NUMERIC_MOD, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
         add(NUMERIC_IDIV, AInt32TypeComputer.INSTANCE);
+        
+        // Xiaoyu Ma Add for new functions
+        add(NUMERIC_ABS, NonTaggedNumericUnaryFunctionTypeComputer.INSTANCE);
+        add(NUMERIC_CEILING, NonTaggedNumericUnaryFunctionTypeComputer.INSTANCE);
+        add(NUMERIC_FLOOR, NonTaggedNumericUnaryFunctionTypeComputer.INSTANCE);
+        add(NUMERIC_ROUND, NonTaggedNumericUnaryFunctionTypeComputer.INSTANCE);
+        add(NUMERIC_ROUND_HALF_TO_EVEN, NonTaggedNumericUnaryFunctionTypeComputer.INSTANCE);
+        add(NUMERIC_ROUND_HALF_TO_EVEN2, NonTaggedNumericRoundHalfToEven2TypeComputer.INSTANCE);
+        
+        add(STRING_TO_CODEPOINT, OrderedListOfAInt32TypeComputer.INSTANCE);
+        add(CODEPOINT_TO_STRING, AStringTypeComputer.INSTANCE);
+        add(STRING_CONCAT, AStringTypeComputer.INSTANCE);
+        add(SUBSTRING2, Substring2TypeComputer.INSTANCE);
+        add(STRING_LENGTH, UnaryStringInt32OrNullTypeComputer.INSTANCE);
+        add(STRING_LOWERCASE, UnaryStringOrNullTypeComputer.INSTANCE);
+        add(STRING_START_WITH, BinaryStringBoolOrNullTypeComputer.INSTANCE);
+        add(STRING_END_WITH, BinaryStringBoolOrNullTypeComputer.INSTANCE);
+        add(STRING_MATCHES, BinaryStringBoolOrNullTypeComputer.INSTANCE);
+        add(STRING_MATCHES_WITH_FLAG, TripleStringBoolOrNullTypeComputer.INSTANCE);
+        add(STRING_REPLACE, TripleStringStringOrNullTypeComputer.INSTANCE);
+        add(STRING_REPLACE_WITH_FLAG, QuadStringStringOrNullTypeComputer.INSTANCE);
+        add(SUBSTRING_BEFORE, BinaryStringStringOrNullTypeComputer.INSTANCE);
+        add(SUBSTRING_AFTER, BinaryStringStringOrNullTypeComputer.INSTANCE);
+        add(STRING_EQUAL, BinaryStringBoolOrNullTypeComputer.INSTANCE);
+        add(STRING_JOIN, AStringTypeComputer.INSTANCE);
+        
         add(OPEN_RECORD_CONSTRUCTOR, OpenRecordConstructorResultType.INSTANCE);
         add(ORDERED_LIST_CONSTRUCTOR, OrderedListConstructorResultType.INSTANCE);
         add(POINT_CONSTRUCTOR, OptionalAPointTypeComputer.INSTANCE);
@@ -537,7 +620,7 @@
                 }
             }
         });
-        add(SUBSTRING, AStringTypeComputer.INSTANCE);
+        add(SUBSTRING, SubstringTypeComputer.INSTANCE);
         add(SUM, NonTaggedSumTypeComputer.INSTANCE);
         add(SWITCH_CASE, NonTaggedSwitchCaseComputer.INSTANCE);
         add(REG_EXP, ABooleanTypeComputer.INSTANCE);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/AbstractBinaryStringTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/AbstractBinaryStringTypeComputer.java
new file mode 100644
index 0000000..0615de4
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/AbstractBinaryStringTypeComputer.java
@@ -0,0 +1,47 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+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.IAType;
+import edu.uci.ics.asterix.om.types.TypeHelper;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+abstract public class AbstractBinaryStringTypeComputer implements IResultTypeComputer {
+    
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression;
+        if(fce.getArguments().size() < 2)
+            throw new AlgebricksException("Wrong Argument Number.");        
+        ILogicalExpression arg0 = fce.getArguments().get(0).getValue();
+        ILogicalExpression arg1 = fce.getArguments().get(1).getValue();
+        IAType t0, t1;
+        try {
+            t0 = (IAType) env.getType(arg0);
+            t1 = (IAType) env.getType(arg1);
+        } catch (AlgebricksException e) {
+            throw new AlgebricksException(e);
+        }
+        if ((t0.getTypeTag() != ATypeTag.NULL && t0.getTypeTag() != ATypeTag.STRING) ||
+            (t1.getTypeTag() != ATypeTag.NULL && t1.getTypeTag() != ATypeTag.STRING)) {
+            throw new AlgebricksException("Expects String Type.");
+        }      
+
+        return getResultType(t0, t1);
+    }    
+    
+    
+    public abstract IAType getResultType(IAType t0, IAType t1);
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/AbstractQuadStringTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/AbstractQuadStringTypeComputer.java
new file mode 100644
index 0000000..0baf221
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/AbstractQuadStringTypeComputer.java
@@ -0,0 +1,50 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public abstract class AbstractQuadStringTypeComputer implements IResultTypeComputer {
+    
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression;
+        if(fce.getArguments().size() < 4)
+            throw new AlgebricksException("Wrong Argument Number.");        
+        ILogicalExpression arg0 = fce.getArguments().get(0).getValue();
+        ILogicalExpression arg1 = fce.getArguments().get(1).getValue();
+        ILogicalExpression arg2 = fce.getArguments().get(2).getValue();  
+        ILogicalExpression arg3 = fce.getArguments().get(3).getValue();                
+        IAType t0, t1, t2, t3;
+        try {
+            t0 = (IAType) env.getType(arg0);
+            t1 = (IAType) env.getType(arg1);
+            t2 = (IAType) env.getType(arg2);    
+            t3 = (IAType) env.getType(arg3);              
+        } catch (AlgebricksException e) {
+            throw new AlgebricksException(e);
+        }
+        if ((t0.getTypeTag() != ATypeTag.NULL && t0.getTypeTag() != ATypeTag.STRING) || 
+            (t1.getTypeTag() != ATypeTag.NULL && t1.getTypeTag() != ATypeTag.STRING) ||
+            (t2.getTypeTag() != ATypeTag.NULL && t2.getTypeTag() != ATypeTag.STRING) ||
+            (t3.getTypeTag() != ATypeTag.NULL && t3.getTypeTag() != ATypeTag.STRING)) {
+            throw new NotImplementedException("Expects String Type.");
+        }
+
+        return getResultType(t0, t1, t2, t3);
+    }    
+    
+    
+    public abstract IAType getResultType(IAType t0, IAType t1, IAType t2, IAType t3);    
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/AbstractTripleStringTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/AbstractTripleStringTypeComputer.java
new file mode 100644
index 0000000..429f1f0
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/AbstractTripleStringTypeComputer.java
@@ -0,0 +1,46 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public abstract class AbstractTripleStringTypeComputer implements IResultTypeComputer {
+    
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression;
+        if(fce.getArguments().size() < 3)
+            throw new AlgebricksException("Wrong Argument Number.");            
+        ILogicalExpression arg0 = fce.getArguments().get(0).getValue();
+        ILogicalExpression arg1 = fce.getArguments().get(1).getValue();
+        ILogicalExpression arg2 = fce.getArguments().get(2).getValue();        
+        IAType t0, t1, t2;
+        try {
+            t0 = (IAType) env.getType(arg0);
+            t1 = (IAType) env.getType(arg1);
+            t2 = (IAType) env.getType(arg2);            
+        } catch (AlgebricksException e) {
+            throw new AlgebricksException(e);
+        }
+        if ((t0.getTypeTag() != ATypeTag.NULL   && t0.getTypeTag() != ATypeTag.STRING) || (t1.getTypeTag() != ATypeTag.NULL &&
+            t1.getTypeTag() != ATypeTag.STRING) || (t2.getTypeTag() != ATypeTag.NULL && t2.getTypeTag() != ATypeTag.STRING)) {
+            throw new AlgebricksException("Expects String Type.");
+        }
+
+        return getResultType(t0, t1, t2);
+    }    
+    
+    
+    public abstract IAType getResultType(IAType t0, IAType t1, IAType t2);
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/BinaryStringBoolOrNullTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/BinaryStringBoolOrNullTypeComputer.java
new file mode 100644
index 0000000..fa2a4a5
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/BinaryStringBoolOrNullTypeComputer.java
@@ -0,0 +1,23 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.types.TypeHelper;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public class BinaryStringBoolOrNullTypeComputer extends AbstractBinaryStringTypeComputer {
+    public static final BinaryStringBoolOrNullTypeComputer INSTANCE = new BinaryStringBoolOrNullTypeComputer();
+    private BinaryStringBoolOrNullTypeComputer() {}    
+    
+    @Override
+    public IAType getResultType(IAType t0, IAType t1) {
+        if (TypeHelper.canBeNull(t0) || TypeHelper.canBeNull(t1)) {
+            return AUnionType.createNullableType(BuiltinType.ABOOLEAN);
+        }        	
+        return BuiltinType.ABOOLEAN;
+    }    
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/BinaryStringStringOrNullTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/BinaryStringStringOrNullTypeComputer.java
new file mode 100644
index 0000000..0b24ff9
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/BinaryStringStringOrNullTypeComputer.java
@@ -0,0 +1,25 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.types.TypeHelper;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public class BinaryStringStringOrNullTypeComputer extends AbstractBinaryStringTypeComputer {
+    
+    public static final BinaryStringStringOrNullTypeComputer INSTANCE = new BinaryStringStringOrNullTypeComputer();
+    private BinaryStringStringOrNullTypeComputer() {}
+
+    @Override
+    public IAType getResultType(IAType t0, IAType t1) {
+        if (TypeHelper.canBeNull(t0) || TypeHelper.canBeNull(t1)) {
+            return AUnionType.createNullableType(BuiltinType.ASTRING);
+        }      	
+        return BuiltinType.ASTRING;
+    }
+    
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericRoundHalfToEven2TypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericRoundHalfToEven2TypeComputer.java
new file mode 100644
index 0000000..da90a06
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericRoundHalfToEven2TypeComputer.java
@@ -0,0 +1,98 @@
+/*
+ * Numeric round half to even
+ * Author : Xiaoyu Ma@UC Irvine
+ * 01/30/2012
+ */
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+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.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class NonTaggedNumericRoundHalfToEven2TypeComputer implements IResultTypeComputer {
+
+    public static final NonTaggedNumericRoundHalfToEven2TypeComputer INSTANCE =
+            new NonTaggedNumericRoundHalfToEven2TypeComputer();
+
+    private NonTaggedNumericRoundHalfToEven2TypeComputer() {
+    }
+
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression;
+        if(fce.getArguments().size() < 2)
+        	throw new AlgebricksException("Argument number invalid.");
+        
+        ILogicalExpression arg1 = fce.getArguments().get(0).getValue();
+        ILogicalExpression arg2 = fce.getArguments().get(1).getValue();
+        
+        IAType t1 = (IAType) env.getType(arg1);
+        IAType t2 = (IAType) env.getType(arg2);
+        
+        List<IAType> unionList = new ArrayList<IAType>();
+        unionList.add(BuiltinType.ANULL);        
+
+        ATypeTag tag1, tag2;
+        if (t1.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t1))
+            tag1 = ((AUnionType) t1).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
+                    .getTypeTag();
+        else
+            tag1 = t1.getTypeTag();
+
+        if (t2.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t2))
+            tag2 = ((AUnionType) t2).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
+                    .getTypeTag();
+        else
+            tag2 = t2.getTypeTag();
+        
+        switch(tag2) {
+	        case INT8:
+	        case INT16:
+	        case INT32:
+	        case INT64:
+	            break;
+	        default:
+	            throw new AlgebricksException("Argument $precision cannot be type " + t2.getTypeName());
+        }        
+        
+        switch (tag1) {
+            case INT8:
+                unionList.add(BuiltinType.AINT8);
+                break;                
+            case INT16:
+                unionList.add(BuiltinType.AINT16);
+                break;                 
+            case INT32:
+                unionList.add(BuiltinType.AINT32);
+                break;                 
+            case INT64:
+                unionList.add(BuiltinType.AINT64);
+                break;                 
+            case FLOAT:
+                unionList.add(BuiltinType.AFLOAT);
+                break;                 
+            case DOUBLE:
+                unionList.add(BuiltinType.ADOUBLE);
+                break;
+            case NULL:
+                return BuiltinType.ANULL;
+            default: {
+                throw new NotImplementedException("Arithmetic operations are not implemented for " + t1.getTypeName());
+            }
+        }
+
+        return new AUnionType(unionList, "NumericFuncionsResult");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericUnaryFunctionTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericUnaryFunctionTypeComputer.java
new file mode 100644
index 0000000..454104b
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericUnaryFunctionTypeComputer.java
@@ -0,0 +1,79 @@
+/*
+ * Numeric Unary Functions like abs
+ * Author : Xiaoyu Ma@UC Irvine
+ * 01/30/2012
+ */
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+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.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class NonTaggedNumericUnaryFunctionTypeComputer implements IResultTypeComputer {
+
+    private static final String errMsg = "Arithmetic operations are not implemented for ";
+    public static final NonTaggedNumericUnaryFunctionTypeComputer INSTANCE =
+            new NonTaggedNumericUnaryFunctionTypeComputer();
+
+    private NonTaggedNumericUnaryFunctionTypeComputer() {
+    }
+
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression;
+        if(fce.getArguments().isEmpty())
+            throw new AlgebricksException("Wrong Argument Number.");
+        
+        ILogicalExpression arg1 = fce.getArguments().get(0).getValue();
+
+        IAType t = (IAType) env.getType(arg1);
+        ATypeTag tag = t.getTypeTag();
+
+        if (tag == ATypeTag.UNION
+                && NonTaggedFormatUtil.isOptionalField((AUnionType) env.getType(arg1))) {
+            return (IAType) env.getType(arg1);
+        }
+        
+        List<IAType> unionList = new ArrayList<IAType>();
+        unionList.add(BuiltinType.ANULL);
+        switch (tag) {
+            case INT8:
+                unionList.add(BuiltinType.AINT8);
+                break;                
+            case INT16:
+                unionList.add(BuiltinType.AINT16);
+                break;                 
+            case INT32:
+                unionList.add(BuiltinType.AINT32);
+                break;                 
+            case INT64:
+                unionList.add(BuiltinType.AINT64);
+                break;                 
+            case FLOAT:
+                unionList.add(BuiltinType.AFLOAT);
+                break;                 
+            case DOUBLE:
+                unionList.add(BuiltinType.ADOUBLE);
+                break;
+            case NULL:
+                return BuiltinType.ANULL;
+            default: {
+                throw new NotImplementedException(errMsg + t.getTypeName());
+            }
+        }
+
+        return new AUnionType(unionList, "NumericUnaryFuncionsResult");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/QuadStringStringOrNullTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/QuadStringStringOrNullTypeComputer.java
new file mode 100644
index 0000000..876df7a
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/QuadStringStringOrNullTypeComputer.java
@@ -0,0 +1,25 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.types.TypeHelper;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public class QuadStringStringOrNullTypeComputer  extends AbstractQuadStringTypeComputer {
+    public static final QuadStringStringOrNullTypeComputer INSTANCE = new QuadStringStringOrNullTypeComputer();
+    private QuadStringStringOrNullTypeComputer() {}
+
+    @Override
+    public IAType getResultType(IAType t0, IAType t1, IAType t2, IAType t3) {
+        if (TypeHelper.canBeNull(t0) || TypeHelper.canBeNull(t1) || 
+        	TypeHelper.canBeNull(t2) || TypeHelper.canBeNull(t3)) {
+            return AUnionType.createNullableType(BuiltinType.ASTRING);
+        }      	
+        return BuiltinType.ASTRING;
+    }
+    
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/Substring2TypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/Substring2TypeComputer.java
new file mode 100644
index 0000000..c5d224c
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/Substring2TypeComputer.java
@@ -0,0 +1,63 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+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.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+
+
+public class Substring2TypeComputer implements IResultTypeComputer {
+    public static final Substring2TypeComputer INSTANCE = new Substring2TypeComputer();
+    
+    
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression;
+        if(fce.getArguments().size() < 2)
+            throw new AlgebricksException("Wrong Argument Number.");            
+        ILogicalExpression arg0 = fce.getArguments().get(0).getValue();
+        ILogicalExpression arg1 = fce.getArguments().get(1).getValue();       
+        IAType t0, t1;
+        try {
+            t0 = (IAType) env.getType(arg0);
+            t1 = (IAType) env.getType(arg1);                  
+        } catch (AlgebricksException e) {
+            throw new AlgebricksException(e);
+        }
+        
+        ATypeTag tag0, tag1;
+        if (t0.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t0))
+            tag0 = ((AUnionType) t0).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
+                    .getTypeTag();
+        else
+            tag0 = t0.getTypeTag();
+        
+        if (t1.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t1))
+            tag1 = ((AUnionType) t1).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
+                    .getTypeTag();
+        else
+            tag1 = t1.getTypeTag();        
+        
+        if(tag0 != ATypeTag.NULL && tag0 != ATypeTag.STRING) {
+            throw new AlgebricksException("First argument should be String Type.");
+        }
+        
+        if(tag1 != ATypeTag.NULL && 
+           tag1 != ATypeTag.INT8 && 
+           tag1 != ATypeTag.INT16 && 
+           tag1 != ATypeTag.INT32 && 
+           tag1 != ATypeTag.INT64) {
+            throw new AlgebricksException("Second argument should be integer Type.");
+        }
+
+        return BuiltinType.ASTRING;
+    }   
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/SubstringTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/SubstringTypeComputer.java
new file mode 100644
index 0000000..b016de8
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/SubstringTypeComputer.java
@@ -0,0 +1,71 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+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.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+
+public class SubstringTypeComputer implements IResultTypeComputer {
+    public static final SubstringTypeComputer INSTANCE = new SubstringTypeComputer();
+
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression;
+        if (fce.getArguments().size() < 3)
+            throw new AlgebricksException("Wrong Argument Number.");
+        ILogicalExpression arg0 = fce.getArguments().get(0).getValue();
+        ILogicalExpression arg1 = fce.getArguments().get(1).getValue();
+        ILogicalExpression arg2 = fce.getArguments().get(2).getValue();
+        IAType t0, t1, t2;
+        try {
+            t0 = (IAType) env.getType(arg0);
+            t1 = (IAType) env.getType(arg1);
+            t2 = (IAType) env.getType(arg2);
+        } catch (AlgebricksException e) {
+            throw new AlgebricksException(e);
+        }
+
+        ATypeTag tag0, tag1, tag2;
+        if (t0.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t0))
+            tag0 = ((AUnionType) t0).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
+                    .getTypeTag();
+        else
+            tag0 = t0.getTypeTag();
+
+        if (t1.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t1))
+            tag1 = ((AUnionType) t1).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
+                    .getTypeTag();
+        else
+            tag1 = t1.getTypeTag();
+
+        if (t2.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t2))
+            tag2 = ((AUnionType) t2).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST)
+                    .getTypeTag();
+        else
+            tag2 = t2.getTypeTag();
+
+        if (tag0 != ATypeTag.NULL && tag0 != ATypeTag.STRING) {
+            throw new AlgebricksException("First argument should be String Type.");
+        }
+
+        if (tag1 != ATypeTag.NULL && tag1 != ATypeTag.INT8 && tag1 != ATypeTag.INT16 && tag1 != ATypeTag.INT32
+                && tag1 != ATypeTag.INT64) {
+            throw new AlgebricksException("Second argument should be integer Type.");
+        }
+
+        if (tag2 != ATypeTag.NULL && tag2 != ATypeTag.INT8 && tag2 != ATypeTag.INT16 && tag2 != ATypeTag.INT32
+                && tag2 != ATypeTag.INT64) {
+            throw new AlgebricksException("Third argument should be integer Type.");
+        }
+
+        return BuiltinType.ASTRING;
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/TripleStringBoolOrNullTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/TripleStringBoolOrNullTypeComputer.java
new file mode 100644
index 0000000..0bac1df
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/TripleStringBoolOrNullTypeComputer.java
@@ -0,0 +1,23 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.types.TypeHelper;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public class TripleStringBoolOrNullTypeComputer  extends AbstractTripleStringTypeComputer {
+    public static final TripleStringBoolOrNullTypeComputer INSTANCE = new TripleStringBoolOrNullTypeComputer();
+    private TripleStringBoolOrNullTypeComputer() {}    
+    @Override
+    public IAType getResultType(IAType t0, IAType t1, IAType t2) {
+        if (TypeHelper.canBeNull(t0) || TypeHelper.canBeNull(t1) || TypeHelper.canBeNull(t2)) {
+            return AUnionType.createNullableType(BuiltinType.ABOOLEAN);
+        }    	
+        return BuiltinType.ABOOLEAN;
+    }
+    
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/TripleStringStringOrNullTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/TripleStringStringOrNullTypeComputer.java
new file mode 100644
index 0000000..10154b0
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/TripleStringStringOrNullTypeComputer.java
@@ -0,0 +1,23 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.types.TypeHelper;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public class TripleStringStringOrNullTypeComputer  extends AbstractTripleStringTypeComputer {
+    public static final TripleStringStringOrNullTypeComputer INSTANCE = new TripleStringStringOrNullTypeComputer();
+    private TripleStringStringOrNullTypeComputer() {}
+
+    @Override
+    public IAType getResultType(IAType t0, IAType t1, IAType t2) {
+        if (TypeHelper.canBeNull(t0) || TypeHelper.canBeNull(t1) || TypeHelper.canBeNull(t2)) {
+            return AUnionType.createNullableType(BuiltinType.ASTRING);
+        }      	
+        return BuiltinType.ASTRING;
+    } 
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnaryStringInt32OrNullTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnaryStringInt32OrNullTypeComputer.java
new file mode 100644
index 0000000..bcd45a7
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnaryStringInt32OrNullTypeComputer.java
@@ -0,0 +1,59 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+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.IAType;
+import edu.uci.ics.asterix.om.types.TypeHelper;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public class UnaryStringInt32OrNullTypeComputer implements IResultTypeComputer  {   
+    
+    public static final UnaryStringInt32OrNullTypeComputer INSTANCE = new UnaryStringInt32OrNullTypeComputer();
+    private UnaryStringInt32OrNullTypeComputer() {}
+    
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression;
+        if(fce.getArguments().isEmpty())
+            throw new AlgebricksException("Wrong Argument Number.");        
+        ILogicalExpression arg0 = fce.getArguments().get(0).getValue();
+        IAType t0;
+        try {
+            t0 = (IAType) env.getType(arg0);
+        } catch (AlgebricksException e) {
+            throw new AlgebricksException(e);
+        }
+        if (t0.getTypeTag() != ATypeTag.NULL &&
+            t0.getTypeTag() != ATypeTag.STRING ) {
+            throw new NotImplementedException("Expects String Type.");
+        }     
+        
+        List<IAType> unionList = new ArrayList<IAType>();
+        unionList.add(BuiltinType.ANULL);
+        if(t0.getTypeTag() == ATypeTag.NULL) {
+            return BuiltinType.ANULL;
+        }
+        
+        if(t0.getTypeTag() == ATypeTag.STRING) {
+            unionList.add(BuiltinType.AINT32);
+        }        
+        
+        return new AUnionType(unionList, "String-length-Result");
+    }      
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnaryStringOrNullTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnaryStringOrNullTypeComputer.java
new file mode 100644
index 0000000..d26a43f
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnaryStringOrNullTypeComputer.java
@@ -0,0 +1,52 @@
+package edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+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.IAType;
+import edu.uci.ics.asterix.om.types.TypeHelper;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public class UnaryStringOrNullTypeComputer implements IResultTypeComputer  {   
+    
+    public static final UnaryStringOrNullTypeComputer INSTANCE = new UnaryStringOrNullTypeComputer();
+    private UnaryStringOrNullTypeComputer() {}
+    
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression;
+        if(fce.getArguments().isEmpty())
+            throw new AlgebricksException("Wrong Argument Number.");        
+        ILogicalExpression arg0 = fce.getArguments().get(0).getValue();
+        IAType t0;
+        try {
+            t0 = (IAType) env.getType(arg0);
+        } catch (AlgebricksException e) {
+            throw new AlgebricksException(e);
+        }
+        
+        if (TypeHelper.canBeNull(t0)) {
+            return AUnionType.createNullableType(BuiltinType.ASTRING);
+        }            
+        
+        if (t0.getTypeTag() == ATypeTag.NULL)
+        	return BuiltinType.ANULL;
+        
+        if(t0.getTypeTag() == ATypeTag.STRING) 
+        	return BuiltinType.ASTRING;
+        
+        throw new AlgebricksException("Expects String Type.");        
+    }      
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractBinaryStringBoolEval.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractBinaryStringBoolEval.java
new file mode 100644
index 0000000..c9834ac
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractBinaryStringBoolEval.java
@@ -0,0 +1,109 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+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.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+import java.io.DataOutput;
+import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public abstract class AbstractBinaryStringBoolEval implements ICopyEvaluator {
+
+    private DataOutput dout;
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private ArrayBackedValueStorage array0 = new ArrayBackedValueStorage();
+    private ArrayBackedValueStorage array1 = new ArrayBackedValueStorage();
+    private ICopyEvaluator evalLeft;
+    private ICopyEvaluator evalRight;
+    @SuppressWarnings({ "rawtypes" })
+    private ISerializerDeserializer boolSerde = AqlSerializerDeserializerProvider.INSTANCE
+            .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+
+    public AbstractBinaryStringBoolEval(DataOutput dout, ICopyEvaluatorFactory evalLeftFactory,
+            ICopyEvaluatorFactory evalRightFactory) throws AlgebricksException {
+        this.dout = dout;
+        this.evalLeft = evalLeftFactory.createEvaluator(array0);
+        this.evalRight = evalRightFactory.createEvaluator(array1);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+        array0.reset();
+        evalLeft.evaluate(tuple);
+        array1.reset();
+        evalRight.evaluate(tuple);
+
+        try {
+            if (array0.getByteArray()[0] == SER_NULL_TYPE_TAG && array1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+                try {
+                    boolSerde.serialize(ABoolean.TRUE, dout);
+                } catch (HyracksDataException ex) {
+                    Logger.getLogger(AbstractBinaryStringBoolEval.class.getName()).log(Level.SEVERE, null, ex);
+                }
+                return;
+            } else if (array0.getByteArray()[0] == SER_NULL_TYPE_TAG || array1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+                boolSerde.serialize(ABoolean.FALSE, dout);
+                return;
+            }
+        } catch (HyracksDataException e) {
+            throw new AlgebricksException(e);
+        }
+
+        byte[] b1 = array0.getByteArray();
+        byte[] b2 = array1.getByteArray();
+
+        int lLen = array0.getLength();
+        int rLen = array1.getLength();
+
+        int lStart = array0.getStartOffset();
+        int rStart = array1.getStartOffset();
+        ABoolean res = compute(b1, lLen, lStart, b2, rLen, rStart, array0, array1) ? ABoolean.TRUE : ABoolean.FALSE;
+        try {
+            boolSerde.serialize(res, dout);
+        } catch (HyracksDataException e) {
+            throw new AlgebricksException(e);
+        }
+    }
+
+    protected abstract boolean compute(byte[] lBytes, int lLen, int lStart, byte[] rBytes, int rLen, int rStart,
+            ArrayBackedValueStorage array0, ArrayBackedValueStorage array1) throws AlgebricksException;
+
+    protected 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 final static char[] reservedRegexChars = new char[] { '\\', '(', ')', '[', ']', '{', '}', '.', '^', '$',
+            '*', '|' };
+    static {
+        Arrays.sort(reservedRegexChars);
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
new file mode 100644
index 0000000..96a2876
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
@@ -0,0 +1,222 @@
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.common.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;
+
+@SuppressWarnings("serial")
+public abstract class AbstractNumericArithmeticEval extends AbstractScalarFunctionDynamicDescriptor {
+
+    
+    abstract protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException;
+    abstract protected double evaluateDouble(double lhs, double rhs) throws HyracksDataException;
+    
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+                return new ICopyEvaluator() {
+                    private DataOutput out = output.getDataOutput();
+                    // one temp. buffer re-used by both children
+                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+                    private ICopyEvaluator evalLeft = args[0].createEvaluator(argOut);
+                    private ICopyEvaluator evalRight = args[1].createEvaluator(argOut);
+                    private double[] operandsFloating = new double[args.length];
+                    private long[]   operandsInteger  = new long[args.length];
+                    private int      resultType;
+                    static protected final int typeInt8 = 1;
+                    static protected final int typeInt16 = 2;
+                    static protected final int typeInt32 = 3;
+                    static protected final int typeInt64 = 4;
+                    static protected final int typeFloat = 5;
+                    static protected final int typeDouble = 6;
+                    
+                    
+                    protected AMutableFloat aFloat = new AMutableFloat(0);
+                    protected AMutableDouble aDouble = new AMutableDouble(0);
+                    protected AMutableInt64 aInt64 = new AMutableInt64(0);
+                    protected AMutableInt32 aInt32 = new AMutableInt32(0);
+                    protected AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+                    protected AMutableInt8 aInt8 = new AMutableInt8((byte) 0);                    
+                    private ATypeTag typeTag;
+                    @SuppressWarnings("rawtypes")
+                    private ISerializerDeserializer serde;
+
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+                        try {
+                            resultType = 0;
+                            int currentType = 0;
+                            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.getByteArray()[0]);
+                                switch (typeTag) {
+                                    case INT8: {   
+                                        currentType = typeInt8;
+                                        operandsInteger[i] = AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
+                                        operandsFloating[i] = AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
+                                        break;
+                                    }
+                                    case INT16: {
+                                        currentType = typeInt16;
+                                        operandsInteger[i] = AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
+                                        operandsFloating[i] = AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
+                                        break;
+                                    }
+                                    case INT32: {
+                                        currentType = typeInt32;
+                                        operandsInteger[i] = AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
+                                        operandsFloating[i] = AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
+                                        break;
+                                    }
+                                    case INT64: {
+                                        currentType = typeInt64;
+                                        operandsInteger[i] = AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
+                                        operandsFloating[i] = AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
+                                        break;
+                                    }
+                                    case FLOAT: {
+                                        currentType = typeFloat;
+                                        operandsFloating[i] = AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
+                                        break;
+                                    }
+                                    case DOUBLE: {
+                                        currentType = typeDouble;
+                                        operandsFloating[i] = ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 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
+                                                                .getByteArray()[0]));
+                                    }
+                                }
+                                
+                                if(resultType < currentType) {
+                                    resultType = currentType;
+                                }
+                            }
+                            
+                            long lres = 0;
+                            double dres = 0;
+                            switch(resultType) {
+                                case typeInt8:
+                                    serde = AqlSerializerDeserializerProvider.INSTANCE
+                                    .getSerializerDeserializer(BuiltinType.AINT8);
+                                    lres = evaluateInteger(operandsInteger[0], operandsInteger[1]);
+                                    if(lres > Byte.MAX_VALUE) {
+                                        throw new AlgebricksException("Overflow happened.");
+                                    } 
+                                    if(lres < Byte.MIN_VALUE) {
+                                        throw new AlgebricksException("Underflow happened.");
+                                    }                                     
+                                    aInt8.setValue((byte)lres);
+                                    serde.serialize(aInt8, out);                
+                                    break;                                
+                                case typeInt16:
+                                    serde = AqlSerializerDeserializerProvider.INSTANCE
+                                    .getSerializerDeserializer(BuiltinType.AINT16);
+                                    lres = evaluateInteger(operandsInteger[0], operandsInteger[1]);
+                                    if(lres > Short.MAX_VALUE) {
+                                        throw new AlgebricksException("Overflow happened.");
+                                    } 
+                                    if(lres < Short.MIN_VALUE) {
+                                        throw new AlgebricksException("Underflow happened.");
+                                    }                                    
+                                    aInt16.setValue((short)lres);
+                                    serde.serialize(aInt16, out);                
+                                    break;
+                                case typeInt32:
+                                    serde = AqlSerializerDeserializerProvider.INSTANCE
+                                    .getSerializerDeserializer(BuiltinType.AINT32);
+                                    lres = evaluateInteger(operandsInteger[0], operandsInteger[1]);
+                                    if(lres > Integer.MAX_VALUE) {
+                                        throw new AlgebricksException("Overflow happened.");
+                                    } 
+                                    if(lres < Integer.MIN_VALUE) {
+                                        throw new AlgebricksException("Underflow happened.");
+                                    }                                      
+                                    aInt32.setValue((int)lres);
+                                    serde.serialize(aInt32, out);                 
+                                    break;
+                                case typeInt64:
+                                    serde = AqlSerializerDeserializerProvider.INSTANCE
+                                    .getSerializerDeserializer(BuiltinType.AINT64);
+                                    lres = evaluateInteger(operandsInteger[0], operandsInteger[1]);                                      
+                                    aInt64.setValue(lres);
+                                    serde.serialize(aInt64, out);                   
+                                    break;
+                                case typeFloat:
+                                    serde = AqlSerializerDeserializerProvider.INSTANCE
+                                    .getSerializerDeserializer(BuiltinType.AFLOAT);
+                                    dres = evaluateDouble(operandsFloating[0], operandsFloating[1]);
+                                    if(dres > Float.MAX_VALUE) {
+                                        throw new AlgebricksException("Overflow happened.");
+                                    } 
+                                    if(dres < - Float.MAX_VALUE) {
+                                        throw new AlgebricksException("Underflow happened.");
+                                    }                                      
+                                    aFloat.setValue((float)dres);
+                                    serde.serialize(aFloat, out);                   
+                                    break;                                    
+                                case typeDouble:
+                                    serde = AqlSerializerDeserializerProvider.INSTANCE
+                                    .getSerializerDeserializer(BuiltinType.ADOUBLE);
+                                    aDouble.setValue(evaluateDouble(operandsFloating[0], operandsFloating[1]));
+                                    serde.serialize(aDouble, out);                   
+                                    break;
+                            }                                                   
+                        } catch (HyracksDataException hde) {
+                            throw new AlgebricksException(hde);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java
new file mode 100644
index 0000000..a0befd8
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java
@@ -0,0 +1,169 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+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.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+/**
+ * @author ilovesoup
+ */
+public abstract class AbstractQuadStringStringEval implements ICopyEvaluator {
+
+    private DataOutput dout;
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+    private ArrayBackedValueStorage array0 = new ArrayBackedValueStorage();
+    private ArrayBackedValueStorage array1 = new ArrayBackedValueStorage();
+    private ArrayBackedValueStorage array2 = new ArrayBackedValueStorage();
+    private ArrayBackedValueStorage array3 = new ArrayBackedValueStorage();
+    private ICopyEvaluator eval0;
+    private ICopyEvaluator eval1;
+    private ICopyEvaluator eval2;
+    private ICopyEvaluator eval3;
+
+    private AMutableString resultBuffer = new AMutableString("");
+    @SuppressWarnings("rawtypes")
+    private ISerializerDeserializer nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+            .getSerializerDeserializer(BuiltinType.ANULL);
+    @SuppressWarnings("rawtypes")
+    private ISerializerDeserializer strSerde = AqlSerializerDeserializerProvider.INSTANCE
+            .getSerializerDeserializer(BuiltinType.ASTRING);
+
+    public AbstractQuadStringStringEval(DataOutput dout, ICopyEvaluatorFactory eval0, ICopyEvaluatorFactory eval1,
+            ICopyEvaluatorFactory eval2, ICopyEvaluatorFactory eval3) throws AlgebricksException {
+        this.dout = dout;
+        this.eval0 = eval0.createEvaluator(array0);
+        this.eval1 = eval1.createEvaluator(array1);
+        this.eval2 = eval2.createEvaluator(array2);
+        this.eval3 = eval3.createEvaluator(array3);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+        array0.reset();
+        eval0.evaluate(tuple);
+        array1.reset();
+        eval1.evaluate(tuple);
+        array2.reset();
+        eval2.evaluate(tuple);
+        array3.reset();
+        eval3.evaluate(tuple);
+
+        try {
+            if (array0.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+                nullSerde.serialize(ANull.NULL, dout);
+                return;
+            } else if (array0.getByteArray()[0] == SER_STRING_TYPE_TAG) {
+                if (array0.getByteArray()[1] == SER_NULL_TYPE_TAG) {
+                    dout.write(array0.getByteArray(), array0.getStartOffset(), array0.getLength());
+                    return;
+                }
+
+            } else {
+                throw new AlgebricksException("Expects String Type.");
+            }
+        } catch (HyracksDataException e) {
+            throw new AlgebricksException(e);
+        } catch (IOException e) {
+            throw new AlgebricksException(e.getMessage());
+        }
+
+        byte[] b0 = array0.getByteArray();
+        byte[] b1 = array1.getByteArray();
+        byte[] b2 = array2.getByteArray();
+        byte[] b3 = array3.getByteArray();
+
+        int len0 = array0.getLength();
+        int len1 = array1.getLength();
+        int len2 = array2.getLength();
+        int len3 = array3.getLength();
+
+        int s0 = array0.getStartOffset();
+        int s1 = array1.getStartOffset();
+        int s2 = array2.getStartOffset();
+        int s3 = array3.getStartOffset();
+
+        String res = compute(b0, len0, s0, b1, len1, s1, b2, len2, s2, b3, len3, s3, array0, array1);
+        resultBuffer.setValue(res);
+        try {
+            strSerde.serialize(resultBuffer, dout);
+        } catch (HyracksDataException e) {
+            throw new AlgebricksException(e);
+        }
+    }
+
+    protected abstract String compute(byte[] b0, int l0, int s0, byte[] b1, int l1, int s1, byte[] b2, int l2, int s2,
+            byte[] b3, int l3, int s3, ArrayBackedValueStorage array0, ArrayBackedValueStorage array1)
+            throws AlgebricksException;
+
+    protected 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();
+    }
+
+    protected int toFlag(AString pattern) {
+        String str = pattern.getStringValue();
+        int flag = 0;
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            switch (c) {
+                case 's':
+                    flag |= Pattern.DOTALL;
+                    break;
+                case 'm':
+                    flag |= Pattern.MULTILINE;
+                    break;
+                case 'i':
+                    flag |= Pattern.CASE_INSENSITIVE;
+                    break;
+                case 'x':
+                    flag |= Pattern.COMMENTS;
+                    break;
+            }
+        }
+        return flag;
+    }
+
+    private final static char[] reservedRegexChars = new char[] { '\\', '(', ')', '[', ']', '{', '}', '.', '^', '$',
+            '*', '|' };
+
+    static {
+        Arrays.sort(reservedRegexChars);
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractTripleStringBoolEval.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractTripleStringBoolEval.java
new file mode 100644
index 0000000..e0f8fc9
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractTripleStringBoolEval.java
@@ -0,0 +1,141 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ABoolean;
+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.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+import java.io.DataOutput;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public abstract class AbstractTripleStringBoolEval implements ICopyEvaluator {
+
+    private DataOutput dout;
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private ArrayBackedValueStorage array0 = new ArrayBackedValueStorage();
+    private ArrayBackedValueStorage array1 = new ArrayBackedValueStorage();
+    private ArrayBackedValueStorage array2 = new ArrayBackedValueStorage();
+    private ICopyEvaluator eval0;
+    private ICopyEvaluator eval1;
+    private ICopyEvaluator eval2;
+    @SuppressWarnings("rawtypes")
+    private ISerializerDeserializer boolSerde = AqlSerializerDeserializerProvider.INSTANCE
+            .getSerializerDeserializer(BuiltinType.ABOOLEAN);
+
+    public AbstractTripleStringBoolEval(DataOutput dout, ICopyEvaluatorFactory eval0, ICopyEvaluatorFactory eval1,
+            ICopyEvaluatorFactory eval2) throws AlgebricksException {
+        this.dout = dout;
+        this.eval0 = eval0.createEvaluator(array0);
+        this.eval1 = eval1.createEvaluator(array1);
+        this.eval2 = eval2.createEvaluator(array2);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+        array0.reset();
+        eval0.evaluate(tuple);
+        array1.reset();
+        eval1.evaluate(tuple);
+        array2.reset();
+        eval2.evaluate(tuple);
+
+        try {
+            if (array0.getByteArray()[0] == SER_NULL_TYPE_TAG && array1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+                boolSerde.serialize(ABoolean.TRUE, dout);
+                return;
+            } else if (array0.getByteArray()[0] == SER_NULL_TYPE_TAG || array1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+                boolSerde.serialize(ABoolean.FALSE, dout);
+                return;
+            }
+        } catch (HyracksDataException e) {
+            throw new AlgebricksException(e);
+        }
+
+        byte[] b0 = array0.getByteArray();
+        byte[] b1 = array1.getByteArray();
+        byte[] b2 = array2.getByteArray();
+
+        int len0 = array0.getLength();
+        int len1 = array1.getLength();
+        int len2 = array2.getLength();
+
+        int s0 = array0.getStartOffset();
+        int s1 = array1.getStartOffset();
+        int s2 = array2.getStartOffset();
+
+        ABoolean res = compute(b0, len0, s0, b1, len1, s1, b2, len2, s2, array0, array1) ? ABoolean.TRUE
+                : ABoolean.FALSE;
+        try {
+            boolSerde.serialize(res, dout);
+        } catch (HyracksDataException e) {
+            throw new AlgebricksException(e);
+        }
+    }
+
+    protected abstract boolean compute(byte[] b0, int l0, int s0, byte[] b1, int l1, int s1, byte[] b2, int l2, int s2,
+            ArrayBackedValueStorage array0, ArrayBackedValueStorage array1) throws AlgebricksException;
+
+    protected 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();
+    }
+
+    protected int toFlag(AString pattern) {
+        String str = pattern.getStringValue();
+        int flag = 0;
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            switch (c) {
+                case 's':
+                    flag |= Pattern.DOTALL;
+                    break;
+                case 'm':
+                    flag |= Pattern.MULTILINE;
+                    break;
+                case 'i':
+                    flag |= Pattern.CASE_INSENSITIVE;
+                    break;
+                case 'x':
+                    flag |= Pattern.COMMENTS;
+                    break;
+            }
+        }
+        return flag;
+    }
+
+    private final static char[] reservedRegexChars = new char[] { '\\', '(', ')', '[', ']', '{', '}', '.', '^', '$',
+            '*', '|' };
+
+    static {
+        Arrays.sort(reservedRegexChars);
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractTripleStringStringEval.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractTripleStringStringEval.java
new file mode 100644
index 0000000..e82d30f
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractTripleStringStringEval.java
@@ -0,0 +1,156 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+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.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public abstract class AbstractTripleStringStringEval implements ICopyEvaluator {
+
+    private DataOutput dout;
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+    private ArrayBackedValueStorage array0 = new ArrayBackedValueStorage();
+    private ArrayBackedValueStorage array1 = new ArrayBackedValueStorage();
+    private ArrayBackedValueStorage array2 = new ArrayBackedValueStorage();
+    private ICopyEvaluator eval0;
+    private ICopyEvaluator eval1;
+    private ICopyEvaluator eval2;
+
+    private AMutableString resultBuffer = new AMutableString("");
+    @SuppressWarnings("rawtypes")
+    private ISerializerDeserializer nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+            .getSerializerDeserializer(BuiltinType.ANULL);
+    @SuppressWarnings("rawtypes")
+    private ISerializerDeserializer strSerde = AqlSerializerDeserializerProvider.INSTANCE
+            .getSerializerDeserializer(BuiltinType.ASTRING);
+
+    public AbstractTripleStringStringEval(DataOutput dout, ICopyEvaluatorFactory eval0, ICopyEvaluatorFactory eval1,
+            ICopyEvaluatorFactory eval2) throws AlgebricksException {
+        this.dout = dout;
+        this.eval0 = eval0.createEvaluator(array0);
+        this.eval1 = eval1.createEvaluator(array1);
+        this.eval2 = eval2.createEvaluator(array2);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+        array0.reset();
+        eval0.evaluate(tuple);
+        array1.reset();
+        eval1.evaluate(tuple);
+        array2.reset();
+        eval2.evaluate(tuple);
+
+        try {
+            if (array0.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+                nullSerde.serialize(ANull.NULL, dout);
+                return;
+            } else if (array0.getByteArray()[0] == SER_STRING_TYPE_TAG) {
+                if (array0.getByteArray()[1] == SER_NULL_TYPE_TAG) {
+                    dout.write(array0.getByteArray(), array0.getStartOffset(), array0.getLength());
+                    return;
+                }
+
+            } else {
+                throw new AlgebricksException("Expects String Type.");
+            }
+        } catch (HyracksDataException e) {
+            throw new AlgebricksException(e);
+        } catch (IOException e) {
+            throw new AlgebricksException(e.getMessage());
+        }
+
+        byte[] b0 = array0.getByteArray();
+        byte[] b1 = array1.getByteArray();
+        byte[] b2 = array2.getByteArray();
+
+        int len0 = array0.getLength();
+        int len1 = array1.getLength();
+        int len2 = array2.getLength();
+
+        int s0 = array0.getStartOffset();
+        int s1 = array1.getStartOffset();
+        int s2 = array2.getStartOffset();
+
+        String res = compute(b0, len0, s0, b1, len1, s1, b2, len2, s2, array0, array1);
+        resultBuffer.setValue(res);
+        try {
+            strSerde.serialize(resultBuffer, dout);
+        } catch (HyracksDataException e) {
+            throw new AlgebricksException(e);
+        }
+    }
+
+    protected abstract String compute(byte[] b0, int l0, int s0, byte[] b1, int l1, int s1, byte[] b2, int l2, int s2,
+            ArrayBackedValueStorage array0, ArrayBackedValueStorage array1) throws AlgebricksException;
+
+    protected 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();
+    }
+
+    protected int toFlag(AString pattern) {
+        String str = pattern.getStringValue();
+        int flag = 0;
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            switch (c) {
+                case 's':
+                    flag |= Pattern.DOTALL;
+                    break;
+                case 'm':
+                    flag |= Pattern.MULTILINE;
+                    break;
+                case 'i':
+                    flag |= Pattern.CASE_INSENSITIVE;
+                    break;
+                case 'x':
+                    flag |= Pattern.COMMENTS;
+                    break;
+            }
+        }
+        return flag;
+    }
+
+    private final static char[] reservedRegexChars = new char[] { '\\', '(', ')', '[', ']', '{', '}', '.', '^', '$',
+            '*', '|' };
+
+    static {
+        Arrays.sort(reservedRegexChars);
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CodePointToStringDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CodePointToStringDescriptor.java
new file mode 100644
index 0000000..7e27463
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CodePointToStringDescriptor.java
@@ -0,0 +1,152 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+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.AInt32SerializerDeserializer;
+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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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.util.StringUtils;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class CodePointToStringDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "codepoint-to-string", 1);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new CodePointToStringDescriptor();
+        }
+    };
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+    private final static byte[] currentUTF8 = new byte[6];
+    private final byte stringTypeTag = ATypeTag.STRING.serialize();
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+
+            private static final long serialVersionUID = 1L;
+
+            private int codePointToUTF8(int c) {
+                if (c < 0x80) {
+                    currentUTF8[0] = (byte) (c & 0x7F /*mask 7 lsb: 0b1111111 */);
+                    return 1;
+                } else if (c < 0x0800) {
+                    currentUTF8[0] = (byte) (c >> 6 & 0x1F | 0xC0);
+                    currentUTF8[1] = (byte) (c & 0x3F | 0x80);
+                    return 2;
+                } else if (c < 0x010000) {
+                    currentUTF8[0] = (byte) (c >> 12 & 0x0F | 0xE0);
+                    currentUTF8[1] = (byte) (c >> 6 & 0x3F | 0x80);
+                    currentUTF8[2] = (byte) (c & 0x3F | 0x80);
+                    return 3;
+                } else if (c < 0x200000) {
+                    currentUTF8[0] = (byte) (c >> 18 & 0x07 | 0xF0);
+                    currentUTF8[1] = (byte) (c >> 12 & 0x3F | 0x80);
+                    currentUTF8[2] = (byte) (c >> 6 & 0x3F | 0x80);
+                    currentUTF8[3] = (byte) (c & 0x3F | 0x80);
+                    return 4;
+                } else if (c < 0x4000000) {
+                    currentUTF8[0] = (byte) (c >> 24 & 0x03 | 0xF8);
+                    currentUTF8[1] = (byte) (c >> 18 & 0x3F | 0x80);
+                    currentUTF8[2] = (byte) (c >> 12 & 0x3F | 0x80);
+                    currentUTF8[3] = (byte) (c >> 6 & 0x3F | 0x80);
+                    currentUTF8[4] = (byte) (c & 0x3F | 0x80);
+                    return 5;
+                } else if (c < 0x80000000) {
+                    currentUTF8[0] = (byte) (c >> 30 & 0x01 | 0xFC);
+                    currentUTF8[1] = (byte) (c >> 24 & 0x3F | 0x80);
+                    currentUTF8[2] = (byte) (c >> 18 & 0x3F | 0x80);
+                    currentUTF8[3] = (byte) (c >> 12 & 0x3F | 0x80);
+                    currentUTF8[4] = (byte) (c >> 6 & 0x3F | 0x80);
+                    currentUTF8[5] = (byte) (c & 0x3F | 0x80);
+                    return 6;
+                }
+                return 0;
+            }
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ICopyEvaluatorFactory listEvalFactory = args[0];
+                    private ArrayBackedValueStorage outInputList = new ArrayBackedValueStorage();
+                    private ICopyEvaluator evalList = listEvalFactory.createEvaluator(outInputList);
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ANULL);
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        try {
+                            outInputList.reset();
+                            evalList.evaluate(tuple);
+                            byte[] serOrderedList = outInputList.getByteArray();
+                            if (serOrderedList[0] == SER_NULL_TYPE_TAG) {
+                                nullSerde.serialize(ANull.NULL, out);
+                                return;
+                            }
+                            if (serOrderedList[0] != SER_ORDEREDLIST_TYPE_TAG) {
+                                throw new AlgebricksException("Expects an Integer List."
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serOrderedList[0]));
+                            }
+                            int size = AOrderedListSerializerDeserializer.getNumberOfItems(serOrderedList);
+                            try {
+                                // calculate length first
+                                int utf_8_len = 0;
+                                for (int i = 0; i < size; i++) {
+                                    int itemOffset = AOrderedListSerializerDeserializer
+                                            .getItemOffset(serOrderedList, i);
+                                    int codePoint = AInt32SerializerDeserializer.getInt(serOrderedList, itemOffset);
+                                    utf_8_len += codePointToUTF8(codePoint);
+                                }
+                                out.writeByte(stringTypeTag);
+                                StringUtils.writeUTF8Len(utf_8_len, out);
+                                for (int i = 0; i < size; i++) {
+                                    int itemOffset = AOrderedListSerializerDeserializer
+                                            .getItemOffset(serOrderedList, i);
+                                    int codePoint = AInt32SerializerDeserializer.getInt(serOrderedList, itemOffset);
+                                    utf_8_len = codePointToUTF8(codePoint);
+                                    for (int j = 0; j < utf_8_len; j++) {
+                                        out.writeByte(currentUTF8[j]);
+                                    }
+                                }
+                            } catch (AsterixException ex) {
+                                throw new AlgebricksException(ex);
+                            }
+                        } catch (IOException e1) {
+                            throw new AlgebricksException(e1.getMessage());
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CodepointIterator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CodepointIterator.java
new file mode 100644
index 0000000..f103e0f
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CodepointIterator.java
@@ -0,0 +1,101 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
+
+/**
+ *
+ * @author Xiaoyu Ma
+ */
+public class CodepointIterator {
+    public void reset(byte [] buf, int startPos) {
+        this.buf = buf;
+        this.curPos = startPos + 2;
+        this.startPos = startPos;
+        len = UTF8StringPointable.getUTFLength(buf, startPos);        
+    }
+    
+    public int size() { return len; }
+
+    private byte[] buf;
+    private int curPos = 0;
+    private int len = 0;
+    private int startPos = 0;
+
+    public int getCodePoint() {
+        return UTF8ToCodePoint(buf, curPos);
+    }
+
+    public static int UTF8ToCodePoint(byte[] b, int s) {
+        if (b[s] >> 7 == 0) {
+            // 1 byte
+            return b[s];
+        } else if ((b[s] & 0xe0) == 0xc0) { /*
+             * 0xe0 = 0b1110000
+             */
+            // 2 bytes
+            return ((int) (b[s] & 0x1f)) << 6
+                    | /*
+                     * 0x3f = 0b00111111
+                     */ ((int) (b[s + 1] & 0x3f));
+        } else if ((b[s] & 0xf0) == 0xe0) {
+            // 3bytes
+            return ((int) (b[s] & 0xf)) << 12
+                    | ((int) (b[s + 1] & 0x3f)) << 6
+                    | ((int) (b[s + 2] & 0x3f));
+        } else if ((b[s] & 0xf8) == 0xf0) {
+            // 4bytes
+            return ((int) (b[s] & 0x7)) << 18
+                    | ((int) (b[s + 1] & 0x3f)) << 12
+                    | ((int) (b[s + 2] & 0x3f)) << 6
+                    | ((int) (b[s + 3] & 0x3f));
+        } else if ((b[s] & 0xfc) == 0xf8) {
+            // 5bytes
+            return ((int) (b[s] & 0x3)) << 24
+                    | ((int) (b[s + 1] & 0x3f)) << 18
+                    | ((int) (b[s + 2] & 0x3f)) << 12
+                    | ((int) (b[s + 3] & 0x3f)) << 6
+                    | ((int) (b[s + 4] & 0x3f));
+        } else if ((b[s] & 0xfe) == 0xfc) {
+            // 6bytes
+            return ((int) (b[s] & 0x1)) << 30
+                    | ((int) (b[s + 1] & 0x3f)) << 24
+                    | ((int) (b[s + 2] & 0x3f)) << 18
+                    | ((int) (b[s + 3] & 0x3f)) << 12
+                    | ((int) (b[s + 4] & 0x3f)) << 6
+                    | ((int) (b[s + 5] & 0x3f));
+        }
+        return 0;
+    }
+
+    public void next() {
+        int step = UTF8StringPointable.charSize(buf, curPos);
+        if(step + curPos < len + 2 + startPos)
+            curPos += step;
+    }
+
+    public boolean hasNext() {
+        int step = UTF8StringPointable.charSize(buf, curPos);
+        if(step + curPos < len + 2 + startPos)
+            return true;   
+        return false;
+    }
+    
+    public static int compare(CodepointIterator ls, CodepointIterator rs) {
+        CodepointIterator shortString = ls.size() < rs.size() ? ls : rs;
+        
+        while (true) {
+            int c1 = ls.getCodePoint();
+            int c2 = rs.getCodePoint();
+            if (c1 != c2) {
+                return c1 - c2;
+            }
+            if(shortString.hasNext()) {
+                ls.next();
+                rs.next();
+            } else {
+                break;
+            }
+        }
+        return ls.size() - rs.size();
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAbsDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAbsDescriptor.java
new file mode 100644
index 0000000..662e777
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAbsDescriptor.java
@@ -0,0 +1,145 @@
+/*
+ * Numeric function Absolute value
+ * Author : Xiaoyu Ma@UC Irvine
+ * 01/30/2012
+ */
+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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.common.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 NumericAbsDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+    public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "numeric-abs", 1);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new NumericAbsDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+                    private ICopyEvaluator 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("rawtypes")
+                    private ISerializerDeserializer serde;
+
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        argOut.reset();
+                        eval.evaluate(tuple);
+                        try {
+                            if (argOut.getByteArray()[0] == serNullTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ANULL);
+                                serde.serialize(ANull.NULL, out);
+                            } else if (argOut.getByteArray()[0] == serInt8TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT8);
+                                byte val = (byte) AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
+                                aInt8.setValue((val <= 0) ? (byte) (0 - val) : val);
+                                serde.serialize(aInt8, out);
+                            } else if (argOut.getByteArray()[0] == serInt16TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT16);
+                                short val = (short) AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
+                                aInt16.setValue((val <= 0) ? (short) (0 - val) : val);
+                                serde.serialize(aInt16, out);
+                            } else if (argOut.getByteArray()[0] == serInt32TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT32);
+                                int val = (int) AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
+                                aInt32.setValue((val <= 0) ? (0 - val) : val);
+                                serde.serialize(aInt32, out);
+                            } else if (argOut.getByteArray()[0] == serInt64TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT64);
+                                long val = (long) AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
+                                aInt64.setValue((val <= 0L) ? (0L - val) : val);
+                                serde.serialize(aInt64, out);
+                            } else if (argOut.getByteArray()[0] == serFloatTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AFLOAT);
+                                float val = (float) AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
+                                aFloat.setValue((val <= 0.0f) ? 0.0f - val : val);
+                                serde.serialize(aFloat, out);
+                            } else if (argOut.getByteArray()[0] == serDoubleTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ADOUBLE);
+                                double val = (double) ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 1);
+                                aDouble.setValue((val <= 0.0D) ? 0.0D - val : val);
+                                serde.serialize(aDouble, out);
+                            } else {
+                                throw new NotImplementedException("Numeric Abs is not implemented for "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[0]));
+                            }
+                        } catch (HyracksDataException e) {
+                            throw new AlgebricksException(e);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+}
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
index 27b4a2a..c2791b9 100644
--- 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
@@ -1,40 +1,12 @@
 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.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
-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.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
 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.runtime.base.ICopyEvaluator;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
-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 {
+public class NumericAddDescriptor extends AbstractNumericArithmeticEval {
 
     private static final long serialVersionUID = 1L;
     public final static FunctionIdentifier FID = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS,
@@ -51,129 +23,18 @@
     }
 
     @Override
-    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
-        return new ICopyEvaluatorFactory() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
-
-                return new ICopyEvaluator() {
-                    private DataOutput out = output.getDataOutput();
-                    // one temp. buffer re-used by both children
-                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
-                    private ICopyEvaluator evalLeft = args[0].createEvaluator(argOut);
-                    private ICopyEvaluator 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("rawtypes")
-                    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.getByteArray()[0]);
-                                switch (typeTag) {
-                                    case INT8: {
-                                        metInt8 = true;
-                                        operands[i] = AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case INT16: {
-                                        metInt16 = true;
-                                        operands[i] = AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case INT32: {
-                                        metInt32 = true;
-                                        operands[i] = AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case INT64: {
-                                        metInt64 = true;
-                                        operands[i] = AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case FLOAT: {
-                                        metFloat = true;
-                                        operands[i] = AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case DOUBLE: {
-                                        metDouble = true;
-                                        operands[i] = ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 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
-                                                        .getByteArray()[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);
-                        }
-                    }
-                };
-            }
-        };
+    protected long evaluateInteger(long x, long y) throws HyracksDataException {
+        long z = x + y;
+        if (x > 0) {
+            if (y > 0 && z < 0)
+                throw new ArithmeticException("Overflow adding " + x + " + " + y);
+        } else if (y < 0 && z > 0)
+            throw new ArithmeticException("Overflow adding " + x + " + " + y);
+        return z;
     }
 
+    @Override
+    protected double evaluateDouble(double lhs, double rhs) throws HyracksDataException {
+        return lhs + rhs;
+    }
 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericCeilingDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericCeilingDescriptor.java
new file mode 100644
index 0000000..2029426
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericCeilingDescriptor.java
@@ -0,0 +1,147 @@
+/*
+ * Numeric function ceiling
+ * Author : Xiaoyu Ma@UC Irvine
+ * 01/30/2012
+ */
+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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.common.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 NumericCeilingDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "numeric-ceiling", 1);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new NumericCeilingDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+                    private ICopyEvaluator 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("rawtypes")
+                    private ISerializerDeserializer serde;
+
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        argOut.reset();
+                        eval.evaluate(tuple);
+                        try {
+                            if (argOut.getByteArray()[0] == serNullTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ANULL);
+                                serde.serialize(ANull.NULL, out);
+                            } else if (argOut.getByteArray()[0] == serInt8TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT8);
+                                byte val = (byte) AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
+                                aInt8.setValue(val);
+                                serde.serialize(aInt8, out);
+                            } else if (argOut.getByteArray()[0] == serInt16TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT16);
+                                short val = (short) AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
+                                aInt16.setValue(val);
+                                serde.serialize(aInt16, out);
+                            } else if (argOut.getByteArray()[0] == serInt32TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT32);
+                                int val = (int) AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
+                                aInt32.setValue(val);
+                                serde.serialize(aInt32, out);
+                            } else if (argOut.getByteArray()[0] == serInt64TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT64);
+                                long val = (long) AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
+                                aInt64.setValue(val);
+                                serde.serialize(aInt64, out);
+                            } else if (argOut.getByteArray()[0] == serFloatTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AFLOAT);
+                                float val = (float) AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
+                                aFloat.setValue((float) Math.ceil(val));
+                                serde.serialize(aFloat, out);
+                            } else if (argOut.getByteArray()[0] == serDoubleTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ADOUBLE);
+                                double val = (double) ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 1);
+                                aDouble.setValue(Math.ceil(val));
+                                serde.serialize(aDouble, out);
+                            } else {
+                                throw new NotImplementedException("Numeric Ceiling is not implemented for "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[0]));
+                            }
+                        } catch (HyracksDataException e) {
+                            throw new AlgebricksException(e);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+}
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
index 00e7838..87a4257 100644
--- 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
@@ -1,40 +1,12 @@
 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.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
-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.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
-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 {
+public class NumericDivideDescriptor extends AbstractNumericArithmeticEval {
 
     private static final long serialVersionUID = 1L;
     public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "numeric-divide",
@@ -51,129 +23,14 @@
     }
 
     @Override
-    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
-        return new ICopyEvaluatorFactory() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
-
-                return new ICopyEvaluator() {
-                    private DataOutput out = output.getDataOutput();
-                    // one temp. buffer re-used by both children
-                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
-                    private ICopyEvaluator evalLeft = args[0].createEvaluator(argOut);
-                    private ICopyEvaluator 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("rawtypes")
-                    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.getByteArray()[0]);
-                                switch (typeTag) {
-                                    case INT8: {
-                                        metInt8 = true;
-                                        operands[i] = AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case INT16: {
-                                        metInt16 = true;
-                                        operands[i] = AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case INT32: {
-                                        metInt32 = true;
-                                        operands[i] = AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case INT64: {
-                                        metInt64 = true;
-                                        operands[i] = AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case FLOAT: {
-                                        metFloat = true;
-                                        operands[i] = AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case DOUBLE: {
-                                        metDouble = true;
-                                        operands[i] = ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 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
-                                                        .getByteArray()[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);
-                        }
-                    }
-                };
-            }
-        };
+    protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException {
+        if (rhs == 0)
+            throw new HyracksDataException("Divide by Zero.");
+        return lhs / rhs;
     }
 
+    @Override
+    protected double evaluateDouble(double lhs, double rhs) {
+        return lhs / rhs;
+    }
 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericFloorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericFloorDescriptor.java
new file mode 100644
index 0000000..d30ebb5
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericFloorDescriptor.java
@@ -0,0 +1,146 @@
+/*
+ * Numeric function Floor
+ * Author : Xiaoyu Ma@UC Irvine
+ * 01/30/2012
+ */
+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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.common.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 NumericFloorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+    public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "numeric-floor",
+            1);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new NumericFloorDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+                    private ICopyEvaluator 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("rawtypes")
+                    private ISerializerDeserializer serde;
+
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        argOut.reset();
+                        eval.evaluate(tuple);
+                        try {
+                            if (argOut.getByteArray()[0] == serNullTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ANULL);
+                                serde.serialize(ANull.NULL, out);
+                            } else if (argOut.getByteArray()[0] == serInt8TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT8);
+                                byte val = (byte) AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
+                                aInt8.setValue(val);
+                                serde.serialize(aInt8, out);
+                            } else if (argOut.getByteArray()[0] == serInt16TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT16);
+                                short val = (short) AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
+                                aInt16.setValue(val);
+                                serde.serialize(aInt16, out);
+                            } else if (argOut.getByteArray()[0] == serInt32TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT32);
+                                int val = (int) AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
+                                aInt32.setValue(val);
+                                serde.serialize(aInt32, out);
+                            } else if (argOut.getByteArray()[0] == serInt64TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT64);
+                                long val = (long) AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
+                                aInt64.setValue(val);
+                                serde.serialize(aInt64, out);
+                            } else if (argOut.getByteArray()[0] == serFloatTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AFLOAT);
+                                float val = (float) AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
+                                aFloat.setValue((float) Math.floor(val));
+                                serde.serialize(aFloat, out);
+                            } else if (argOut.getByteArray()[0] == serDoubleTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ADOUBLE);
+                                double val = (double) ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 1);
+                                aDouble.setValue(Math.floor(val));
+                                serde.serialize(aDouble, out);
+                            } else {
+                                throw new NotImplementedException("Numeric Floor is not implemented for "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[0]));
+                            }
+                        } catch (HyracksDataException e) {
+                            throw new AlgebricksException(e);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+}
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
index 76657bd..606f2ec 100644
--- 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
@@ -1,40 +1,12 @@
 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.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
-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.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
-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 {
+public class NumericMultiplyDescriptor extends AbstractNumericArithmeticEval {
 
     private static final long serialVersionUID = 1L;
     public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -51,128 +23,26 @@
     }
 
     @Override
-    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
-        return new ICopyEvaluatorFactory() {
-            private static final long serialVersionUID = 1L;
+    protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException {
+        int signLhs = lhs > 0 ? 1 : (lhs < 0 ? -1 : 0);
+        int signRhs = rhs > 0 ? 1 : (rhs < 0 ? -1 : 0);
+        long maximum = signLhs == signRhs ? Long.MAX_VALUE : Long.MIN_VALUE;
 
-            @Override
-            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+        if (lhs != 0 && (rhs > 0 && rhs > maximum / lhs || rhs < 0 && rhs < maximum / lhs))
+            throw new HyracksDataException("Overflow Happened.");
 
-                return new ICopyEvaluator() {
-                    private DataOutput out = output.getDataOutput();
-                    // one temp. buffer re-used by both children
-                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
-                    private ICopyEvaluator evalLeft = args[0].createEvaluator(argOut);
-                    private ICopyEvaluator 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("rawtypes")
-                    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.getByteArray()[0]);
-                                switch (typeTag) {
-                                    case INT8: {
-                                        metInt8 = true;
-                                        operands[i] = AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case INT16: {
-                                        metInt16 = true;
-                                        operands[i] = AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case INT32: {
-                                        metInt32 = true;
-                                        operands[i] = AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case INT64: {
-                                        metInt64 = true;
-                                        operands[i] = AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case FLOAT: {
-                                        metFloat = true;
-                                        operands[i] = AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
-                                        break;
-                                    }
-                                    case DOUBLE: {
-                                        metDouble = true;
-                                        operands[i] = ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 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
-                                                        .getByteArray()[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);
-                        }
-                    }
-                };
-            }
-        };
+        return lhs * rhs;
     }
 
+    @Override
+    protected double evaluateDouble(double lhs, double rhs) throws HyracksDataException {
+        int signLhs = lhs > 0 ? 1 : (lhs < 0 ? -1 : 0);
+        int signRhs = rhs > 0 ? 1 : (rhs < 0 ? -1 : 0);
+        double maximum = signLhs == signRhs ? Double.MAX_VALUE : -Double.MAX_VALUE;
+
+        if (lhs != 0 && (rhs > 0 && rhs > maximum / lhs || rhs < 0 && rhs < maximum / lhs))
+            throw new HyracksDataException("Overflow Happened.");
+
+        return lhs * rhs;
+    }
 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericRoundDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericRoundDescriptor.java
new file mode 100644
index 0000000..d43cdd0
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericRoundDescriptor.java
@@ -0,0 +1,148 @@
+/*
+ * Numeric function Round
+ * Author : Xiaoyu Ma@UC Irvine
+ * 01/30/2012
+ */
+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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.common.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 NumericRoundDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+    public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "numeric-round",
+            1);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new NumericRoundDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+                    private ICopyEvaluator 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("rawtypes")
+                    private ISerializerDeserializer serde;
+
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        argOut.reset();
+                        eval.evaluate(tuple);
+                        try {
+                            if (argOut.getByteArray()[0] == serNullTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ANULL);
+                                serde.serialize(ANull.NULL, out);
+                            } else if (argOut.getByteArray()[0] == serInt8TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT8);
+                                byte val = (byte) AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
+                                aInt8.setValue(val);
+                                serde.serialize(aInt8, out);
+                            } else if (argOut.getByteArray()[0] == serInt16TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT16);
+                                short val = (short) AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
+                                aInt16.setValue(val);
+                                serde.serialize(aInt16, out);
+                            } else if (argOut.getByteArray()[0] == serInt32TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT32);
+                                int val = (int) AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
+                                aInt32.setValue(val);
+                                serde.serialize(aInt32, out);
+                            } else if (argOut.getByteArray()[0] == serInt64TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT64);
+                                long val = (long) AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
+                                aInt64.setValue(val);
+                                serde.serialize(aInt64, out);
+                            } else if (argOut.getByteArray()[0] == serFloatTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AFLOAT);
+                                float val = (float) AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
+                                val = Math.round(val);
+                                aFloat.setValue(val);
+                                serde.serialize(aFloat, out);
+                            } else if (argOut.getByteArray()[0] == serDoubleTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ADOUBLE);
+                                double val = (double) ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 1);
+                                val = Math.round(val);
+                                aDouble.setValue(val);
+                                serde.serialize(aDouble, out);
+                            } else {
+                                throw new NotImplementedException("Numeric Round is not implemented for "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[0]));
+                            }
+                        } catch (HyracksDataException e) {
+                            throw new AlgebricksException(e);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericRoundHalfToEven2Descriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericRoundHalfToEven2Descriptor.java
new file mode 100644
index 0000000..f43567c
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericRoundHalfToEven2Descriptor.java
@@ -0,0 +1,174 @@
+/*
+ * Numeric function Round half to even
+ * Author : Xiaoyu Ma@UC Irvine
+ * 01/30/2012
+ */
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.*;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.*;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.common.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;
+import java.io.DataOutput;
+import java.math.BigDecimal;
+
+public class NumericRoundHalfToEven2Descriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "numeric-round-half-to-even2", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new NumericRoundHalfToEven2Descriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+                    private ICopyEvaluator eval = args[0].createEvaluator(argOut);
+                    private ICopyEvaluator precision = args[1].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("rawtypes")
+                    private ISerializerDeserializer serde;
+
+                    private int getPrecision(IFrameTupleReference tuple) throws AlgebricksException {
+                        argOut.reset();
+                        precision.evaluate(tuple);
+
+                        if (argOut.getByteArray()[0] == serInt8TypeTag) {
+                            return (int) AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
+                        } else if (argOut.getByteArray()[0] == serInt16TypeTag) {
+                            return (int) AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
+                        } else if (argOut.getByteArray()[0] == serInt32TypeTag) {
+                            return (int) AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
+                        } else if (argOut.getByteArray()[0] == serInt64TypeTag) {
+                            return (int) AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
+                        } else if (argOut.getByteArray()[0] == serFloatTypeTag) {
+                            return (int) AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
+                        } else if (argOut.getByteArray()[0] == serDoubleTypeTag) {
+                            return (int) ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 1);
+                        }
+
+                        return 0;
+                    }
+
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        argOut.reset();
+                        eval.evaluate(tuple);
+
+                        try {
+                            if (argOut.getByteArray()[0] == serNullTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ANULL);
+                                serde.serialize(ANull.NULL, out);
+                            } else if (argOut.getByteArray()[0] == serInt8TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT8);
+                                byte val = (byte) AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
+                                aInt8.setValue(val);
+                                serde.serialize(aInt8, out);
+                            } else if (argOut.getByteArray()[0] == serInt16TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT16);
+                                short val = (short) AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
+                                aInt16.setValue(val);
+                                serde.serialize(aInt16, out);
+                            } else if (argOut.getByteArray()[0] == serInt32TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT32);
+                                int val = (int) AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
+                                aInt32.setValue(val);
+                                serde.serialize(aInt32, out);
+                            } else if (argOut.getByteArray()[0] == serInt64TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT64);
+                                long val = (long) AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
+                                aInt64.setValue(val);
+                                serde.serialize(aInt64, out);
+                            } else if (argOut.getByteArray()[0] == serFloatTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AFLOAT);
+                                float val = (float) AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
+                                if (Float.isNaN(val) || Float.isInfinite(val) || val == -0.0F || val == 0.0F) {
+                                    aFloat.setValue(val);
+                                    serde.serialize(aFloat, out);
+                                } else {
+                                    BigDecimal r = new BigDecimal(Float.toString(val));
+                                    aFloat.setValue(r.setScale(getPrecision(tuple), BigDecimal.ROUND_HALF_EVEN)
+                                            .floatValue());
+                                    serde.serialize(aFloat, out);
+                                }
+                            } else if (argOut.getByteArray()[0] == serDoubleTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ADOUBLE);
+                                double val = (double) ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 1);
+                                if (Double.isNaN(val) || Double.isInfinite(val) || val == -0.0D || val == 0.0D) {
+                                    aDouble.setValue(val);
+                                    serde.serialize(aDouble, out);
+                                } else {
+                                    BigDecimal r = new BigDecimal(Double.toString(val));
+                                    aDouble.setValue(r.setScale(getPrecision(tuple), BigDecimal.ROUND_HALF_EVEN)
+                                            .doubleValue());
+                                    serde.serialize(aDouble, out);
+                                }
+                            } else {
+                                throw new NotImplementedException("Numeric Round Half to Even is not implemented for "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[0]));
+                            }
+                        } catch (HyracksDataException e) {
+                            throw new AlgebricksException(e);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericRoundHalfToEvenDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericRoundHalfToEvenDescriptor.java
new file mode 100644
index 0000000..9499bb3
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericRoundHalfToEvenDescriptor.java
@@ -0,0 +1,135 @@
+/*
+ * Numeric function Round half to even
+ * Author : Xiaoyu Ma@UC Irvine
+ * 01/30/2012
+ */
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.*;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.*;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.algebricks.common.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;
+import java.io.DataOutput;
+
+public class NumericRoundHalfToEvenDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+    public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "numeric-round-half-to-even", 1);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new NumericRoundHalfToEvenDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+                    private ICopyEvaluator 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("rawtypes")
+                    private ISerializerDeserializer serde;
+
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        argOut.reset();
+                        eval.evaluate(tuple);
+                        try {
+                            if (argOut.getByteArray()[0] == serNullTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ANULL);
+                                serde.serialize(ANull.NULL, out);
+                                return;
+                            } else if (argOut.getByteArray()[0] == serInt8TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT8);
+                                byte val = (byte) AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1);
+                                aInt8.setValue(val);
+                                serde.serialize(aInt8, out);
+                            } else if (argOut.getByteArray()[0] == serInt16TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT16);
+                                short val = (short) AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1);
+                                aInt16.setValue(val);
+                                serde.serialize(aInt16, out);
+                            } else if (argOut.getByteArray()[0] == serInt32TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT32);
+                                int val = (int) AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1);
+                                aInt32.setValue(val);
+                                serde.serialize(aInt32, out);
+                            } else if (argOut.getByteArray()[0] == serInt64TypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AINT64);
+                                long val = (long) AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1);
+                                aInt64.setValue(val);
+                                serde.serialize(aInt64, out);
+                            } else if (argOut.getByteArray()[0] == serFloatTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.AFLOAT);
+                                float val = (float) AFloatSerializerDeserializer.getFloat(argOut.getByteArray(), 1);
+                                aFloat.setValue((float) Math.rint(val));
+                                serde.serialize(aFloat, out);
+                            } else if (argOut.getByteArray()[0] == serDoubleTypeTag) {
+                                serde = AqlSerializerDeserializerProvider.INSTANCE
+                                        .getSerializerDeserializer(BuiltinType.ADOUBLE);
+                                double val = (double) ADoubleSerializerDeserializer.getDouble(argOut.getByteArray(), 1);
+                                aDouble.setValue(Math.rint(val));
+                                serde.serialize(aDouble, out);
+                            } else {
+                                throw new NotImplementedException("Numeric Round Half to Even is not implemented for "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[0]));
+                            }
+                        } catch (HyracksDataException e) {
+                            throw new AlgebricksException(e);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringConcatDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringConcatDescriptor.java
new file mode 100644
index 0000000..73d2ac9
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringConcatDescriptor.java
@@ -0,0 +1,111 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+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;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringConcatDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "string-concat",
+            1);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringConcatDescriptor();
+        }
+    };
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+    private final byte stringTypeTag = ATypeTag.STRING.serialize();
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ICopyEvaluatorFactory listEvalFactory = args[0];
+                    private ArrayBackedValueStorage outInputList = new ArrayBackedValueStorage();
+                    private ICopyEvaluator evalList = listEvalFactory.createEvaluator(outInputList);
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ANULL);
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        try {
+                            outInputList.reset();
+                            evalList.evaluate(tuple);
+                            byte[] serOrderedList = outInputList.getByteArray();
+                            if (serOrderedList[0] == SER_NULL_TYPE_TAG) {
+                                nullSerde.serialize(ANull.NULL, out);
+                                return;
+                            }
+                            if (serOrderedList[0] != SER_ORDEREDLIST_TYPE_TAG) {
+                                throw new AlgebricksException("Expects String List."
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serOrderedList[0]));
+                            }
+                            int size = AOrderedListSerializerDeserializer.getNumberOfItems(serOrderedList);
+                            try {
+                                // calculate length first
+                                int utf_8_len = 0;
+                                for (int i = 0; i < size; i++) {
+                                    int itemOffset = AOrderedListSerializerDeserializer
+                                            .getItemOffset(serOrderedList, i);
+                                    utf_8_len += UTF8StringPointable.getUTFLength(serOrderedList, itemOffset);
+                                }
+                                out.writeByte(stringTypeTag);
+                                StringUtils.writeUTF8Len(utf_8_len, out);
+                                for (int i = 0; i < size; i++) {
+                                    int itemOffset = AOrderedListSerializerDeserializer
+                                            .getItemOffset(serOrderedList, i);
+                                    utf_8_len = UTF8StringPointable.getUTFLength(serOrderedList, itemOffset);
+                                    for (int j = 0; j < utf_8_len; j++) {
+                                        out.writeByte(serOrderedList[2 + itemOffset + j]);
+                                    }
+                                }
+                            } catch (AsterixException ex) {
+                                throw new AlgebricksException(ex);
+                            }
+                        } catch (IOException e1) {
+                            throw new AlgebricksException(e1.getMessage());
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringEndWithDescrtiptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringEndWithDescrtiptor.java
new file mode 100644
index 0000000..7d5bdab
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringEndWithDescrtiptor.java
@@ -0,0 +1,77 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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 java.io.DataOutput;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringEndWithDescrtiptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "end-with", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringEndWithDescrtiptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+                DataOutput dout = output.getDataOutput();
+
+                return new AbstractBinaryStringBoolEval(dout, args[0], args[1]) {
+
+                    @Override
+                    protected boolean compute(byte[] lBytes, int lLen, int lStart, byte[] rBytes, int rLen, int rStart,
+                            ArrayBackedValueStorage array0, ArrayBackedValueStorage array1) {
+                        int len1 = UTF8StringPointable.getUTFLength(lBytes, 1);
+                        int len2 = UTF8StringPointable.getUTFLength(rBytes, 1);
+                        if (len2 > len1)
+                            return false;
+
+                        int pos = 3;
+                        int delta = len1 - len2;
+                        while (pos < len2 + 3) {
+                            char c1 = UTF8StringPointable.charAt(lBytes, pos + delta);
+                            char c2 = UTF8StringPointable.charAt(rBytes, pos);
+                            if (c1 != c2)
+                                return false;
+
+                            pos += UTF8StringPointable.charSize(lBytes, pos);
+                        }
+
+                        return true;
+                    }
+
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringEqualDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringEqualDescriptor.java
new file mode 100644
index 0000000..5417e22
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringEqualDescriptor.java
@@ -0,0 +1,73 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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 java.io.DataOutput;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringEqualDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "string-equal",
+            2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringEqualDescriptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+                DataOutput dout = output.getDataOutput();
+
+                return new AbstractBinaryStringBoolEval(dout, args[0], args[1]) {
+
+                    @Override
+                    protected boolean compute(byte[] lBytes, int lLen, int lStart, byte[] rBytes, int rLen, int rStart,
+                            ArrayBackedValueStorage array0, ArrayBackedValueStorage array1) {
+                        int len = UTF8StringPointable.getUTFLength(lBytes, 1);
+
+                        if (len != UTF8StringPointable.getUTFLength(rBytes, 1))
+                            return false;
+
+                        int pos = 3;
+                        while (pos < len + 3) {
+                            char c1 = UTF8StringPointable.charAt(lBytes, pos);
+                            char c2 = UTF8StringPointable.charAt(rBytes, pos);
+                            if (c1 != c2)
+                                return false;
+
+                            pos += UTF8StringPointable.charSize(lBytes, pos);
+                        }
+
+                        return true;
+                    }
+
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringJoinDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringJoinDescriptor.java
new file mode 100644
index 0000000..83784bb
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringJoinDescriptor.java
@@ -0,0 +1,137 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+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;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringJoinDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "string-join", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringJoinDescriptor();
+        }
+    };
+    private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_ORDEREDLIST_TYPE_TAG = ATypeTag.ORDEREDLIST.serialize();
+    private final byte stringTypeTag = ATypeTag.STRING.serialize();
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ICopyEvaluatorFactory listEvalFactory = args[0];
+                    private ICopyEvaluatorFactory sepEvalFactory = args[1];
+                    private ArrayBackedValueStorage outInputList = new ArrayBackedValueStorage();
+                    private ArrayBackedValueStorage outInputSep = new ArrayBackedValueStorage();
+                    private ICopyEvaluator evalList = listEvalFactory.createEvaluator(outInputList);
+                    private ICopyEvaluator evalSep = sepEvalFactory.createEvaluator(outInputSep);
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ANULL);
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        try {
+                            outInputList.reset();
+                            evalList.evaluate(tuple);
+                            byte[] serOrderedList = outInputList.getByteArray();
+
+                            outInputSep.reset();
+                            evalSep.evaluate(tuple);
+                            byte[] serSep = outInputSep.getByteArray();
+                            if (serOrderedList[0] == SER_NULL_TYPE_TAG) {
+                                nullSerde.serialize(ANull.NULL, out);
+                                return;
+                            }
+                            if (serOrderedList[0] != SER_ORDEREDLIST_TYPE_TAG) {
+                                throw new AlgebricksException("Expects String List."
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serOrderedList[0]));
+                            }
+
+                            if (serSep[0] == SER_NULL_TYPE_TAG) {
+                            }
+                            if (serSep[0] != SER_STRING_TYPE_TAG) {
+                                throw new AlgebricksException("Expects String as Seperator."
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serOrderedList[0]));
+                            }
+
+                            int size = AOrderedListSerializerDeserializer.getNumberOfItems(serOrderedList);
+                            try {
+                                // calculate length first
+                                int utf_8_len = 0;
+                                int sep_len = UTF8StringPointable.getUTFLength(serSep, 1);
+
+                                for (int i = 0; i < size; i++) {
+                                    int itemOffset = AOrderedListSerializerDeserializer
+                                            .getItemOffset(serOrderedList, i);
+                                    int currentSize = UTF8StringPointable.getUTFLength(serOrderedList, itemOffset);
+                                    if (i != size - 1 && currentSize != 0) {
+                                        utf_8_len += sep_len;
+                                    }
+                                    utf_8_len += currentSize;
+                                }
+                                out.writeByte(stringTypeTag);
+                                StringUtils.writeUTF8Len(utf_8_len, out);
+                                for (int i = 0; i < size; i++) {
+                                    int itemOffset = AOrderedListSerializerDeserializer
+                                            .getItemOffset(serOrderedList, i);
+                                    utf_8_len = UTF8StringPointable.getUTFLength(serOrderedList, itemOffset);
+                                    for (int j = 0; j < utf_8_len; j++) {
+                                        out.writeByte(serOrderedList[2 + itemOffset + j]);
+                                    }
+                                    if (i == size - 1 || utf_8_len == 0)
+                                        continue;
+                                    for (int j = 0; j < sep_len; j++) {
+                                        out.writeByte(serSep[3 + j]);
+                                    }
+                                }
+                            } catch (AsterixException ex) {
+                                throw new AlgebricksException(ex);
+                            }
+                        } catch (IOException e1) {
+                            throw new AlgebricksException(e1.getMessage());
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringLengthDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringLengthDescriptor.java
new file mode 100644
index 0000000..1952da2
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringLengthDescriptor.java
@@ -0,0 +1,88 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+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 java.io.DataOutput;
+import java.io.IOException;
+
+public class StringLengthDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "string-length",
+            1);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringLengthDescriptor();
+        }
+    };
+    private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+                    private AMutableInt32 result = new AMutableInt32(0);
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+                    private ICopyEvaluator 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);
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<AInt32> intSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.AINT32);
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+
+                        try {
+                            outInput.reset();
+                            eval.evaluate(tuple);
+                            byte[] serString = outInput.getByteArray();
+                            if (serString[0] == SER_STRING_TYPE_TAG) {
+                                int len = UTF8StringPointable.getUTFLength(outInput.getByteArray(), 1);
+                                result.setValue(len);
+                                intSerde.serialize(result, 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/functions/StringLowerCaseDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringLowerCaseDescriptor.java
new file mode 100644
index 0000000..f576cf4
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringLowerCaseDescriptor.java
@@ -0,0 +1,98 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+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;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringLowerCaseDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "lowercase", 1);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringLowerCaseDescriptor();
+        }
+    };
+    private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage outInput = new ArrayBackedValueStorage();
+                    private ICopyEvaluator eval = args[0].createEvaluator(outInput);
+                    private String errorMessage = "This is not an instance of string";
+                    private final byte stt = ATypeTag.STRING.serialize();
+
+                    @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.getByteArray();
+
+                            if (serString[0] == SER_STRING_TYPE_TAG) {
+                                byte[] bytes = outInput.getByteArray();
+                                int len = UTF8StringPointable.getUTFLength(bytes, 1);
+
+                                out.writeByte(stt);
+                                StringUtils.writeUTF8Len(len, out);
+
+                                int pos = 3;
+                                while (pos < len + 3) {
+                                    char c1 = UTF8StringPointable.charAt(bytes, pos);
+                                    c1 = Character.toLowerCase(c1);
+                                    pos += UTF8StringPointable.charSize(bytes, pos);
+                                    StringUtils.writeCharAsModifiedUTF8(c1, 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;
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringMatchesDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringMatchesDescriptor.java
new file mode 100644
index 0000000..e9e016f
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringMatchesDescriptor.java
@@ -0,0 +1,112 @@
+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.AString;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringMatchesDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "matches", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringMatchesDescriptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+                DataOutput dout = output.getDataOutput();
+
+                return new AbstractBinaryStringBoolEval(dout, args[0], args[1]) {
+
+                    private Pattern pattern = null;
+                    private Matcher matcher = null;
+                    private ByteArrayAccessibleOutputStream lastPattern = new ByteArrayAccessibleOutputStream();
+                    private IBinaryComparator strComp = AqlBinaryComparatorFactoryProvider.INSTANCE
+                            .getBinaryComparatorFactory(BuiltinType.ASTRING, true).createBinaryComparator();
+                    private UTF8CharSequence carSeq = new UTF8CharSequence();
+
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ASTRING);
+
+                    @Override
+                    protected boolean compute(byte[] lBytes, int lLen, int lStart, byte[] rBytes, int rLen, int rStart,
+                            ArrayBackedValueStorage array0, ArrayBackedValueStorage array1) throws AlgebricksException {
+                        try {
+                            boolean newPattern = false;
+                            if (pattern == null) {
+                                newPattern = true;
+                            } else {
+                                int c = strComp.compare(rBytes, rStart, rLen, lastPattern.getByteArray(), 0,
+                                        lastPattern.size());
+                                if (c != 0) {
+                                    newPattern = true;
+                                }
+                            }
+                            if (newPattern) {
+                                lastPattern.reset();
+                                lastPattern.write(rBytes, rStart, rLen);
+                                // ! object creation !
+                                DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+                                        lastPattern.getByteArray()));
+                                AString strPattern = (AString) stringSerde.deserialize(di);
+                                // pattern = Pattern.compile(toRegex(strPattern));
+                                pattern = Pattern.compile(strPattern.getStringValue());
+                            }
+
+                            carSeq.reset(array0, 1);
+                            if (newPattern) {
+                                matcher = pattern.matcher(carSeq);
+                            } else {
+                                matcher.reset(carSeq);
+                            }
+                            return matcher.find();
+                        } 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/StringMatchesWithFlagDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringMatchesWithFlagDescriptor.java
new file mode 100644
index 0000000..912a014
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringMatchesWithFlagDescriptor.java
@@ -0,0 +1,139 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+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.AString;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringMatchesWithFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "matches2", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringMatchesWithFlagDescriptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+
+        return new ICopyEvaluatorFactory() {
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+                DataOutput dout = output.getDataOutput();
+
+                return new AbstractTripleStringBoolEval(dout, args[0], args[1], args[2]) {
+
+                    private Pattern pattern = null;
+                    private Matcher matcher = null;
+                    private String strPattern = "";
+                    private int flags = 0;
+                    private ByteArrayAccessibleOutputStream lastPattern = new ByteArrayAccessibleOutputStream();
+                    private ByteArrayAccessibleOutputStream lastFlags = new ByteArrayAccessibleOutputStream();
+                    private IBinaryComparator strComp = AqlBinaryComparatorFactoryProvider.INSTANCE
+                            .getBinaryComparatorFactory(BuiltinType.ASTRING, true).createBinaryComparator();
+                    private UTF8CharSequence carSeq = new UTF8CharSequence();
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ASTRING);
+
+                    @Override
+                    protected boolean compute(byte[] b0, int l0, int s0, byte[] b1, int l1, int s1, byte[] b2, int l2,
+                            int s2, ArrayBackedValueStorage array0, ArrayBackedValueStorage array1)
+                            throws AlgebricksException {
+                        try {
+                            boolean newPattern = false;
+                            boolean newFlags = false;
+
+                            AString astrPattern;
+                            AString astrFlags;
+
+                            if (pattern == null) {
+                                newPattern = true;
+                                newFlags = true;
+                            } else {
+                                int c = strComp.compare(b1, s1, l1, lastPattern.getByteArray(), 0, lastPattern.size());
+                                if (c != 0) {
+                                    newPattern = true;
+                                }
+
+                                c = strComp.compare(b2, s2, l2, lastFlags.getByteArray(), 0, lastFlags.size());
+                                if (c != 0) {
+                                    newFlags = true;
+                                }
+                            }
+                            if (newPattern) {
+                                lastPattern.reset();
+                                lastPattern.write(b1, s1, l1);
+                                // ! object creation !
+                                DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+                                        lastPattern.getByteArray()));
+                                astrPattern = (AString) stringSerde.deserialize(di);
+                                // strPattern = toRegex(astrPattern);
+                                strPattern = astrPattern.getStringValue();
+                            }
+                            if (newFlags) {
+                                lastFlags.reset();
+                                lastFlags.write(b2, s2, l2);
+                                // ! object creation !
+                                DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+                                        lastFlags.getByteArray()));
+                                astrFlags = (AString) stringSerde.deserialize(di);
+                                flags = toFlag(astrFlags);
+                            }
+
+                            pattern = Pattern.compile(strPattern, flags);
+                            carSeq.reset(array0, 1);
+                            if (newPattern) {
+                                matcher = pattern.matcher(carSeq);
+                            } else {
+                                matcher.reset(carSeq);
+                            }
+                            return matcher.find();
+                        } 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/StringReplaceDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringReplaceDescriptor.java
new file mode 100644
index 0000000..15c612e
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringReplaceDescriptor.java
@@ -0,0 +1,140 @@
+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.AString;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringReplaceDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "replace", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringReplaceDescriptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+
+        return new ICopyEvaluatorFactory() {
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+                DataOutput dout = output.getDataOutput();
+
+                return new AbstractTripleStringStringEval(dout, args[0], args[1], args[2]) {
+
+                    private Pattern pattern = null;
+                    private Matcher matcher = null;
+                    private String replace;
+                    private String strPattern = "";
+                    private StringBuffer resultBuf = new StringBuffer();
+                    private ByteArrayAccessibleOutputStream lastPattern = new ByteArrayAccessibleOutputStream();
+                    private ByteArrayAccessibleOutputStream lastReplace = new ByteArrayAccessibleOutputStream();
+                    private IBinaryComparator strComp = AqlBinaryComparatorFactoryProvider.INSTANCE
+                            .getBinaryComparatorFactory(BuiltinType.ASTRING, true).createBinaryComparator();
+                    private UTF8CharSequence carSeq = new UTF8CharSequence();
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ASTRING);
+
+                    @Override
+                    protected String compute(byte[] b0, int l0, int s0, byte[] b1, int l1, int s1, byte[] b2, int l2,
+                            int s2, ArrayBackedValueStorage array0, ArrayBackedValueStorage array1)
+                            throws AlgebricksException {
+                        try {
+                            boolean newPattern = false;
+                            boolean newReplace = false;
+
+                            AString astrPattern;
+                            AString astrReplace;
+
+                            if (pattern == null) {
+                                newPattern = true;
+                                newReplace = true;
+                            } else {
+                                int c = strComp.compare(b1, s1, l1, lastPattern.getByteArray(), 0, lastPattern.size());
+                                if (c != 0) {
+                                    newPattern = true;
+                                }
+
+                                c = strComp.compare(b2, s2, l2, lastReplace.getByteArray(), 0, lastReplace.size());
+                                if (c != 0) {
+                                    newReplace = true;
+                                }
+                            }
+                            if (newPattern) {
+                                lastPattern.reset();
+                                lastPattern.write(b1, s1, l1);
+                                // ! object creation !
+                                DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+                                        lastPattern.getByteArray()));
+                                astrPattern = (AString) stringSerde.deserialize(di);
+                                // strPattern = toRegex(astrPattern);
+                                strPattern = astrPattern.getStringValue();
+                            }
+                            if (newReplace) {
+                                lastReplace.reset();
+                                lastReplace.write(b2, s2, l2);
+                                // ! object creation !
+                                DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+                                        lastReplace.getByteArray()));
+                                astrReplace = (AString) stringSerde.deserialize(di);
+                                replace = astrReplace.getStringValue();
+                            }
+                            if (newPattern)
+                                pattern = Pattern.compile(strPattern);
+                            carSeq.reset(array0, 1);
+                            if (newPattern) {
+                                matcher = pattern.matcher(carSeq);
+                            } else {
+                                matcher.reset(carSeq);
+                            }
+                            while (matcher.find()) {
+                                matcher.appendReplacement(resultBuf, replace);
+                            }
+                            matcher.appendTail(resultBuf);
+                            return resultBuf.toString();
+                        } 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/StringReplaceWithFlagsDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringReplaceWithFlagsDescriptor.java
new file mode 100644
index 0000000..aedad20
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringReplaceWithFlagsDescriptor.java
@@ -0,0 +1,163 @@
+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.AString;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringReplaceWithFlagsDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "replace2", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringReplaceWithFlagsDescriptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+
+        return new ICopyEvaluatorFactory() {
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+                DataOutput dout = output.getDataOutput();
+
+                return new AbstractQuadStringStringEval(dout, args[0], args[1], args[2], args[3]) {
+
+                    private Pattern pattern = null;
+                    private Matcher matcher = null;
+                    private String strPattern = "";
+                    private String replace = "";
+                    private int flags = 0;
+                    private StringBuffer resultBuf = new StringBuffer();
+                    private ByteArrayAccessibleOutputStream lastPattern = new ByteArrayAccessibleOutputStream();
+                    private ByteArrayAccessibleOutputStream lastFlags = new ByteArrayAccessibleOutputStream();
+                    private ByteArrayAccessibleOutputStream lastReplace = new ByteArrayAccessibleOutputStream();
+                    private IBinaryComparator strComp = AqlBinaryComparatorFactoryProvider.INSTANCE
+                            .getBinaryComparatorFactory(BuiltinType.ASTRING, true).createBinaryComparator();
+                    private UTF8CharSequence carSeq = new UTF8CharSequence();
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ASTRING);
+
+                    @Override
+                    protected String compute(byte[] b0, int l0, int s0, byte[] b1, int l1, int s1, byte[] b2, int l2,
+                            int s2, byte[] b3, int l3, int s3, ArrayBackedValueStorage array0,
+                            ArrayBackedValueStorage array1) throws AlgebricksException {
+                        try {
+                            boolean newPattern = false;
+                            boolean newFlags = false;
+                            boolean newReplace = false;
+
+                            AString astrPattern;
+                            AString astrFlags;
+
+                            if (pattern == null) {
+                                newPattern = true;
+                                newFlags = true;
+                            } else {
+                                int c = strComp.compare(b1, s1, l1, lastPattern.getByteArray(), 0, lastPattern.size());
+                                if (c != 0) {
+                                    newPattern = true;
+                                }
+
+                                c = strComp.compare(b3, s3, l3, lastFlags.getByteArray(), 0, lastFlags.size());
+                                if (c != 0) {
+                                    newFlags = true;
+                                }
+                            }
+
+                            if (replace == null) {
+                                newReplace = true;
+                            } else {
+                                int c = strComp.compare(b2, s2, l2, lastReplace.getByteArray(), 0, lastReplace.size());
+                                if (c != 0) {
+                                    newReplace = true;
+                                }
+                            }
+
+                            if (newPattern) {
+                                lastPattern.reset();
+                                lastPattern.write(b1, s1, l1);
+                                // ! object creation !
+                                DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+                                        lastPattern.getByteArray()));
+                                astrPattern = (AString) stringSerde.deserialize(di);
+                                // strPattern = toRegex(astrPattern);
+                                strPattern = astrPattern.getStringValue();
+                            }
+                            if (newReplace) {
+                                lastReplace.reset();
+                                lastReplace.write(b2, s2, l2);
+                                // ! object creation !
+                                DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+                                        lastReplace.getByteArray()));
+                                replace = ((AString) stringSerde.deserialize(di)).getStringValue();
+                            }
+                            if (newFlags) {
+                                lastFlags.reset();
+                                lastFlags.write(b3, s3, l3);
+                                // ! object creation !
+                                DataInputStream di = new DataInputStream(new ByteArrayInputStream(
+                                        lastFlags.getByteArray()));
+                                astrFlags = (AString) stringSerde.deserialize(di);
+                                flags = toFlag(astrFlags);
+                            }
+
+                            if (newPattern || newFlags)
+                                pattern = Pattern.compile(strPattern, flags);
+                            resultBuf.setLength(0);
+                            carSeq.reset(array0, 1);
+                            if (newPattern) {
+                                matcher = pattern.matcher(carSeq);
+                            } else {
+                                matcher.reset(carSeq);
+                            }
+                            while (matcher.find()) {
+                                matcher.appendReplacement(resultBuf, replace);
+                            }
+                            matcher.appendTail(resultBuf);
+                            return resultBuf.toString();
+                        } 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/StringStartWithDescrtiptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringStartWithDescrtiptor.java
new file mode 100644
index 0000000..9ecdee9
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringStartWithDescrtiptor.java
@@ -0,0 +1,72 @@
+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.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringStartWithDescrtiptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "start-with", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringStartWithDescrtiptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(IDataOutputProvider output) throws AlgebricksException {
+
+                DataOutput dout = output.getDataOutput();
+
+                return new AbstractBinaryStringBoolEval(dout, args[0], args[1]) {
+
+                    @Override
+                    protected boolean compute(byte[] lBytes, int lLen, int lStart, byte[] rBytes, int rLen, int rStart,
+                            ArrayBackedValueStorage array0, ArrayBackedValueStorage array1) {
+                        int patternLength = UTF8StringPointable.getUTFLength(rBytes, 1);
+                        if (patternLength > UTF8StringPointable.getUTFLength(lBytes, 1))
+                            return false;
+
+                        int pos = 3;
+                        while (pos < patternLength + 3) {
+                            char c1 = UTF8StringPointable.charAt(lBytes, pos);
+                            char c2 = UTF8StringPointable.charAt(rBytes, pos);
+                            if (c1 != c2)
+                                return false;
+
+                            pos += UTF8StringPointable.charSize(lBytes, pos);
+                        }
+
+                        return true;
+                    }
+
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringToCodePointDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringToCodePointDescriptor.java
new file mode 100644
index 0000000..3c60e28
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/StringToCodePointDescriptor.java
@@ -0,0 +1,147 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+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.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.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+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;
+
+/**
+ * @author Xiaoyu Ma
+ */
+public class StringToCodePointDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "string-to-codepoint", 1);
+    public static final IFunctionDescriptorFactory FACTORY1 = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringToCodePointDescriptor();
+        }
+    };
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringToCodePointDescriptor();
+        }
+    };
+    private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+                    protected final DataOutput out = output.getDataOutput();;
+                    protected final ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+                    protected final ICopyEvaluator stringEval = args[0].createEvaluator(argOut);
+                    protected final AOrderedListType intListType = new AOrderedListType(BuiltinType.AINT32, null);
+
+                    private IAOrderedListBuilder listBuilder = new OrderedListBuilder();
+                    private ArrayBackedValueStorage inputVal = new ArrayBackedValueStorage();
+
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ANULL);
+                    @SuppressWarnings("unchecked")
+                    private final ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.AINT32);
+                    private final AMutableInt32 aInt32 = new AMutableInt32(0);
+
+                    int UTF8ToCodePoint(byte[] b, int s) {
+                        if (b[s] >> 7 == 0) {
+                            // 1 byte
+                            return b[s];
+                        } else if ((b[s] & 0xe0) == 0xc0) { /*0xe0 = 0b1110000*/
+                            // 2 bytes
+                            return ((int) (b[s] & 0x1f)) << 6 | /*0x3f = 0b00111111*/
+                            ((int) (b[s + 1] & 0x3f));
+                        } else if ((b[s] & 0xf0) == 0xe0) {
+                            // 3bytes
+                            return ((int) (b[s] & 0xf)) << 12 | ((int) (b[s + 1] & 0x3f)) << 6
+                                    | ((int) (b[s + 2] & 0x3f));
+                        } else if ((b[s] & 0xf8) == 0xf0) {
+                            // 4bytes
+                            return ((int) (b[s] & 0x7)) << 18 | ((int) (b[s + 1] & 0x3f)) << 12
+                                    | ((int) (b[s + 2] & 0x3f)) << 6 | ((int) (b[s + 3] & 0x3f));
+                        } else if ((b[s] & 0xfc) == 0xf8) {
+                            // 5bytes
+                            return ((int) (b[s] & 0x3)) << 24 | ((int) (b[s + 1] & 0x3f)) << 18
+                                    | ((int) (b[s + 2] & 0x3f)) << 12 | ((int) (b[s + 3] & 0x3f)) << 6
+                                    | ((int) (b[s + 4] & 0x3f));
+                        } else if ((b[s] & 0xfe) == 0xfc) {
+                            // 6bytes
+                            return ((int) (b[s] & 0x1)) << 30 | ((int) (b[s + 1] & 0x3f)) << 24
+                                    | ((int) (b[s + 2] & 0x3f)) << 18 | ((int) (b[s + 3] & 0x3f)) << 12
+                                    | ((int) (b[s + 4] & 0x3f)) << 6 | ((int) (b[s + 5] & 0x3f));
+                        }
+                        return 0;
+                    }
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        try {
+                            argOut.reset();
+                            stringEval.evaluate(tuple);
+                            byte[] serString = argOut.getByteArray();
+
+                            if (serString[0] == SER_STRING_TYPE_TAG) {
+                                byte[] bytes = argOut.getByteArray();
+                                int len = UTF8StringPointable.getUTFLength(bytes, 1);
+
+                                int pos = 3;
+                                listBuilder.reset(intListType);
+                                while (pos < len + 3) {
+                                    int codePoint = UTF8ToCodePoint(bytes, pos);
+                                    pos += UTF8StringPointable.charSize(bytes, pos);
+
+                                    inputVal.reset();
+                                    aInt32.setValue(codePoint);
+                                    int32Serde.serialize(aInt32, inputVal.getDataOutput());
+                                    listBuilder.addItem(inputVal);
+
+                                }
+                                listBuilder.write(out, true);
+                            } else if (serString[0] == SER_NULL_TYPE_TAG)
+                                nullSerde.serialize(ANull.NULL, out);
+                            else
+                                throw new AlgebricksException("Expects String Type.");
+                        } catch (IOException e1) {
+                            throw new AlgebricksException(e1.getMessage());
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return FID;
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/Substring2Descriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/Substring2Descriptor.java
new file mode 100644
index 0000000..ebbfe80
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/Substring2Descriptor.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.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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 Substring2Descriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "substring2", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new Substring2Descriptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+                    private ICopyEvaluator evalString = args[0].createEvaluator(argOut);
+                    private ICopyEvaluator evalStart = args[1].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.getByteArray(), 1) - 1;
+                        argOut.reset();
+                        evalString.evaluate(tuple);
+
+                        byte[] bytes = argOut.getByteArray();
+                        int utflen = UTF8StringPointable.getUTFLength(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;
+
+                        while (c < utflen) {
+                            c += UTF8StringPointable.charSize(bytes, sStart + c);
+                        }
+
+                        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/SubstringAfterDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SubstringAfterDescriptor.java
new file mode 100644
index 0000000..567526d
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SubstringAfterDescriptor.java
@@ -0,0 +1,101 @@
+package edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+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.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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 java.io.DataOutput;
+import java.io.IOException;
+
+public class SubstringAfterDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "substring-after", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new SubstringAfterDescriptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage array0 = new ArrayBackedValueStorage();
+                    private ArrayBackedValueStorage array1 = new ArrayBackedValueStorage();
+                    private ICopyEvaluator evalString = args[0].createEvaluator(array0);
+                    private ICopyEvaluator evalPattern = args[1].createEvaluator(array1);
+                    private final byte stt = ATypeTag.STRING.serialize();
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        array0.reset();
+                        evalString.evaluate(tuple);
+                        byte[] src = array0.getByteArray();
+
+                        array1.reset();
+                        evalPattern.evaluate(tuple);
+                        byte[] pattern = array1.getByteArray();
+
+                        int srcLen = UTF8StringPointable.getUTFLength(src, 1);
+                        int patternLen = UTF8StringPointable.getUTFLength(pattern, 1);
+                        int posSrc = 3;
+                        int posPattern = 3;
+
+                        int offset = 0;
+                        // boolean found = false;
+                        while (posSrc - 3 < srcLen - patternLen) {
+                            offset = 0;
+                            while (posPattern + offset - 3 < patternLen && posSrc + offset - 3 < srcLen) {
+                                char c1 = UTF8StringPointable.charAt(src, posSrc + offset);
+                                char c2 = UTF8StringPointable.charAt(pattern, posPattern + offset);
+                                if (c1 != c2)
+                                    break;
+                                offset++;
+                            }
+                            if (offset == patternLen) {
+                                // found = true;
+                                break;
+                            }
+                            posSrc += UTF8StringPointable.charSize(src, posSrc);
+                        }
+
+                        posSrc += patternLen;
+                        int substrByteLen = srcLen - posSrc + 3;
+                        try {
+                            out.writeByte(stt);
+                            out.writeByte((byte) ((substrByteLen >>> 8) & 0xFF));
+                            out.writeByte((byte) ((substrByteLen >>> 0) & 0xFF));
+                            out.write(src, posSrc, 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/SubstringBeforeDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SubstringBeforeDescriptor.java
new file mode 100644
index 0000000..fb496a1
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/SubstringBeforeDescriptor.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.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+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;
+
+public class SubstringBeforeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    private final static FunctionIdentifier FID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "substring-before", 2);
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new SubstringBeforeDescriptor();
+        }
+    };
+
+    @Override
+    public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+        return new ICopyEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+                return new ICopyEvaluator() {
+
+                    private DataOutput out = output.getDataOutput();
+                    private ArrayBackedValueStorage array0 = new ArrayBackedValueStorage();
+                    private ArrayBackedValueStorage array1 = new ArrayBackedValueStorage();
+                    private ICopyEvaluator evalString = args[0].createEvaluator(array0);
+                    private ICopyEvaluator evalPattern = args[1].createEvaluator(array1);
+                    private final byte stt = ATypeTag.STRING.serialize();
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+                        array0.reset();
+                        evalString.evaluate(tuple);
+                        byte[] src = array0.getByteArray();
+
+                        array1.reset();
+                        evalPattern.evaluate(tuple);
+                        byte[] pattern = array1.getByteArray();
+
+                        int srcLen = UTF8StringPointable.getUTFLength(src, 1);
+                        int patternLen = UTF8StringPointable.getUTFLength(pattern, 1);
+                        int posSrc = 3;
+                        int posPattern = 3;
+
+                        int offset = 0;
+                        while (posSrc - 3 < srcLen - patternLen) {
+                            // offset = 0;                        
+                            while (posPattern + offset - 3 < patternLen && posSrc + offset - 3 < srcLen) {
+                                char c1 = UTF8StringPointable.charAt(src, posSrc + offset);
+                                char c2 = UTF8StringPointable.charAt(pattern, posPattern + offset);
+                                if (c1 != c2)
+                                    break;
+                                offset++;
+                            }
+                            if (offset == patternLen) {
+                                // found = true;
+                                break;
+                            }
+                            posSrc += UTF8StringPointable.charSize(src, posSrc);
+                        }
+                        int startSubstr = 3;
+
+                        int substrByteLen = posSrc - startSubstr;
+                        try {
+                            out.writeByte(stt);
+                            out.writeByte((byte) ((substrByteLen >>> 8) & 0xFF));
+                            out.writeByte((byte) ((substrByteLen >>> 0) & 0xFF));
+                            out.write(src, 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/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
index e28e59c..e9f1ac5 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
@@ -134,6 +134,28 @@
 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.evaluators.functions.NumericAbsDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericCeilingDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericFloorDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericRoundDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericRoundHalfToEvenDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericRoundHalfToEven2Descriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringEqualDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringStartWithDescrtiptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringEndWithDescrtiptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringMatchesDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringLowerCaseDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringMatchesWithFlagDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringReplaceDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringReplaceWithFlagsDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringLengthDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.Substring2Descriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SubstringBeforeDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.SubstringAfterDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringToCodePointDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.CodePointToStringDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringConcatDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.StringJoinDescriptor;
 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;
@@ -246,6 +268,31 @@
         temp.add(NonEmptyStreamAggregateDescriptor.FACTORY);
         temp.add(RangeDescriptor.FACTORY);
 
+// Xiaoyu Ma add for numeric unary functions
+        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);