Add several builtin functions.

- add functions such as greatest, least, concat(||), initcap(title),
  regexp_contains, regexp_like, regexp_position, regexp_replace, ltrim,
  trim, rtrim, position;
- refactor string functions;
- remove undocumented function "regexp", which is equivalent to "matches";
- remove AQL.html and SQLPP.html since they are generated in "target/".

Change-Id: I26351af22f67d66b56176f55b29a4e7ff63583f7
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1104
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
index ee4dc32..a1746cc 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
@@ -190,7 +190,6 @@
 import org.apache.asterix.runtime.evaluators.functions.OrDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.OrderedListConstructorDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.PrefixLenJaccardDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.RegExpDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.SimilarityJaccardCheckDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.SimilarityJaccardDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.SimilarityJaccardPrefixCheckDescriptor;
@@ -205,16 +204,28 @@
 import org.apache.asterix.runtime.evaluators.functions.StringContainsDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.StringEndsWithDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.StringEqualDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringInitCapDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.StringJoinDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringLTrim2Descriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringLTrimDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.StringLengthDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.StringLikeDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.StringLowerCaseDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.StringMatchesDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.StringMatchesWithFlagDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.StringReplaceDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.StringReplaceWithFlagsDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringPositionDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRTrim2Descriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRTrimDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRegExpContainsDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRegExpContainsWithFlagDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRegExpLikeDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRegExpLikeWithFlagDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRegExpPositionDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRegExpPositionWithFlagDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRegExpReplaceDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRegExpReplaceWithFlagsDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.StringStartsWithDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.StringToCodePointDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringTrim2Descriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringTrimDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.StringUpperCaseDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.Substring2Descriptor;
 import org.apache.asterix.runtime.evaluators.functions.SubstringAfterDescriptor;
@@ -476,12 +487,8 @@
         functionsToInjectUnkownHandling.add(StringStartsWithDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(SubstringDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(StringEqualDescriptor.FACTORY);
-        functionsToInjectUnkownHandling.add(StringMatchesDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(StringLowerCaseDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(StringUpperCaseDescriptor.FACTORY);
-        functionsToInjectUnkownHandling.add(StringMatchesWithFlagDescriptor.FACTORY);
-        functionsToInjectUnkownHandling.add(StringReplaceDescriptor.FACTORY);
-        functionsToInjectUnkownHandling.add(StringReplaceWithFlagsDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(StringLengthDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(Substring2Descriptor.FACTORY);
         functionsToInjectUnkownHandling.add(SubstringBeforeDescriptor.FACTORY);
@@ -490,7 +497,22 @@
         functionsToInjectUnkownHandling.add(CodePointToStringDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(StringConcatDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(StringJoinDescriptor.FACTORY);
-        functionsToInjectUnkownHandling.add(RegExpDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRegExpContainsDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRegExpContainsWithFlagDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRegExpLikeDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRegExpLikeWithFlagDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRegExpPositionDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRegExpPositionWithFlagDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRegExpReplaceDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRegExpReplaceWithFlagsDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringInitCapDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringTrimDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringLTrimDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRTrimDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringTrim2Descriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringLTrim2Descriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringRTrim2Descriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(StringPositionDescriptor.FACTORY);
 
         // Constructors
         functionsToInjectUnkownHandling.add(ABooleanConstructorDescriptor.FACTORY);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.query.aql
index 90ee93f..00a84fc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.query.aql
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.query.aql
@@ -26,24 +26,24 @@
   where $p.p_partkey = $l.l_partkey
     and ( (
         $p.p_brand = 'Brand#12'
-        and reg-exp($p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG')
+        and matches($p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG')
         and $l.l_quantity >= 1 and $l.l_quantity <= 11
         and $p.p_size >= 1 and $p.p_size <= 5
-        and reg-exp($l.l_shipmode, 'AIR||AIR REG')
+        and matches($l.l_shipmode, 'AIR||AIR REG')
         and $l.l_shipinstruct = 'DELIVER IN PERSON'
       ) or (
         $p.p_brand = 'Brand#23'
-        and reg-exp($p.p_container, 'MED BAG||MED BOX||MED PKG||MED PACK')
+        and matches($p.p_container, 'MED BAG||MED BOX||MED PKG||MED PACK')
         and $l.l_quantity >= 10 and $l.l_quantity <= 20
         and $p.p_size >= 1 and $p.p_size <= 10
-        and reg-exp($l.l_shipmode, 'AIR||AIR REG')
+        and matches($l.l_shipmode, 'AIR||AIR REG')
         and $l.l_shipinstruct = 'DELIVER IN PERSON'
       ) or (
         $p.p_brand = 'Brand#34'
-        and reg-exp($p.p_container, 'LG CASE||LG BOX||LG PACK||LG PKG')
+        and matches($p.p_container, 'LG CASE||LG BOX||LG PACK||LG PKG')
         and $l.l_quantity >= 20 and $l.l_quantity <= 30
         and $p.p_size >= 1 and $p.p_size <= 15
-        and reg-exp($l.l_shipmode, 'AIR||AIR REG')
+        and matches($l.l_shipmode, 'AIR||AIR REG')
         and $l.l_shipinstruct = 'DELIVER IN PERSON'
       )
     )
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/tpch/q19_discounted_revenue/q19_discounted_revenue.3.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/tpch/q19_discounted_revenue/q19_discounted_revenue.3.query.aql
index 42e9a82..60d3c41 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/tpch/q19_discounted_revenue/q19_discounted_revenue.3.query.aql
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/tpch/q19_discounted_revenue/q19_discounted_revenue.3.query.aql
@@ -20,30 +20,30 @@
 
 set import-private-functions 'true';
 
-sum( 
+sum(
   for $l in dataset('LineItem')
   for $p in dataset('Part')
   where $p.p_partkey = $l.l_partkey
     and ( (
         $p.p_brand = 'Brand#12'
-        and reg-exp($p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG')
+        and matches($p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG')
         and $l.l_quantity >= 1 and $l.l_quantity <= 11
         and $p.p_size >= 1 and $p.p_size <= 5
-        and reg-exp($l.l_shipmode, 'AIR||AIR REG')
+        and matches($l.l_shipmode, 'AIR||AIR REG')
         and $l.l_shipinstruct = 'DELIVER IN PERSON'
       ) or (
         $p.p_brand = 'Brand#23'
-        and reg-exp($p.p_container, 'MED BAG||MED BOX||MED PKG||MED PACK')
+        and matches($p.p_container, 'MED BAG||MED BOX||MED PKG||MED PACK')
         and $l.l_quantity >= 10 and $l.l_quantity <= 20
         and $p.p_size >= 1 and $p.p_size <= 10
-        and reg-exp($l.l_shipmode, 'AIR||AIR REG')
+        and matches($l.l_shipmode, 'AIR||AIR REG')
         and $l.l_shipinstruct = 'DELIVER IN PERSON'
       ) or (
         $p.p_brand = 'Brand#34'
-        and reg-exp($p.p_container, 'LG CASE||LG BOX||LG PACK||LG PKG')
+        and matches($p.p_container, 'LG CASE||LG BOX||LG PACK||LG PKG')
         and $l.l_quantity >= 20 and $l.l_quantity <= 30
         and $p.p_size >= 1 and $p.p_size <= 15
-        and reg-exp($l.l_shipmode, 'AIR||AIR REG')
+        and matches($l.l_shipmode, 'AIR||AIR REG')
         and $l.l_shipinstruct = 'DELIVER IN PERSON'
       )
     )
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/comparison/greatest_mixed/greatest_mixed.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/comparison/greatest_mixed/greatest_mixed.3.query.sqlpp
new file mode 100644
index 0000000..9056b4b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/comparison/greatest_mixed/greatest_mixed.3.query.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+SELECT VALUE greatest(1.0, 3.0, -2, 10.0, 2, null, missing);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/comparison/least_mixed/least_mixed.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/comparison/least_mixed/least_mixed.1.query.sqlpp
new file mode 100644
index 0000000..948d146
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/comparison/least_mixed/least_mixed.1.query.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+SELECT VALUE LEAST(1.0, 3.0, -2, 10.0, 2, null, missing);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_func/concat_func.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_func/concat_func.1.query.sqlpp
new file mode 100644
index 0000000..46f2a65
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_func/concat_func.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+with  k as [{'a':1,'b':'hello'},{'a':2,'b':{'k':[1,2,2]}}]
+
+select value concat(x.b, " world")
+from  k as x
+where x.a = 1
+;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_pipe/concat_pipe.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_pipe/concat_pipe.1.query.sqlpp
new file mode 100644
index 0000000..16bef11
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_pipe/concat_pipe.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+with  k as [{'a':1,'b':'hello'},{'a':2,'b':{'k':[1,2,2]}}]
+
+select value x.b || " world"
+from  k as x
+where x.a = 1
+;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_pipe_multi/concat_pipe_multi.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_pipe_multi/concat_pipe_multi.1.query.sqlpp
new file mode 100644
index 0000000..3f06395
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_pipe_multi/concat_pipe_multi.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+with  k as [{'a':1,'b':'hello'},{'a':2,'b':{'k':[1,2,2]}}]
+
+select value x.b || " new" || " world"
+from  k as x
+where x.a = 1
+;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/initcap/initcap.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/initcap/initcap.1.query.sqlpp
new file mode 100644
index 0000000..35580ce
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/initcap/initcap.1.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+[
+   initcap(""),
+   initcap("very large data base--a conference"),
+   initcap("very large data base?a conference"),
+   initcap(null),
+   initcap(missing)
+];
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/ltrim/ltrim.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/ltrim/ltrim.1.query.sqlpp
new file mode 100644
index 0000000..bc062e5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/ltrim/ltrim.1.query.sqlpp
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+[
+   ltrim(""),
+   ltrim("    "),
+   ltrim(" abc "),
+   ltrim("abcd"),
+   ltrim(null),
+   ltrim(missing),
+   ltrim("", "ad "),
+   ltrim("    ", "ad "),
+   ltrim(" abc ", "ad "),
+   ltrim("abcd", "ad "),
+   ltrim("abc", null),
+   ltrim(null, "abc"),
+   ltrim(null, null),
+   ltrim("abc", missing),
+   ltrim(missing, "abc"),
+   ltrim(missing, missing)
+];
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/position/position.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/position/position.1.query.sqlpp
new file mode 100644
index 0000000..d8afe59
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/position/position.1.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+select element [position(x,'ofo'), position(y,'ofo')]
+from  ['foofoo'] as x,
+      ['barbar'] as y
+;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_contains/regexp_contains.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_contains/regexp_contains.1.query.sqlpp
new file mode 100644
index 0000000..a639365
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_contains/regexp_contains.1.query.sqlpp
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+select element a
+from [
+      REGEXP_CONTAINS('mnop','.'),
+      REGEXP_CONTAINS('abcdefABCDEF','/d'),
+      REGEXP_CONTAINS('12345','\\d'),
+      REGEXP_CONTAINS('abcdefGHIJK','\\D'),
+      REGEXP_CONTAINS('       ','\\s'),
+      REGEXP_CONTAINS('       ','\\S'),
+      REGEXP_CONTAINS('Welcome to pattern matching!','[a-zA-Z_0-9]'),
+      REGEXP_CONTAINS('!@#$%^&*()','[a-zA-Z_0-9]'),
+      REGEXP_CONTAINS('!@#$%^&*()','[^\\W]'),
+      REGEXP_CONTAINS('!@#$%^&*','[^\\w]'),
+      REGEXP_CONTAINS('0xffff','[\\p{XDigit}]'),
+      REGEXP_CONTAINS('FFFFFFFF','[\\p{XDigit}]'),
+      REGEXP_CONTAINS('abcdefgh','[\\p{javaLowerCase}]'),
+      REGEXP_CONTAINS('ABCDEF','[\\p{javaLowerCase}]'),
+      REGEXP_CONTAINS(`codepoint-to-string`([163]),'[\\p{Sc}]')
+     ] as a
+;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_contains_with_flag/regexp_contains.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_contains_with_flag/regexp_contains.1.query.sqlpp
new file mode 100644
index 0000000..0836054
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_contains_with_flag/regexp_contains.1.query.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{'result1': REGEXP_CONTAINS('helloworld','hello world','x')};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_like/regexp_like.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_like/regexp_like.1.query.sqlpp
new file mode 100644
index 0000000..eaaacc5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_like/regexp_like.1.query.sqlpp
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+select element a
+from [
+      REGEXP_LIKE('mnop','.'),
+      REGEXP_LIKE('abcdefABCDEF','/d'),
+      REGEXP_LIKE('12345','\\d'),
+      REGEXP_LIKE('abcdefGHIJK','\\D'),
+      REGEXP_LIKE('       ','\\s'),
+      REGEXP_LIKE('       ','\\S'),
+      REGEXP_LIKE('Welcome to pattern matching!','[a-zA-Z_0-9]'),
+      REGEXP_LIKE('!@#$%^&*()','[a-zA-Z_0-9]'),
+      REGEXP_LIKE('!@#$%^&*()','[^\\W]'),
+      REGEXP_LIKE('!@#$%^&*','[^\\w]'),
+      REGEXP_LIKE('0xffff','[\\p{XDigit}]'),
+      REGEXP_LIKE('FFFFFFFF','[\\p{XDigit}]'),
+      REGEXP_LIKE('abcdefgh','[\\p{javaLowerCase}]'),
+      REGEXP_LIKE('ABCDEF','[\\p{javaLowerCase}]'),
+      REGEXP_LIKE(`codepoint-to-string`([163]),'[\\p{Sc}]'),
+      REGEXP_LIKE('Steven','Ste(v|ph)en'),
+      REGEXP_LIKE('Stephen','.*(v|ph)*')
+     ] as a
+;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_like_with_flag/regexp_like_with_flag.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_like_with_flag/regexp_like_with_flag.1.query.sqlpp
new file mode 100644
index 0000000..91f90a4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_like_with_flag/regexp_like_with_flag.1.query.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{'result1': REGEXP_LIKE('helloworld','hello world','x')};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_position/regexp_position.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_position/regexp_position.1.query.sqlpp
new file mode 100644
index 0000000..41b4489
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_position/regexp_position.1.query.sqlpp
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+select element a
+from [
+      REGEXP_POSITION('mnop','.'),
+      REGEXP_POSITION('abcdefABCDEF','/d'),
+      REGEXP_POSITION('12345','\\d'),
+      REGEXP_POSITION('abcdefGHIJK','\\D'),
+      REGEXP_POSITION('       ','\\s'),
+      REGEXP_POSITION('       ','\\S'),
+      REGEXP_POSITION('Welcome to pattern matching!','[a-zA-Z_0-9]'),
+      REGEXP_POSITION('!@#$%^&*()','[a-zA-Z_0-9]'),
+      REGEXP_POSITION('!@#$%^&*()','[^\\W]'),
+      REGEXP_POSITION('!@#$%^&*','[^\\w]'),
+      REGEXP_POSITION('0xffff','[\\p{XDigit}]'),
+      REGEXP_POSITION('FFFFFFFF','[\\p{XDigit}]'),
+      REGEXP_POSITION('abcdefgh','[\\p{javaLowerCase}]'),
+      REGEXP_POSITION('ABCDEF','[\\p{javaLowerCase}]'),
+      REGEXP_POSITION(`codepoint-to-string`([163]),'[\\p{Sc}]')
+     ] as a
+;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_position_with_flag/regexp_position_with_flag.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_position_with_flag/regexp_position_with_flag.1.query.sqlpp
new file mode 100644
index 0000000..6568d06
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_position_with_flag/regexp_position_with_flag.1.query.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{'result1': REGEXP_POSITION('helloworld','hello world','x')};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_replace/regexp_replace.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_replace/regexp_replace.1.query.sqlpp
new file mode 100644
index 0000000..819bb83
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_replace/regexp_replace.1.query.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+
+{
+  'result1':REGEXP_REPLACE('abracadabra','',null,null),
+  'result2':REGEXP_REPLACE('abracadabra','bra','XXX',''),
+  'result3':REGEXP_REPLACE(null,'hello world','XxXx','x'),
+  'result4':REGEXP_REPLACE('abracadabra','bra','XXX',null),
+  'result5':REGEXP_REPLACE('abracadabra',null,'XXX',null),
+  'result6':REGEXP_REPLACE('abracadabra','Bra',null,'i'),
+  'result7':REGEXP_REPLACE('abracadabra','Bra','','i'),
+  'result8':REGEXP_REPLACE('abracadabra','','XXX','')
+};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/rtrim/rtrim.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/rtrim/rtrim.1.query.sqlpp
new file mode 100644
index 0000000..64a050b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/rtrim/rtrim.1.query.sqlpp
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+[
+   rtrim(""),
+   rtrim("    "),
+   rtrim(" abc "),
+   rtrim("abcd"),
+   rtrim(null),
+   rtrim(missing),
+   rtrim("", "ad "),
+   rtrim("    ", "ad "),
+   rtrim(" abc ", "ad "),
+   rtrim("abcd", "ad "),
+   rtrim("abc", null),
+   rtrim(null, "abc"),
+   rtrim(null, null),
+   rtrim("abc", missing),
+   rtrim(missing, "abc"),
+   rtrim(missing, missing)
+];
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/title/title.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/title/title.1.query.sqlpp
new file mode 100644
index 0000000..b12c475
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/title/title.1.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+[
+   title(""),
+   title("very large data base--a conference"),
+   title("very large data base?a conference"),
+   title(null),
+   title(missing)
+];
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/trim/trim.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/trim/trim.1.query.sqlpp
new file mode 100644
index 0000000..61dc619
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/trim/trim.1.query.sqlpp
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+[
+   trim(""),
+   trim("    "),
+   trim(" abc "),
+   trim("abcd"),
+   trim(null),
+   trim(missing),
+   trim("", "ad "),
+   trim("    ", "ad "),
+   trim(" abc ", "ad "),
+   trim("abcd", "ad "),
+   trim("abc", null),
+   trim(null, "abc"),
+   trim(null, null),
+   trim("abc", missing),
+   trim(missing, "abc"),
+   trim(missing, missing)
+];
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
index 21086cb..9057ccb 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
@@ -22,9 +22,9 @@
 
 set `import-private-functions` `true`;
 
-select element tpch.coll_sum((
+select element coll_sum((
     select element (l.l_extendedprice * (1 - l.l_discount))
     from  LineItem as l,
           Part as p
-    where ((p.p_partkey = l.l_partkey) and (((p.p_brand = 'Brand#12') and tpch.`reg-exp`(p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG') and (l.l_quantity >= 1) and (l.l_quantity <= 11) and (p.p_size >= 1) and (p.p_size <= 5) and tpch.`reg-exp`(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#23') and tpch.`reg-exp`(p.p_container,'MED BAG||MED BOX||MED PKG||MED PACK') and (l.l_quantity >= 10) and (l.l_quantity <= 20) and (p.p_size >= 1) and (p.p_size <= 10) and tpch.`reg-exp`(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#34') and tpch.`reg-exp`(p.p_container,'LG CASE||LG BOX||LG PACK||LG PKG') and (l.l_quantity >= 20) and (l.l_quantity <= 30) and (p.p_size >= 1) and (p.p_size <= 15) and tpch.`reg-exp`(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON'))))
+    where ((p.p_partkey = l.l_partkey) and (((p.p_brand = 'Brand#12') and regexp_contains(p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG') and (l.l_quantity >= 1) and (l.l_quantity <= 11) and (p.p_size >= 1) and (p.p_size <= 5) and regexp_contains(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#23') and regexp_contains(p.p_container,'MED BAG||MED BOX||MED PKG||MED PACK') and (l.l_quantity >= 10) and (l.l_quantity <= 20) and (p.p_size >= 1) and (p.p_size <= 10) and regexp_contains(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#34') and regexp_contains(p.p_container,'LG CASE||LG BOX||LG PACK||LG PKG') and (l.l_quantity >= 20) and (l.l_quantity <= 30) and (p.p_size >= 1) and (p.p_size <= 15) and regexp_contains(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON'))))
 ));
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
index cb352ea..318e939 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
@@ -28,28 +28,28 @@
   WHERE
   (
     p_brand = 'Brand#12'
-    AND `reg-exp`(p_container, 'SM CASE||SM BOX||SM PACK||SM PKG')
+    AND regexp_contains(p_container, 'SM CASE||SM BOX||SM PACK||SM PKG')
     AND l_quantity >= 1 and l_quantity <= 11
     AND p_size >= 1 and p_size <= 5
-    AND `reg-exp`(l_shipmode, 'AIR||AIR REG')
+    AND regexp_contains(l_shipmode, 'AIR||AIR REG')
     AND l_shipinstruct = 'DELIVER IN PERSON'
   )
   OR
   (
     p_brand = 'Brand#23'
-    AND `reg-exp`(p_container, 'MED BAG||MED BOX||MED PKG||MED PACK')
+    AND regexp_contains(p_container, 'MED BAG||MED BOX||MED PKG||MED PACK')
     AND l_quantity >= 10 and l_quantity <= 20
     AND p_size >= 1 and p_size <= 10
-    AND `reg-exp`(l_shipmode, 'AIR||AIR REG')
+    AND regexp_contains(l_shipmode, 'AIR||AIR REG')
     AND l_shipinstruct = 'DELIVER IN PERSON'
   )
   OR
   (
     p_brand = 'Brand#34'
-    AND `reg-exp`(p_container, 'LG CASE||LG BOX||LG PACK||LG PKG')
+    AND regexp_contains(p_container, 'LG CASE||LG BOX||LG PACK||LG PKG')
     AND l_quantity >= 20 and l_quantity <= 30
     AND p_size >= 1 and p_size <= 15
-    AND `reg-exp`(l_shipmode, 'AIR||AIR REG')
+    AND regexp_contains(l_shipmode, 'AIR||AIR REG')
     AND l_shipinstruct = 'DELIVER IN PERSON'
   )
 ;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
index 73b8daf..4b4da55 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
@@ -28,28 +28,28 @@
   WHERE
   (
     p.p_brand = 'Brand#12'
-    AND `reg-exp`(p.p_container, 'SM CASE||SM BOX||SM PACK||SM PKG')
+    AND regexp_contains(p.p_container, 'SM CASE||SM BOX||SM PACK||SM PKG')
     AND l.l_quantity >= 1 and l.l_quantity <= 11
     AND p.p_size >= 1 and p.p_size <= 5
-    AND `reg-exp`(l.l_shipmode, 'AIR||AIR REG')
+    AND regexp_contains(l.l_shipmode, 'AIR||AIR REG')
     AND l.l_shipinstruct = 'DELIVER IN PERSON'
   )
   OR
   (
     p.p_brand = 'Brand#23'
-    AND `reg-exp`(p.p_container, 'MED BAG||MED BOX||MED PKG||MED PACK')
+    AND regexp_contains(p.p_container, 'MED BAG||MED BOX||MED PKG||MED PACK')
     AND l.l_quantity >= 10 and l.l_quantity <= 20
     AND p.p_size >= 1 and p.p_size <= 10
-    AND `reg-exp`(l.l_shipmode, 'AIR||AIR REG')
+    AND regexp_contains(l.l_shipmode, 'AIR||AIR REG')
     AND l.l_shipinstruct = 'DELIVER IN PERSON'
   )
   OR
   (
     p.p_brand = 'Brand#34'
-    AND `reg-exp`(p.p_container, 'LG CASE||LG BOX||LG PACK||LG PKG')
+    AND regexp_contains(p.p_container, 'LG CASE||LG BOX||LG PACK||LG PKG')
     AND l.l_quantity >= 20 and l.l_quantity <= 30
     AND p.p_size >= 1 and p.p_size <= 15
-    AND `reg-exp`(l.l_shipmode, 'AIR||AIR REG')
+    AND regexp_contains(l.l_shipmode, 'AIR||AIR REG')
     AND l.l_shipinstruct = 'DELIVER IN PERSON'
   )
 ;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
index 21086cb..9057ccb 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
@@ -22,9 +22,9 @@
 
 set `import-private-functions` `true`;
 
-select element tpch.coll_sum((
+select element coll_sum((
     select element (l.l_extendedprice * (1 - l.l_discount))
     from  LineItem as l,
           Part as p
-    where ((p.p_partkey = l.l_partkey) and (((p.p_brand = 'Brand#12') and tpch.`reg-exp`(p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG') and (l.l_quantity >= 1) and (l.l_quantity <= 11) and (p.p_size >= 1) and (p.p_size <= 5) and tpch.`reg-exp`(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#23') and tpch.`reg-exp`(p.p_container,'MED BAG||MED BOX||MED PKG||MED PACK') and (l.l_quantity >= 10) and (l.l_quantity <= 20) and (p.p_size >= 1) and (p.p_size <= 10) and tpch.`reg-exp`(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#34') and tpch.`reg-exp`(p.p_container,'LG CASE||LG BOX||LG PACK||LG PKG') and (l.l_quantity >= 20) and (l.l_quantity <= 30) and (p.p_size >= 1) and (p.p_size <= 15) and tpch.`reg-exp`(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON'))))
+    where ((p.p_partkey = l.l_partkey) and (((p.p_brand = 'Brand#12') and regexp_contains(p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG') and (l.l_quantity >= 1) and (l.l_quantity <= 11) and (p.p_size >= 1) and (p.p_size <= 5) and regexp_contains(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#23') and regexp_contains(p.p_container,'MED BAG||MED BOX||MED PKG||MED PACK') and (l.l_quantity >= 10) and (l.l_quantity <= 20) and (p.p_size >= 1) and (p.p_size <= 10) and regexp_contains(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#34') and regexp_contains(p.p_container,'LG CASE||LG BOX||LG PACK||LG PKG') and (l.l_quantity >= 20) and (l.l_quantity <= 30) and (p.p_size >= 1) and (p.p_size <= 15) and regexp_contains(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON'))))
 ));
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
index d2ca05c..df4e276 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q19_discounted_revenue/q19_discounted_revenue.3.query.sqlpp
@@ -26,5 +26,5 @@
     select element (l.l_extendedprice * (1 - l.l_discount))
     from  LineItem as l,
           Part as p
-    where ((p.p_partkey = l.l_partkey) and (((p.p_brand = 'Brand#12') and tpch.`reg-exp`(p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG') and (l.l_quantity >= 1) and (l.l_quantity <= 11) and (p.p_size >= 1) and (p.p_size <= 5) and tpch.`reg-exp`(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#23') and tpch.`reg-exp`(p.p_container,'MED BAG||MED BOX||MED PKG||MED PACK') and (l.l_quantity >= 10) and (l.l_quantity <= 20) and (p.p_size >= 1) and (p.p_size <= 10) and tpch.`reg-exp`(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#34') and tpch.`reg-exp`(p.p_container,'LG CASE||LG BOX||LG PACK||LG PKG') and (l.l_quantity >= 20) and (l.l_quantity <= 30) and (p.p_size >= 1) and (p.p_size <= 15) and tpch.`reg-exp`(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON'))))
+    where ((p.p_partkey = l.l_partkey) and (((p.p_brand = 'Brand#12') and regexp_contains(p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG') and (l.l_quantity >= 1) and (l.l_quantity <= 11) and (p.p_size >= 1) and (p.p_size <= 5) and regexp_contains(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#23') and regexp_contains(p.p_container,'MED BAG||MED BOX||MED PKG||MED PACK') and (l.l_quantity >= 10) and (l.l_quantity <= 20) and (p.p_size >= 1) and (p.p_size <= 10) and regexp_contains(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON')) or ((p.p_brand = 'Brand#34') and regexp_contains(p.p_container,'LG CASE||LG BOX||LG PACK||LG PKG') and (l.l_quantity >= 20) and (l.l_quantity <= 30) and (p.p_size >= 1) and (p.p_size <= 15) and regexp_contains(l.l_shipmode,'AIR||AIR REG') and (l.l_shipinstruct = 'DELIVER IN PERSON'))))
 ));
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/comparison/greatest_mixed/greatest_mixed.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/comparison/greatest_mixed/greatest_mixed.1.adm
new file mode 100644
index 0000000..2f52450
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/comparison/greatest_mixed/greatest_mixed.1.adm
@@ -0,0 +1 @@
+10.0
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/comparison/least_mixed/least_mixed.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/comparison/least_mixed/least_mixed.1.adm
new file mode 100644
index 0000000..134d589
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/comparison/least_mixed/least_mixed.1.adm
@@ -0,0 +1 @@
+-2.0
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/concat_pipe_multi/concat_pipe_multi.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/concat_pipe_multi/concat_pipe_multi.1.adm
new file mode 100644
index 0000000..90ca27a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/concat_pipe_multi/concat_pipe_multi.1.adm
@@ -0,0 +1 @@
+"hello new world"
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/initcap/initcap.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/initcap/initcap.1.adm
new file mode 100644
index 0000000..5f6a8de
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/initcap/initcap.1.adm
@@ -0,0 +1 @@
+[ "", "Very Large Data Base--A Conference", "Very Large Data Base?A Conference", null, null ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/ltrim/ltrim.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/ltrim/ltrim.1.adm
new file mode 100644
index 0000000..d336557
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/ltrim/ltrim.1.adm
@@ -0,0 +1 @@
+[ "", "", "abc ", "abcd", null, null, "", "", "bc ", "bcd", null, null, null, null, null, null ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/position/position.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/position/position.1.adm
new file mode 100644
index 0000000..76e3e97
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/position/position.1.adm
@@ -0,0 +1 @@
+[ 2, -1 ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_like/regexp_like.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_like/regexp_like.1.adm
new file mode 100644
index 0000000..1d8287b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_like/regexp_like.1.adm
@@ -0,0 +1,17 @@
+false
+false
+false
+false
+false
+false
+false
+false
+false
+false
+false
+false
+false
+false
+true
+true
+true
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_position/regexp_position.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_position/regexp_position.1.adm
new file mode 100644
index 0000000..428917f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_position/regexp_position.1.adm
@@ -0,0 +1,15 @@
+0
+-1
+0
+0
+0
+-1
+0
+-1
+-1
+0
+0
+0
+0
+-1
+0
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_position_with_flag/regexp_position_with_flag.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_position_with_flag/regexp_position_with_flag.1.adm
new file mode 100644
index 0000000..fa99af7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/regexp_position_with_flag/regexp_position_with_flag.1.adm
@@ -0,0 +1 @@
+{ "result1": 0 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/rtrim/rtrim.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/rtrim/rtrim.1.adm
new file mode 100644
index 0000000..bcaee0b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/rtrim/rtrim.1.adm
@@ -0,0 +1 @@
+[ "", "", " abc", "abcd", null, null, "", "", " abc", "abc", null, null, null, null, null, null ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/string/trim/trim.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/trim/trim.1.adm
new file mode 100644
index 0000000..410cb004
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/string/trim/trim.1.adm
@@ -0,0 +1 @@
+[ "", "", "abc", "abcd", null, null, "", "", "bc", "bc", null, null, null, null, null, null ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.ast
index 156754d..cc6a71b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q19_discounted_revenue/q19_discounted_revenue.3.ast
@@ -56,7 +56,7 @@
               LiteralExpr [STRING] [Brand#12]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$p ]
                 Field=p_container
@@ -100,7 +100,7 @@
               LiteralExpr [LONG] [5]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$l ]
                 Field=l_shipmode
@@ -128,7 +128,7 @@
               LiteralExpr [STRING] [Brand#23]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$p ]
                 Field=p_container
@@ -172,7 +172,7 @@
               LiteralExpr [LONG] [10]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$l ]
                 Field=l_shipmode
@@ -200,7 +200,7 @@
               LiteralExpr [STRING] [Brand#34]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$p ]
                 Field=p_container
@@ -244,7 +244,7 @@
               LiteralExpr [LONG] [15]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$l ]
                 Field=l_shipmode
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q19_discounted_revenue/q19_discounted_revenue.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q19_discounted_revenue/q19_discounted_revenue.3.ast
index 156754d..cc6a71b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q19_discounted_revenue/q19_discounted_revenue.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q19_discounted_revenue/q19_discounted_revenue.3.ast
@@ -56,7 +56,7 @@
               LiteralExpr [STRING] [Brand#12]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$p ]
                 Field=p_container
@@ -100,7 +100,7 @@
               LiteralExpr [LONG] [5]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$l ]
                 Field=l_shipmode
@@ -128,7 +128,7 @@
               LiteralExpr [STRING] [Brand#23]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$p ]
                 Field=p_container
@@ -172,7 +172,7 @@
               LiteralExpr [LONG] [10]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$l ]
                 Field=l_shipmode
@@ -200,7 +200,7 @@
               LiteralExpr [STRING] [Brand#34]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$p ]
                 Field=p_container
@@ -244,7 +244,7 @@
               LiteralExpr [LONG] [15]
             ]
             and
-            FunctionCall tpch.reg-exp@2[
+            FunctionCall tpch.matches@2[
               FieldAccessor [
                 Variable [ Name=$l ]
                 Field=l_shipmode
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 77b4a9c..5aa466c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -1146,6 +1146,16 @@
         <output-dir compare="Text">binary_null</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="comparison">
+      <compilation-unit name="greatest_mixed">
+        <output-dir compare="Text">greatest_mixed</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="comparison">
+      <compilation-unit name="least_mixed">
+        <output-dir compare="Text">least_mixed</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="constructor">
     <test-case FilePath="constructor">
@@ -5073,6 +5083,21 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="string">
+      <compilation-unit name="concat_pipe">
+        <output-dir compare="Text">concat_03</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
+      <compilation-unit name="concat_pipe_multi">
+        <output-dir compare="Text">concat_pipe_multi</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
+      <compilation-unit name="concat_func">
+        <output-dir compare="Text">concat_03</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
       <compilation-unit name="constructor">
         <output-dir compare="Text">constructor</output-dir>
       </compilation-unit>
@@ -5148,6 +5173,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="string">
+      <compilation-unit name="initcap">
+        <output-dir compare="Text">initcap</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
       <compilation-unit name="length_01">
         <output-dir compare="Text">length_01</output-dir>
       </compilation-unit>
@@ -5173,6 +5203,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="string">
+      <compilation-unit name="ltrim">
+        <output-dir compare="Text">ltrim</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
       <compilation-unit name="matches02">
         <output-dir compare="Text">matches02</output-dir>
       </compilation-unit>
@@ -5238,6 +5273,46 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="string">
+      <compilation-unit name="position">
+        <output-dir compare="Text">position</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
+      <compilation-unit name="regexp_contains">
+        <output-dir compare="Text">matches06</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
+      <compilation-unit name="regexp_contains_with_flag">
+        <output-dir compare="Text">matches23</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
+      <compilation-unit name="regexp_like">
+        <output-dir compare="Text">regexp_like</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
+      <compilation-unit name="regexp_like_with_flag">
+        <output-dir compare="Text">matches23</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
+      <compilation-unit name="regexp_position">
+        <output-dir compare="Text">regexp_position</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
+      <compilation-unit name="regexp_position_with_flag">
+        <output-dir compare="Text">regexp_position_with_flag</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
+      <compilation-unit name="regexp_replace">
+        <output-dir compare="Text">replace22</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
       <compilation-unit name="replace1">
         <output-dir compare="Text">replace1</output-dir>
       </compilation-unit>
@@ -5263,6 +5338,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="string">
+      <compilation-unit name="rtrim">
+        <output-dir compare="Text">rtrim</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
       <compilation-unit name="start-with1">
         <output-dir compare="Text">start-with1</output-dir>
       </compilation-unit>
@@ -5465,6 +5545,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="string">
+      <compilation-unit name="title">
+        <output-dir compare="Text">initcap</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
       <compilation-unit name="toLowerCase02">
         <output-dir compare="Text">toLowerCase02</output-dir>
       </compilation-unit>
@@ -5480,6 +5565,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="string">
+      <compilation-unit name="trim">
+        <output-dir compare="Text">trim</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="string">
       <compilation-unit name="uppercase">
         <output-dir compare="Text">uppercase</output-dir>
       </compilation-unit>
diff --git a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.html b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.html
deleted file mode 100644
index d3670d6..0000000
--- a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.html
+++ /dev/null
@@ -1,774 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
-<HTML>
-<HEAD>
-<TITLE>BNF for AQL.jj</TITLE>
-</HEAD>
-<BODY>
-<H1 ALIGN=CENTER>BNF for AQL.jj</H1>
-<H2 ALIGN=CENTER>TOKENS</H2>
-<TABLE>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;ASC: "asc"&gt;
-| &lt;AT: "at"&gt;
-| &lt;BY: "by"&gt;
-| &lt;DATASET: "dataset"&gt;
-| &lt;DECOR: "decor"&gt;
-| &lt;DESC: "desc"&gt;
-| &lt;DISTINCT: "distinct"&gt;
-| &lt;ELSE: "else"&gt;
-| &lt;EVERY: "every"&gt;
-| &lt;FOR: "for"&gt;
-| &lt;FROM: "from"&gt;
-| &lt;GROUP: "group"&gt;
-| &lt;IF: "if"&gt;
-| &lt;IN: "in"&gt;
-| &lt;LET: "let"&gt;
-| &lt;LIMIT: "limit"&gt;
-| &lt;OFFSET: "offset"&gt;
-| &lt;ORDER: "order"&gt;
-| &lt;RETURN: "return"&gt;
-| &lt;SATISFIES: "satisfies"&gt;
-| &lt;SELECT: "select"&gt;
-| &lt;SOME: "some"&gt;
-| &lt;THEN: "then"&gt;
-| &lt;UNION: "union"&gt;
-| &lt;WHERE: "where"&gt;
-| &lt;WITH: "with"&gt;
-| &lt;KEEPING: "keeping"&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;CARET: "^"&gt;
-| &lt;DIV: "/"&gt;
-| &lt;IDIV: "idiv"&gt;
-| &lt;MINUS: "-"&gt;
-| &lt;MOD: "%"&gt;
-| &lt;MUL: "*"&gt;
-| &lt;PLUS: "+"&gt;
-| &lt;LEFTPAREN: "("&gt;
-| &lt;RIGHTPAREN: ")"&gt;
-| &lt;LEFTBRACKET: "["&gt;
-| &lt;RIGHTBRACKET: "]"&gt;
-| &lt;COLON: ":"&gt;
-| &lt;COMMA: ","&gt;
-| &lt;DOT: "."&gt;
-| &lt;QUES: "?"&gt;
-| &lt;LT: "&lt;"&gt;
-| &lt;GT: "&gt;"&gt;
-| &lt;LE: "&lt;="&gt;
-| &lt;GE: "&gt;="&gt;
-| &lt;EQ: "="&gt;
-| &lt;NE: "!="&gt;
-| &lt;SIMILAR: "~="&gt;
-| &lt;ASSIGN: ":="&gt;
-| &lt;AND: "and"&gt;
-| &lt;OR: "or"&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;LEFTBRACE: "{"&gt; : DEFAULT
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT&gt; TOKEN : {
-&lt;RIGHTBRACE: "}"&gt; : {
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;LEFTDBLBRACE: "{{"&gt; : IN_DBL_BRACE
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;IN_DBL_BRACE&gt; TOKEN : {
-&lt;RIGHTDBLBRACE: "}}"&gt; : {
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;INTEGER_LITERAL: (&lt;DIGIT&gt;)+&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;NULL: "null"&gt;
-| &lt;TRUE: "true"&gt;
-| &lt;FALSE: "false"&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;#DIGIT: ["0"-"9"]&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;DOUBLE_LITERAL: &lt;DIGITS&gt; | &lt;DIGITS&gt; ("." &lt;DIGITS&gt;)? | "." &lt;DIGITS&gt;&gt;
-| &lt;FLOAT_LITERAL: &lt;DIGITS&gt; ("f" | "F") | &lt;DIGITS&gt; ("." &lt;DIGITS&gt; ("f" | "F"))? | "." &lt;DIGITS&gt; ("f" | "F")&gt;
-| &lt;DIGITS: (&lt;DIGIT&gt;)+&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;#LETTER: ["A"-"Z","a"-"z"]&gt;
-| &lt;SPECIALCHARS: ["$","_","-"]&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;STRING_LITERAL: "\"" (&lt;EscapeQuot&gt; | &lt;EscapeBslash&gt; | &lt;EscapeSlash&gt; | &lt;EscapeBspace&gt; | &lt;EscapeFormf&gt; | &lt;EscapeNl&gt; | &lt;EscapeCr&gt; | &lt;EscapeTab&gt; | ~["\"","\\"])* "\"" | "\'" (&lt;EscapeApos&gt; | &lt;EscapeBslash&gt; | &lt;EscapeSlash&gt; | &lt;EscapeBspace&gt; | &lt;EscapeFormf&gt; | &lt;EscapeNl&gt; | &lt;EscapeCr&gt; | &lt;EscapeTab&gt; | ~["\'","\\"])* "\'"&gt;
-| &lt;#EscapeQuot: "\\\""&gt;
-| &lt;#EscapeApos: "\\\'"&gt;
-| &lt;#EscapeBslash: "\\\\"&gt;
-| &lt;#EscapeSlash: "\\/"&gt;
-| &lt;#EscapeBspace: "\\b"&gt;
-| &lt;#EscapeFormf: "\\f"&gt;
-| &lt;#EscapeNl: "\\n"&gt;
-| &lt;#EscapeCr: "\\r"&gt;
-| &lt;#EscapeTab: "\\t"&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;IDENTIFIER: &lt;LETTER&gt; (&lt;LETTER&gt; | &lt;DIGIT&gt; | &lt;SPECIALCHARS&gt;)*&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;VARIABLE: "$" &lt;LETTER&gt; (&lt;LETTER&gt; | &lt;DIGIT&gt; | "_")*&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; SKIP : {
-" "
-| "\t"
-| "\r"
-| "\n"
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; SKIP : {
-&lt;"//" (~["\n"])* "\n"&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; SKIP : {
-&lt;"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")?&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; SKIP : {
-"/*" : INSIDE_COMMENT
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;INSIDE_COMMENT&gt; SPECIAL : {
-&lt;"+" (" ")* (~["*"])*&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;INSIDE_COMMENT&gt; SKIP : {
-"/*" : {
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;INSIDE_COMMENT&gt; SKIP : {
-"*/" : {
-| &lt;~[]&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
-</TABLE>
-<H2 ALIGN=CENTER>NON-TERMINALS</H2>
-<TABLE>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod1">Statement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod2">SingleStatement</A> ( ";" )? )* &lt;EOF&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod2">SingleStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod3">DataverseDeclaration</A> | <A HREF="#prod4">FunctionDeclaration</A> | <A HREF="#prod5">CreateStatement</A> | <A HREF="#prod6">LoadStatement</A> | <A HREF="#prod7">DropStatement</A> | <A HREF="#prod8">WriteStatement</A> | <A HREF="#prod9">SetStatement</A> | <A HREF="#prod10">InsertStatement</A> | <A HREF="#prod11">DeleteStatement</A> | <A HREF="#prod12">UpdateStatement</A> | <A HREF="#prod13">FeedStatement</A> | <A HREF="#prod14">CompactStatement</A> | <A HREF="#prod15">Query</A> | <A HREF="#prod16">RefreshExternalDatasetStatement</A> | <A HREF="#prod17">RunStatement</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod3">DataverseDeclaration</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"use" "dataverse" <A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod5">CreateStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"create" ( <A HREF="#prod19">TypeSpecification</A> | <A HREF="#prod20">NodegroupSpecification</A> | <A HREF="#prod21">DatasetSpecification</A> | <A HREF="#prod22">IndexSpecification</A> | <A HREF="#prod23">DataverseSpecification</A> | <A HREF="#prod24">FunctionSpecification</A> | <A HREF="#prod25">FeedSpecification</A> | <A HREF="#prod26">FeedPolicySpecification</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod19">TypeSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"type" <A HREF="#prod27">TypeName</A> <A HREF="#prod28">IfNotExists</A> "as" <A HREF="#prod29">TypeExpr</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod20">NodegroupSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"nodegroup" <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> "on" <A HREF="#prod18">Identifier</A> ( &lt;COMMA&gt; <A HREF="#prod18">Identifier</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod21">DatasetSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "external" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> &lt;LEFTPAREN&gt; <A HREF="#prod27">TypeName</A> &lt;RIGHTPAREN&gt; <A HREF="#prod28">IfNotExists</A> "using" <A HREF="#prod31">AdapterName</A> <A HREF="#prod32">Configuration</A> ( "on" <A HREF="#prod18">Identifier</A> )? ( "hints" <A HREF="#prod33">Properties</A> )? ( "using" "compaction" "policy" <A HREF="#prod34">CompactionPolicy</A> ( <A HREF="#prod32">Configuration</A> )? )? | ( "internal" | "temporary" )? &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> &lt;LEFTPAREN&gt; <A HREF="#prod27">TypeName</A> &lt;RIGHTPAREN&gt; ( &lt;WITH&gt; <A HREF="#prod18">Identifier</A> &lt;LEFTPAREN&gt; <A HREF="#prod27">TypeName</A> &lt;RIGHTPAREN&gt; )? <A HREF="#prod28">IfNotExists</A> <A HREF="#prod35">PrimaryKey</A> ( "autogenerated" )? ( "on" <A HREF="#prod18">Identifier</A> )? ( "hints" <A HREF="#prod33">Properties</A> )? ( "using" "compaction" "policy" <A HREF="#prod34">CompactionPolicy</A> ( <A HREF="#prod32">Configuration</A> )? )? ( "with filter on" <A HREF="#prod36">NestedField</A> )? )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod16">RefreshExternalDatasetStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"refresh external" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod17">RunStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"run" <A HREF="#prod18">Identifier</A> &lt;LEFTPAREN&gt; ( <A HREF="#prod18">Identifier</A> ( &lt;COMMA&gt; )? )* &lt;RIGHTPAREN&gt; &lt;FROM&gt; &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> "to" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod22">IndexSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"index" <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> "on" <A HREF="#prod30">QualifiedName</A> &lt;LEFTPAREN&gt; ( <A HREF="#prod37">OpenField</A> ) ( &lt;COMMA&gt; <A HREF="#prod37">OpenField</A> )* &lt;RIGHTPAREN&gt; ( "type" <A HREF="#prod38">IndexType</A> )? ( "enforced" )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod34">CompactionPolicy</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod39">FilterField</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod38">IndexType</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "btree" | "rtree" | "keyword" | "ngram" &lt;LEFTPAREN&gt; &lt;INTEGER_LITERAL&gt; &lt;RIGHTPAREN&gt; )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod23">DataverseSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"dataverse" <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> ( "with format" <A HREF="#prod40">StringLiteral</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod24">FunctionSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"function" <A HREF="#prod41">FunctionName</A> <A HREF="#prod28">IfNotExists</A> <A HREF="#prod42">ParameterList</A> &lt;LEFTBRACE&gt; <A HREF="#prod43">Expression</A> &lt;RIGHTBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod25">FeedSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "secondary" "feed" <A HREF="#prod30">QualifiedName</A> <A HREF="#prod28">IfNotExists</A> &lt;FROM&gt; "feed" <A HREF="#prod30">QualifiedName</A> ( <A HREF="#prod44">ApplyFunction</A> )? | ( "primary" )? "feed" <A HREF="#prod30">QualifiedName</A> <A HREF="#prod28">IfNotExists</A> "using" <A HREF="#prod31">AdapterName</A> <A HREF="#prod32">Configuration</A> ( <A HREF="#prod44">ApplyFunction</A> )? )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod26">FeedPolicySpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "ingestion" "policy" <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> &lt;FROM&gt; ( "policy" <A HREF="#prod18">Identifier</A> <A HREF="#prod32">Configuration</A> ( "definition" <A HREF="#prod40">StringLiteral</A> )? | "path" <A HREF="#prod18">Identifier</A> ( "definition" <A HREF="#prod40">StringLiteral</A> )? ) )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod42">ParameterList</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTPAREN&gt; ( &lt;VARIABLE&gt; ( &lt;COMMA&gt; &lt;VARIABLE&gt; )* )? &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod28">IfNotExists</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "if not exists" )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod44">ApplyFunction</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"apply" "function" <A HREF="#prod41">FunctionName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod45">GetPolicy</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"using" "policy" <A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod46">FunctionSignature</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod41">FunctionName</A> "@" &lt;INTEGER_LITERAL&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod35">PrimaryKey</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"primary" "key" <A HREF="#prod36">NestedField</A> ( &lt;COMMA&gt; <A HREF="#prod36">NestedField</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod7">DropStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"drop" ( &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> <A HREF="#prod47">IfExists</A> | "index" <A HREF="#prod48">DoubleQualifiedName</A> <A HREF="#prod47">IfExists</A> | "nodegroup" <A HREF="#prod18">Identifier</A> <A HREF="#prod47">IfExists</A> | "type" <A HREF="#prod27">TypeName</A> <A HREF="#prod47">IfExists</A> | "dataverse" <A HREF="#prod18">Identifier</A> <A HREF="#prod47">IfExists</A> | "function" <A HREF="#prod46">FunctionSignature</A> <A HREF="#prod47">IfExists</A> | "feed" <A HREF="#prod30">QualifiedName</A> <A HREF="#prod47">IfExists</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod47">IfExists</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;IF&gt; "exists" )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod10">InsertStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "insert" | "upsert" ) "into" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> <A HREF="#prod15">Query</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod11">DeleteStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"delete" <A HREF="#prod49">Variable</A> &lt;FROM&gt; &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> ( &lt;WHERE&gt; <A HREF="#prod43">Expression</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod12">UpdateStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"update" <A HREF="#prod49">Variable</A> &lt;IN&gt; <A HREF="#prod43">Expression</A> &lt;WHERE&gt; <A HREF="#prod43">Expression</A> &lt;LEFTPAREN&gt; ( <A HREF="#prod50">UpdateClause</A> ( &lt;COMMA&gt; <A HREF="#prod50">UpdateClause</A> )* ) &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod50">UpdateClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "set" <A HREF="#prod43">Expression</A> &lt;ASSIGN&gt; <A HREF="#prod43">Expression</A> | <A HREF="#prod10">InsertStatement</A> | <A HREF="#prod11">DeleteStatement</A> | <A HREF="#prod12">UpdateStatement</A> | &lt;IF&gt; &lt;LEFTPAREN&gt; <A HREF="#prod43">Expression</A> &lt;RIGHTPAREN&gt; &lt;THEN&gt; <A HREF="#prod50">UpdateClause</A> ( &lt;ELSE&gt; <A HREF="#prod50">UpdateClause</A> )? )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod9">SetStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"set" <A HREF="#prod18">Identifier</A> <A HREF="#prod40">StringLiteral</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod8">WriteStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"write" "output" "to" <A HREF="#prod18">Identifier</A> &lt;COLON&gt; <A HREF="#prod40">StringLiteral</A> ( "using" <A HREF="#prod40">StringLiteral</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod6">LoadStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"load" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> "using" <A HREF="#prod31">AdapterName</A> <A HREF="#prod32">Configuration</A> ( "pre-sorted" )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod31">AdapterName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod14">CompactStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"compact" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod13">FeedStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "connect" "feed" <A HREF="#prod30">QualifiedName</A> "to" &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> ( <A HREF="#prod45">GetPolicy</A> )? | "disconnect" "feed" <A HREF="#prod30">QualifiedName</A> &lt;FROM&gt; &lt;DATASET&gt; <A HREF="#prod30">QualifiedName</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod32">Configuration</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTPAREN&gt; ( <A HREF="#prod51">KeyValuePair</A> ( &lt;COMMA&gt; <A HREF="#prod51">KeyValuePair</A> )* )? &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod51">KeyValuePair</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTPAREN&gt; <A HREF="#prod40">StringLiteral</A> &lt;EQ&gt; <A HREF="#prod40">StringLiteral</A> &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod33">Properties</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;LEFTPAREN&gt; <A HREF="#prod52">Property</A> ( &lt;COMMA&gt; <A HREF="#prod52">Property</A> )* &lt;RIGHTPAREN&gt; )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod52">Property</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> &lt;EQ&gt; ( <A HREF="#prod40">StringLiteral</A> | &lt;INTEGER_LITERAL&gt; )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod53">IndexedTypeExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod54">TypeReference</A> | <A HREF="#prod55">OrderedListTypeDef</A> | <A HREF="#prod56">UnorderedListTypeDef</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod29">TypeExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod57">RecordTypeDef</A> | <A HREF="#prod54">TypeReference</A> | <A HREF="#prod55">OrderedListTypeDef</A> | <A HREF="#prod56">UnorderedListTypeDef</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod57">RecordTypeDef</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( "closed" | "open" )? &lt;LEFTBRACE&gt; ( <A HREF="#prod58">RecordField</A> ( &lt;COMMA&gt; <A HREF="#prod58">RecordField</A> )* )? &lt;RIGHTBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod58">RecordField</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> &lt;COLON&gt; <A HREF="#prod29">TypeExpr</A> ( &lt;QUES&gt; )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod54">TypeReference</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod55">OrderedListTypeDef</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTBRACKET&gt; ( <A HREF="#prod29">TypeExpr</A> ) &lt;RIGHTBRACKET&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod56">UnorderedListTypeDef</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTDBLBRACE&gt; ( <A HREF="#prod29">TypeExpr</A> ) &lt;RIGHTDBLBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod41">FunctionName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> ( "#" <A HREF="#prod18">Identifier</A> )? | "#" <A HREF="#prod18">Identifier</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod27">TypeName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod30">QualifiedName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod18">Identifier</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;IDENTIFIER&gt; | <A HREF="#prod40">StringLiteral</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod37">OpenField</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod36">NestedField</A> ( &lt;COLON&gt; <A HREF="#prod53">IndexedTypeExpr</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod36">NestedField</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> ( &lt;LEFTPAREN&gt; &lt;RIGHTPAREN&gt; )? ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod40">StringLiteral</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;STRING_LITERAL&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod30">QualifiedName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod48">DoubleQualifiedName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> &lt;DOT&gt; <A HREF="#prod18">Identifier</A> ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod4">FunctionDeclaration</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>"declare" "function" <A HREF="#prod18">Identifier</A> <A HREF="#prod42">ParameterList</A> &lt;LEFTBRACE&gt; <A HREF="#prod43">Expression</A> &lt;RIGHTBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod15">Query</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod43">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod43">Expression</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod59">OperatorExpr</A> | <A HREF="#prod60">IfThenElse</A> | <A HREF="#prod61">FLWOGR</A> | <A HREF="#prod62">QuantifiedExpression</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod59">OperatorExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod63">AndExpr</A> ( &lt;OR&gt; <A HREF="#prod63">AndExpr</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod63">AndExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod64">RelExpr</A> ( &lt;AND&gt; <A HREF="#prod64">RelExpr</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod64">RelExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod65">AddExpr</A> ( ( &lt;LT&gt; | &lt;GT&gt; | &lt;LE&gt; | &lt;GE&gt; | &lt;EQ&gt; | &lt;NE&gt; | &lt;SIMILAR&gt; ) <A HREF="#prod65">AddExpr</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod65">AddExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod66">MultExpr</A> ( ( &lt;PLUS&gt; | &lt;MINUS&gt; ) <A HREF="#prod66">MultExpr</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod66">MultExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod67">UnionExpr</A> ( ( &lt;MUL&gt; | &lt;DIV&gt; | &lt;MOD&gt; | &lt;CARET&gt; | &lt;IDIV&gt; ) <A HREF="#prod67">UnionExpr</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod67">UnionExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod68">UnaryExpr</A> ( &lt;UNION&gt; ( <A HREF="#prod68">UnaryExpr</A> ) )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod68">UnaryExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( ( &lt;PLUS&gt; | &lt;MINUS&gt; ) )? <A HREF="#prod69">ValueExpr</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod69">ValueExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod70">PrimaryExpr</A> ( <A HREF="#prod71">Field</A> | <A HREF="#prod72">Index</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod71">Field</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DOT&gt; <A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod72">Index</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTBRACKET&gt; ( <A HREF="#prod43">Expression</A> | &lt;QUES&gt; ) &lt;RIGHTBRACKET&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod70">PrimaryExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod73">FunctionCallExpr</A> | <A HREF="#prod74">Literal</A> | <A HREF="#prod75">DatasetAccessExpression</A> | <A HREF="#prod76">VariableRef</A> | <A HREF="#prod77">ListConstructor</A> | <A HREF="#prod78">RecordConstructor</A> | <A HREF="#prod79">ParenthesizedExpression</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod74">Literal</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod40">StringLiteral</A> | &lt;INTEGER_LITERAL&gt; | &lt;FLOAT_LITERAL&gt; | &lt;DOUBLE_LITERAL&gt; | &lt;NULL&gt; | &lt;TRUE&gt; | &lt;FALSE&gt; )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod76">VariableRef</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;VARIABLE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod49">Variable</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;VARIABLE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod77">ListConstructor</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod80">OrderedListConstructor</A> | <A HREF="#prod81">UnorderedListConstructor</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod80">OrderedListConstructor</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTBRACKET&gt; <A HREF="#prod82">ExpressionList</A> &lt;RIGHTBRACKET&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod81">UnorderedListConstructor</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTDBLBRACE&gt; <A HREF="#prod82">ExpressionList</A> &lt;RIGHTDBLBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod82">ExpressionList</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod43">Expression</A> ( &lt;COMMA&gt; <A HREF="#prod82">ExpressionList</A> )? )? ( <A HREF="#prod83">Comma</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod83">Comma</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;COMMA&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod78">RecordConstructor</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTBRACE&gt; ( <A HREF="#prod84">FieldBinding</A> ( &lt;COMMA&gt; <A HREF="#prod84">FieldBinding</A> )* )? &lt;RIGHTBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod84">FieldBinding</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod43">Expression</A> &lt;COLON&gt; <A HREF="#prod43">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod73">FunctionCallExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod41">FunctionName</A> &lt;LEFTPAREN&gt; ( <A HREF="#prod43">Expression</A> ( &lt;COMMA&gt; <A HREF="#prod43">Expression</A> )* )? &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod75">DatasetAccessExpression</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DATASET&gt; ( ( <A HREF="#prod18">Identifier</A> ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> )? ) | ( &lt;LEFTPAREN&gt; <A HREF="#prod43">Expression</A> &lt;RIGHTPAREN&gt; ) )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod79">ParenthesizedExpression</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTPAREN&gt; <A HREF="#prod43">Expression</A> &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod60">IfThenElse</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IF&gt; &lt;LEFTPAREN&gt; <A HREF="#prod43">Expression</A> &lt;RIGHTPAREN&gt; &lt;THEN&gt; <A HREF="#prod43">Expression</A> &lt;ELSE&gt; <A HREF="#prod43">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod61">FLWOGR</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod85">ForClause</A> | <A HREF="#prod86">LetClause</A> ) ( <A HREF="#prod87">Clause</A> )* ( &lt;RETURN&gt; | &lt;SELECT&gt; ) <A HREF="#prod43">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod87">Clause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod85">ForClause</A> | <A HREF="#prod86">LetClause</A> | <A HREF="#prod88">WhereClause</A> | <A HREF="#prod89">OrderbyClause</A> | <A HREF="#prod90">GroupClause</A> | <A HREF="#prod91">LimitClause</A> | <A HREF="#prod92">DistinctClause</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod85">ForClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;FOR&gt; | &lt;FROM&gt; ) <A HREF="#prod49">Variable</A> ( &lt;AT&gt; <A HREF="#prod49">Variable</A> )? &lt;IN&gt; ( <A HREF="#prod43">Expression</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod86">LetClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;LET&gt; | &lt;WITH&gt; ) <A HREF="#prod49">Variable</A> &lt;ASSIGN&gt; <A HREF="#prod43">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod88">WhereClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;WHERE&gt; <A HREF="#prod43">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod89">OrderbyClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;ORDER&gt; &lt;BY&gt; <A HREF="#prod43">Expression</A> ( ( &lt;ASC&gt; ) | ( &lt;DESC&gt; ) )? ( &lt;COMMA&gt; <A HREF="#prod43">Expression</A> ( ( &lt;ASC&gt; ) | ( &lt;DESC&gt; ) )? )* )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod90">GroupClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;GROUP&gt; &lt;BY&gt; ( <A HREF="#prod49">Variable</A> &lt;ASSIGN&gt; )? <A HREF="#prod43">Expression</A> ( &lt;COMMA&gt; ( <A HREF="#prod49">Variable</A> &lt;ASSIGN&gt; )? <A HREF="#prod43">Expression</A> )* ( &lt;DECOR&gt; <A HREF="#prod49">Variable</A> &lt;ASSIGN&gt; <A HREF="#prod43">Expression</A> ( &lt;COMMA&gt; &lt;DECOR&gt; <A HREF="#prod49">Variable</A> &lt;ASSIGN&gt; <A HREF="#prod43">Expression</A> )* )? ( &lt;WITH&gt; | &lt;KEEPING&gt; ) <A HREF="#prod76">VariableRef</A> ( &lt;COMMA&gt; <A HREF="#prod76">VariableRef</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod91">LimitClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LIMIT&gt; <A HREF="#prod43">Expression</A> ( &lt;OFFSET&gt; <A HREF="#prod43">Expression</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod92">DistinctClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DISTINCT&gt; &lt;BY&gt; <A HREF="#prod43">Expression</A> ( &lt;COMMA&gt; <A HREF="#prod43">Expression</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod62">QuantifiedExpression</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( ( &lt;SOME&gt; ) | ( &lt;EVERY&gt; ) ) <A HREF="#prod49">Variable</A> &lt;IN&gt; <A HREF="#prod43">Expression</A> ( &lt;COMMA&gt; <A HREF="#prod49">Variable</A> &lt;IN&gt; <A HREF="#prod43">Expression</A> )* &lt;SATISFIES&gt; <A HREF="#prod43">Expression</A></TD>
-</TR>
-</TABLE>
-</BODY>
-</HTML>
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java
index 6e2e3e2..a5a1bb8 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java
@@ -32,6 +32,7 @@
     NEQ("!="),
     PLUS("+"),
     MINUS("-"),
+    CONCAT("||"),
     MUL("*"),
     DIV("/"), // float/double
     // divide
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
index 7a26c6b..cf88961 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
@@ -55,6 +55,9 @@
         // Rewrites like/not-like expressions.
         rewriteOperatorExpression();
 
+        // Rewrites several variable-arg functions into their corresponding internal list-input functions.
+        rewriteListInputFunctions();
+
         // Generates ids for variables (considering scopes) but DOES NOT replace unbounded variable access with the dataset function.
         // An unbounded variable within a function could be a bounded variable in the top-level query.
         variableCheckAndRewrite(false);
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index 1ce5de7..dd79969 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -59,6 +59,7 @@
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGlobalAggregationSugarVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGroupByVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppInlineUdfsVisitor;
+import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppListInputFunctionRewriteVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SubstituteGroupbyExpressionWithVariableVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.VariableCheckAndRewriteVisitor;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -122,6 +123,9 @@
         // Generate ids for variables (considering scopes) and replace global variable access with the dataset function.
         variableCheckAndRewrite(true);
 
+        // Rewrites several variable-arg functions into their corresponding internal list-input functions.
+        rewriteListInputFunctions();
+
         // Inlines functions.
         inlineDeclaredUdfs();
 
@@ -154,6 +158,14 @@
         globalAggregationVisitor.visit(topExpr, null);
     }
 
+    protected void rewriteListInputFunctions() throws AsterixException {
+        if (topExpr == null) {
+            return;
+        }
+        SqlppListInputFunctionRewriteVisitor listInputFunctionVisitor = new SqlppListInputFunctionRewriteVisitor();
+        listInputFunctionVisitor.visit(topExpr, null);
+    }
+
     protected void rewriteFunctionNames() throws AsterixException {
         if (topExpr == null) {
             return;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/OperatorExpressionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/OperatorExpressionVisitor.java
index 815e020..bbe7c27 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/OperatorExpressionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/OperatorExpressionVisitor.java
@@ -30,8 +30,8 @@
 import org.apache.asterix.lang.common.expression.CallExpr;
 import org.apache.asterix.lang.common.expression.OperatorExpr;
 import org.apache.asterix.lang.common.expression.QuantifiedExpression;
-import org.apache.asterix.lang.common.expression.QuantifiedExpression.Quantifier;
 import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.expression.QuantifiedExpression.Quantifier;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.common.struct.OperatorType;
 import org.apache.asterix.lang.common.struct.QuantifiedPair;
@@ -39,30 +39,33 @@
 
 public class OperatorExpressionVisitor extends AbstractSqlppExpressionScopingVisitor {
 
+    private static final String CONCAT = "concat";
+
     public OperatorExpressionVisitor(LangRewritingContext context) {
         super(context);
     }
 
     @Override
     public Expression visit(OperatorExpr operatorExpr, ILangExpression arg) throws AsterixException {
-
         List<Expression> newExprList = new ArrayList<>();
         for (Expression expr : operatorExpr.getExprList()) {
             newExprList.add(expr.accept(this, operatorExpr));
         }
         operatorExpr.setExprList(newExprList);
-        if (operatorExpr.getExprList().size() == 2) {
-            OperatorType opType = operatorExpr.getOpList().get(0);
-            switch (opType) {
-                case LIKE:
-                case NOT_LIKE:
-                    return processLikeOperator(operatorExpr, opType);
-                case IN:
-                case NOT_IN:
-                    return processInOperator(operatorExpr, opType);
-                default:
-                    break;
-            }
+        OperatorType opType = operatorExpr.getOpList().get(0);
+        switch (opType) {
+        // There can only be one LIKE/NOT_LIKE/IN/NOT_IN in an operator expression (according to the grammar).
+            case LIKE:
+            case NOT_LIKE:
+                return processLikeOperator(operatorExpr, opType);
+            case IN:
+            case NOT_IN:
+                return processInOperator(operatorExpr, opType);
+            case CONCAT:
+                // There can be multiple "||"s in one operator expression (according to the grammar).
+                return processConcatOperator(operatorExpr);
+            default:
+                break;
         }
         return operatorExpr;
     }
@@ -73,7 +76,7 @@
             return likeExpr;
         }
         return new CallExpr(new FunctionSignature(null, "not", 1),
-                new ArrayList<Expression>(Collections.singletonList(likeExpr)));
+ new ArrayList<>(Collections.singletonList(likeExpr)));
     }
 
     private Expression processInOperator(OperatorExpr operatorExpr, OperatorType opType) throws AsterixException {
@@ -86,13 +89,18 @@
         comparison.setCurrentop(true);
         if (opType == OperatorType.IN) {
             comparison.addOperator("=");
-            return new QuantifiedExpression(Quantifier.SOME, new ArrayList<QuantifiedPair>(
+            return new QuantifiedExpression(Quantifier.SOME, new ArrayList<>(
                     Collections.singletonList(new QuantifiedPair(bindingVar, collectionExpr))), comparison);
         } else {
             comparison.addOperator("!=");
-            return new QuantifiedExpression(Quantifier.EVERY, new ArrayList<QuantifiedPair>(
+            return new QuantifiedExpression(Quantifier.EVERY, new ArrayList<>(
                     Collections.singletonList(new QuantifiedPair(bindingVar, collectionExpr))), comparison);
         }
     }
 
+    private Expression processConcatOperator(OperatorExpr operatorExpr) {
+        // All operators have to be "||"s (according to the grammar).
+        return new CallExpr(new FunctionSignature(null, CONCAT, 1), operatorExpr.getExprList());
+    }
+
 }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppListInputFunctionRewriteVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppListInputFunctionRewriteVisitor.java
new file mode 100644
index 0000000..847076b
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppListInputFunctionRewriteVisitor.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.lang.sqlpp.rewrites.visitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.ILangExpression;
+import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
+import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppSimpleExpressionVisitor;
+
+/**
+ * This visitor rewrites several variable-arg user-facing functions to their coressponding
+ * AsterixDB internal functions that takes a list as the input.
+ */
+public class SqlppListInputFunctionRewriteVisitor extends AbstractSqlppSimpleExpressionVisitor {
+
+    @Override
+    public Expression visit(CallExpr callExpr, ILangExpression arg) throws AsterixException {
+        List<Expression> newExprList = new ArrayList<>();
+        for (Expression expr : callExpr.getExprList()) {
+            newExprList.add(expr.accept(this, arg));
+        }
+        callExpr.setExprList(newExprList);
+        return FunctionMapUtil.normalizedListInputFunctions(callExpr);
+    }
+
+}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/FunctionMapUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/FunctionMapUtil.java
index 6d19995..369b8dd 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/FunctionMapUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/FunctionMapUtil.java
@@ -18,12 +18,16 @@
  */
 package org.apache.asterix.lang.sqlpp.util;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.functions.FunctionConstants;
 import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.ListConstructor;
 import org.apache.asterix.lang.common.util.FunctionUtil;
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -43,12 +47,27 @@
         FUNCTION_NAME_MAP.put("lower", "lowercase"); // SQL: lower, AQL: lowercase
         FUNCTION_NAME_MAP.put("substr", "substring"); // SQL: substr,  AQL: substring
         FUNCTION_NAME_MAP.put("upper", "uppercase"); //SQL: upper, AQL: uppercase
+        FUNCTION_NAME_MAP.put("title", "initcap"); //SQL: title, SQL/AQL: initcap
+        FUNCTION_NAME_MAP.put("regexp_contains", "matches"); //SQL: regexp_contains, AQL: matches
+        FUNCTION_NAME_MAP.put("regexp_like", "regexp-like"); //SQL: regexp_like, AQL: regexp-like
+        FUNCTION_NAME_MAP.put("regexp_position", "regexp-position"); //SQL: regexp_position, AQL: regexp-position
+        FUNCTION_NAME_MAP.put("regexp_replace", "replace"); //SQL: regexp_replace, AQL: replace
+    }
+
+    // Maps from a variable-arg SQL function names to an internal list-arg function name.
+    private static final Map<String, String> LIST_INPUT_FUNCTION_MAP = new HashMap<>();
+
+    static {
+        LIST_INPUT_FUNCTION_MAP.put("concat", "string-concat");
+        LIST_INPUT_FUNCTION_MAP.put("greatest", CORE_AGGREGATE_PREFIX + SQL_PREFIX + "max");
+        LIST_INPUT_FUNCTION_MAP.put("least", CORE_AGGREGATE_PREFIX + SQL_PREFIX + "min");
     }
 
     /**
      * Whether a function signature is a SQL-92 core aggregate function.
      *
-     * @param fs,
+     * @param signature
+     *            ,
      *            the function signature.
      * @return true if the function signature is a SQL-92 core aggregate,
      *         false otherwise.
@@ -120,6 +139,25 @@
     }
 
     /**
+     * Rewrites a variable-arg, user-surface function call into an internal, list-arg function.
+     *
+     * @param callExpr
+     *            The input call expression.
+     * @return a new call expression that calls the corresponding AsterixDB internal function.
+     */
+    public static CallExpr normalizedListInputFunctions(CallExpr callExpr) {
+        FunctionSignature fs = callExpr.getFunctionSignature();
+        String internalFuncName = LIST_INPUT_FUNCTION_MAP.get(fs.getName().toLowerCase());
+        if (internalFuncName == null) {
+            return callExpr;
+        }
+        callExpr.setFunctionSignature(new FunctionSignature(FunctionConstants.ASTERIX_NS, internalFuncName, 1));
+        callExpr.setExprList(new ArrayList<>(Collections.singletonList(new ListConstructor(
+                ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR, callExpr.getExprList()))));
+        return callExpr;
+    }
+
+    /**
      * Removes the "coll_" prefix for user-facing SQL++ core aggregate function names.
      *
      * @param name,
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html
deleted file mode 100644
index 7b37ab4..0000000
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html
+++ /dev/null
@@ -1,917 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
-<HTML>
-<HEAD>
-<TITLE>BNF for SQLPP.jj</TITLE>
-</HEAD>
-<BODY>
-<H1 ALIGN=CENTER>BNF for SQLPP.jj</H1>
-<H2 ALIGN=CENTER>TOKENS</H2>
-<TABLE>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN [IGNORE_CASE] : {
-&lt;ALL: "all"&gt;
-| &lt;AND: "and"&gt;
-| &lt;APPLY: "apply"&gt;
-| &lt;AS: "as"&gt;
-| &lt;ASC: "asc"&gt;
-| &lt;AT: "at"&gt;
-| &lt;AUTOGENERATED: "autogenerated"&gt;
-| &lt;BETWEEN: "between"&gt;
-| &lt;BTREE: "btree"&gt;
-| &lt;BY: "by"&gt;
-| &lt;CASE: "case"&gt;
-| &lt;CLOSED: "closed"&gt;
-| &lt;CREATE: "create"&gt;
-| &lt;COMPACTION: "compaction"&gt;
-| &lt;COMPACT: "compact"&gt;
-| &lt;CONNECT: "connect"&gt;
-| &lt;CORRELATE: "correlate"&gt;
-| &lt;DATASET: "table"&gt;
-| &lt;COLLECTION: "collection"&gt;
-| &lt;DATAVERSE: "database"&gt;
-| &lt;DECLARE: "declare"&gt;
-| &lt;DEFINITION: "definition"&gt;
-| &lt;DELETE: "delete"&gt;
-| &lt;DESC: "desc"&gt;
-| &lt;DISCONNECT: "disconnect"&gt;
-| &lt;DISTINCT: "distinct"&gt;
-| &lt;DROP: "drop"&gt;
-| &lt;ELEMENT: "element"&gt;
-| &lt;ELSE: "else"&gt;
-| &lt;ENFORCED: "enforced"&gt;
-| &lt;END: "end"&gt;
-| &lt;EVERY: "every"&gt;
-| &lt;EXCEPT: "except"&gt;
-| &lt;EXISTS: "exists"&gt;
-| &lt;EXTERNAL: "external"&gt;
-| &lt;FEED: "feed"&gt;
-| &lt;FILTER: "filter"&gt;
-| &lt;FLATTEN: "flatten"&gt;
-| &lt;FOR: "for"&gt;
-| &lt;FORMAT: "format"&gt;
-| &lt;FROM: "from"&gt;
-| &lt;FULL: "full"&gt;
-| &lt;FUNCTION: "function"&gt;
-| &lt;GROUP: "group"&gt;
-| &lt;HAVING: "having"&gt;
-| &lt;HINTS: "hints"&gt;
-| &lt;IF: "if"&gt;
-| &lt;INTO: "into"&gt;
-| &lt;IN: "in"&gt;
-| &lt;INDEX: "index"&gt;
-| &lt;INGESTION: "ingestion"&gt;
-| &lt;INNER: "inner"&gt;
-| &lt;INSERT: "insert"&gt;
-| &lt;INTERNAL: "internal"&gt;
-| &lt;INTERSECT: "intersect"&gt;
-| &lt;IS: "is"&gt;
-| &lt;JOIN: "join"&gt;
-| &lt;KEYWORD: "keyword"&gt;
-| &lt;KEY: "key"&gt;
-| &lt;LEFT: "left"&gt;
-| &lt;LETTING: "letting"&gt;
-| &lt;LET: "let"&gt;
-| &lt;LIKE: "like"&gt;
-| &lt;LIMIT: "limit"&gt;
-| &lt;LOAD: "load"&gt;
-| &lt;NODEGROUP: "nodegroup"&gt;
-| &lt;NGRAM: "ngram"&gt;
-| &lt;NOT: "not"&gt;
-| &lt;OFFSET: "offset"&gt;
-| &lt;ON: "on"&gt;
-| &lt;OPEN: "open"&gt;
-| &lt;OR: "or"&gt;
-| &lt;ORDER: "order"&gt;
-| &lt;OUTER: "outer"&gt;
-| &lt;OUTPUT: "output"&gt;
-| &lt;PATH: "path"&gt;
-| &lt;POLICY: "policy"&gt;
-| &lt;PRESORTED: "pre-sorted"&gt;
-| &lt;PRIMARY: "primary"&gt;
-| &lt;RAW: "raw"&gt;
-| &lt;REFRESH: "refresh"&gt;
-| &lt;RETURN: "return"&gt;
-| &lt;RTREE: "rtree"&gt;
-| &lt;RUN: "run"&gt;
-| &lt;SATISFIES: "satisfies"&gt;
-| &lt;SECONDARY: "secondary"&gt;
-| &lt;SELECT: "select"&gt;
-| &lt;SET: "set"&gt;
-| &lt;SOME: "some"&gt;
-| &lt;TEMPORARY: "temporary"&gt;
-| &lt;THEN: "then"&gt;
-| &lt;TYPE: "type"&gt;
-| &lt;TO: "to"&gt;
-| &lt;UNION: "union"&gt;
-| &lt;UNKOWN: "unknown"&gt;
-| &lt;UNNEST: "unnest"&gt;
-| &lt;UPDATE: "update"&gt;
-| &lt;USE: "use"&gt;
-| &lt;USING: "using"&gt;
-| &lt;VALUE: "value"&gt;
-| &lt;WHEN: "when"&gt;
-| &lt;WHERE: "where"&gt;
-| &lt;WITH: "with"&gt;
-| &lt;WRITE: "write"&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;CARET: "^"&gt;
-| &lt;DIV: "/"&gt;
-| &lt;IDIV: "idiv"&gt;
-| &lt;MINUS: "-"&gt;
-| &lt;MOD: "%"&gt;
-| &lt;MUL: "*"&gt;
-| &lt;PLUS: "+"&gt;
-| &lt;LEFTPAREN: "("&gt;
-| &lt;RIGHTPAREN: ")"&gt;
-| &lt;LEFTBRACKET: "["&gt;
-| &lt;RIGHTBRACKET: "]"&gt;
-| &lt;ATT: "@"&gt;
-| &lt;COLON: ":"&gt;
-| &lt;COMMA: ","&gt;
-| &lt;DOT: "."&gt;
-| &lt;QUES: "?"&gt;
-| &lt;SEMICOLON: ";"&gt;
-| &lt;SHARP: "#"&gt;
-| &lt;LT: "&lt;"&gt;
-| &lt;GT: "&gt;"&gt;
-| &lt;LE: "&lt;="&gt;
-| &lt;GE: "&gt;="&gt;
-| &lt;EQ: "="&gt;
-| &lt;NE: "!="&gt;
-| &lt;SIMILAR: "~="&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;LEFTBRACE: "{"&gt; : DEFAULT
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT&gt; TOKEN : {
-&lt;RIGHTBRACE: "}"&gt; : {
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;LEFTDBLBRACE: "{{"&gt; : IN_DBL_BRACE
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;IN_DBL_BRACE&gt; TOKEN : {
-&lt;RIGHTDBLBRACE: "}}"&gt; : {
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;INTEGER_LITERAL: (&lt;DIGIT&gt;)+&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN [IGNORE_CASE] : {
-&lt;MISSING: "missing"&gt;
-| &lt;NULL: "null"&gt;
-| &lt;TRUE: "true"&gt;
-| &lt;FALSE: "false"&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;#DIGIT: ["0"-"9"]&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;DOUBLE_LITERAL: &lt;DIGITS&gt; | &lt;DIGITS&gt; ("." &lt;DIGITS&gt;)? | "." &lt;DIGITS&gt;&gt;
-| &lt;FLOAT_LITERAL: &lt;DIGITS&gt; ("f" | "F") | &lt;DIGITS&gt; ("." &lt;DIGITS&gt; ("f" | "F"))? | "." &lt;DIGITS&gt; ("f" | "F")&gt;
-| &lt;DIGITS: (&lt;DIGIT&gt;)+&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;#LETTER: ["A"-"Z","a"-"z"]&gt;
-| &lt;SPECIALCHARS: ["$","_"]&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;QUOTED_STRING: "`" (&lt;EscapeQuot&gt; | &lt;EscapeBslash&gt; | &lt;EscapeSlash&gt; | &lt;EscapeBspace&gt; | &lt;EscapeFormf&gt; | &lt;EscapeNl&gt; | &lt;EscapeCr&gt; | &lt;EscapeTab&gt; | ~["`","\\"])* "`"&gt;
-| &lt;STRING_LITERAL: "\"" (&lt;EscapeQuot&gt; | &lt;EscapeBslash&gt; | &lt;EscapeSlash&gt; | &lt;EscapeBspace&gt; | &lt;EscapeFormf&gt; | &lt;EscapeNl&gt; | &lt;EscapeCr&gt; | &lt;EscapeTab&gt; | ~["\"","\\"])* "\"" | "\'" (&lt;EscapeApos&gt; | &lt;EscapeBslash&gt; | &lt;EscapeSlash&gt; | &lt;EscapeBspace&gt; | &lt;EscapeFormf&gt; | &lt;EscapeNl&gt; | &lt;EscapeCr&gt; | &lt;EscapeTab&gt; | ~["\'","\\"])* "\'"&gt;
-| &lt;#EscapeQuot: "\\\""&gt;
-| &lt;#EscapeApos: "\\\'"&gt;
-| &lt;#EscapeBslash: "\\\\"&gt;
-| &lt;#EscapeSlash: "\\/"&gt;
-| &lt;#EscapeBspace: "\\b"&gt;
-| &lt;#EscapeFormf: "\\f"&gt;
-| &lt;#EscapeNl: "\\n"&gt;
-| &lt;#EscapeCr: "\\r"&gt;
-| &lt;#EscapeTab: "\\t"&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; TOKEN : {
-&lt;IDENTIFIER: &lt;LETTER&gt; (&lt;LETTER&gt; | &lt;DIGIT&gt; | &lt;SPECIALCHARS&gt;)*&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; SKIP : {
-" "
-| "\t"
-| "\r"
-| "\n"
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; SKIP : {
-&lt;"//" (~["\n"])* "\n"&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; SKIP : {
-&lt;"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")?&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;DEFAULT,IN_DBL_BRACE&gt; SKIP : {
-"/*" : INSIDE_COMMENT
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;INSIDE_COMMENT&gt; SPECIAL : {
-&lt;"+" (" ")* (~["*"])*&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;INSIDE_COMMENT&gt; SKIP : {
-"/*" : {
-}
-
-   </PRE>
-  </TD>
- </TR>
- <!-- Token -->
- <TR>
-  <TD>
-   <PRE>
-&lt;INSIDE_COMMENT&gt; SKIP : {
-"*/" : {
-| &lt;~[]&gt;
-}
-
-   </PRE>
-  </TD>
- </TR>
-</TABLE>
-<H2 ALIGN=CENTER>NON-TERMINALS</H2>
-<TABLE>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod1">Statement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod2">SingleStatement</A> ( &lt;SEMICOLON&gt; )* )* &lt;EOF&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod2">SingleStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod3">DataverseDeclaration</A> | <A HREF="#prod4">FunctionDeclaration</A> | <A HREF="#prod5">CreateStatement</A> | <A HREF="#prod6">LoadStatement</A> | <A HREF="#prod7">DropStatement</A> | <A HREF="#prod8">WriteStatement</A> | <A HREF="#prod9">SetStatement</A> | <A HREF="#prod10">InsertStatement</A> | <A HREF="#prod11">DeleteStatement</A> | <A HREF="#prod12">UpdateStatement</A> | <A HREF="#prod13">FeedStatement</A> | <A HREF="#prod14">CompactStatement</A> | <A HREF="#prod15">Query</A> &lt;SEMICOLON&gt; | <A HREF="#prod16">RefreshExternalDatasetStatement</A> | <A HREF="#prod17">RunStatement</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod3">DataverseDeclaration</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;USE&gt; <A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod5">CreateStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;CREATE&gt; ( <A HREF="#prod19">TypeSpecification</A> | <A HREF="#prod20">NodegroupSpecification</A> | <A HREF="#prod21">DatasetSpecification</A> | <A HREF="#prod22">IndexSpecification</A> | <A HREF="#prod23">DataverseSpecification</A> | <A HREF="#prod24">FunctionSpecification</A> | <A HREF="#prod25">FeedSpecification</A> | <A HREF="#prod26">FeedPolicySpecification</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod19">TypeSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;TYPE&gt; <A HREF="#prod27">TypeName</A> <A HREF="#prod28">IfNotExists</A> &lt;AS&gt; <A HREF="#prod29">TypeExpr</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod20">NodegroupSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;NODEGROUP&gt; <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> &lt;ON&gt; <A HREF="#prod18">Identifier</A> ( &lt;COMMA&gt; <A HREF="#prod18">Identifier</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod21">DatasetSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;EXTERNAL&gt; <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> &lt;LEFTPAREN&gt; <A HREF="#prod27">TypeName</A> &lt;RIGHTPAREN&gt; <A HREF="#prod28">IfNotExists</A> &lt;USING&gt; <A HREF="#prod32">AdapterName</A> <A HREF="#prod33">Configuration</A> ( &lt;ON&gt; <A HREF="#prod18">Identifier</A> )? ( &lt;HINTS&gt; <A HREF="#prod34">Properties</A> )? ( &lt;USING&gt; &lt;COMPACTION&gt; &lt;POLICY&gt; <A HREF="#prod35">CompactionPolicy</A> ( <A HREF="#prod33">Configuration</A> )? )? | ( &lt;INTERNAL&gt; | &lt;TEMPORARY&gt; )? <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> &lt;LEFTPAREN&gt; <A HREF="#prod27">TypeName</A> &lt;RIGHTPAREN&gt; ( &lt;WITH&gt; <A HREF="#prod18">Identifier</A> &lt;LEFTPAREN&gt; <A HREF="#prod27">TypeName</A> &lt;RIGHTPAREN&gt; )? <A HREF="#prod28">IfNotExists</A> <A HREF="#prod36">PrimaryKey</A> ( &lt;AUTOGENERATED&gt; )? ( &lt;ON&gt; <A HREF="#prod18">Identifier</A> )? ( &lt;HINTS&gt; <A HREF="#prod34">Properties</A> )? ( &lt;USING&gt; &lt;COMPACTION&gt; &lt;POLICY&gt; <A HREF="#prod35">CompactionPolicy</A> ( <A HREF="#prod33">Configuration</A> )? )? ( &lt;WITH&gt; &lt;FILTER&gt; &lt;ON&gt; <A HREF="#prod37">NestedField</A> )? )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod16">RefreshExternalDatasetStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;REFRESH&gt; &lt;EXTERNAL&gt; <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod17">RunStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;RUN&gt; <A HREF="#prod18">Identifier</A> &lt;LEFTPAREN&gt; ( <A HREF="#prod18">Identifier</A> ( &lt;COMMA&gt; )? )* &lt;RIGHTPAREN&gt; &lt;FROM&gt; <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> &lt;TO&gt; <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod22">IndexSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;INDEX&gt; <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> &lt;ON&gt; <A HREF="#prod31">QualifiedName</A> &lt;LEFTPAREN&gt; ( <A HREF="#prod38">OpenField</A> ) ( &lt;COMMA&gt; <A HREF="#prod38">OpenField</A> )* &lt;RIGHTPAREN&gt; ( &lt;TYPE&gt; <A HREF="#prod39">IndexType</A> )? ( &lt;ENFORCED&gt; )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod35">CompactionPolicy</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod40">FilterField</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod39">IndexType</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;BTREE&gt; | &lt;RTREE&gt; | &lt;KEYWORD&gt; | &lt;NGRAM&gt; &lt;LEFTPAREN&gt; &lt;INTEGER_LITERAL&gt; &lt;RIGHTPAREN&gt; )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod23">DataverseSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DATAVERSE&gt; <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> ( &lt;WITH&gt; &lt;FORMAT&gt; <A HREF="#prod41">ConstantString</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod24">FunctionSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;FUNCTION&gt; <A HREF="#prod42">FunctionName</A> <A HREF="#prod28">IfNotExists</A> <A HREF="#prod43">ParameterList</A> &lt;LEFTBRACE&gt; <A HREF="#prod44">Expression</A> &lt;RIGHTBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod25">FeedSpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;SECONDARY&gt; &lt;FEED&gt; <A HREF="#prod31">QualifiedName</A> <A HREF="#prod28">IfNotExists</A> &lt;FROM&gt; &lt;FEED&gt; <A HREF="#prod31">QualifiedName</A> ( <A HREF="#prod45">ApplyFunction</A> )? | ( &lt;PRIMARY&gt; )? &lt;FEED&gt; <A HREF="#prod31">QualifiedName</A> <A HREF="#prod28">IfNotExists</A> &lt;USING&gt; <A HREF="#prod32">AdapterName</A> <A HREF="#prod33">Configuration</A> ( <A HREF="#prod45">ApplyFunction</A> )? )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod26">FeedPolicySpecification</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;INGESTION&gt; &lt;POLICY&gt; <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> &lt;FROM&gt; ( &lt;POLICY&gt; <A HREF="#prod18">Identifier</A> <A HREF="#prod33">Configuration</A> ( &lt;DEFINITION&gt; <A HREF="#prod41">ConstantString</A> )? | &lt;PATH&gt; <A HREF="#prod18">Identifier</A> ( &lt;DEFINITION&gt; <A HREF="#prod41">ConstantString</A> )? ) )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod43">ParameterList</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTPAREN&gt; ( &lt;IDENTIFIER&gt; ( &lt;COMMA&gt; &lt;IDENTIFIER&gt; )* )? &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod28">IfNotExists</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;IF&gt; &lt;NOT&gt; &lt;EXISTS&gt; )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod45">ApplyFunction</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;APPLY&gt; &lt;FUNCTION&gt; <A HREF="#prod42">FunctionName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod46">GetPolicy</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;USING&gt; &lt;POLICY&gt; <A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod47">FunctionSignature</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod42">FunctionName</A> &lt;ATT&gt; &lt;INTEGER_LITERAL&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod36">PrimaryKey</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;PRIMARY&gt; &lt;KEY&gt; <A HREF="#prod37">NestedField</A> ( &lt;COMMA&gt; <A HREF="#prod37">NestedField</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod7">DropStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DROP&gt; ( <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> <A HREF="#prod48">IfExists</A> | &lt;INDEX&gt; <A HREF="#prod49">DoubleQualifiedName</A> <A HREF="#prod48">IfExists</A> | &lt;NODEGROUP&gt; <A HREF="#prod18">Identifier</A> <A HREF="#prod48">IfExists</A> | &lt;TYPE&gt; <A HREF="#prod27">TypeName</A> <A HREF="#prod48">IfExists</A> | &lt;DATAVERSE&gt; <A HREF="#prod18">Identifier</A> <A HREF="#prod48">IfExists</A> | &lt;FUNCTION&gt; <A HREF="#prod47">FunctionSignature</A> <A HREF="#prod48">IfExists</A> | &lt;FEED&gt; <A HREF="#prod31">QualifiedName</A> <A HREF="#prod48">IfExists</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod48">IfExists</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;IF&gt; &lt;EXISTS&gt; )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod10">InsertStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;INSERT&gt; &lt;INTO&gt; <A HREF="#prod31">QualifiedName</A> <A HREF="#prod15">Query</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod11">DeleteStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DELETE&gt; &lt;FROM&gt; <A HREF="#prod31">QualifiedName</A> ( ( &lt;AS&gt; )? <A HREF="#prod50">Variable</A> )? ( &lt;WHERE&gt; <A HREF="#prod44">Expression</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod12">UpdateStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;UPDATE&gt; <A HREF="#prod50">Variable</A> &lt;IN&gt; <A HREF="#prod44">Expression</A> &lt;WHERE&gt; <A HREF="#prod44">Expression</A> &lt;LEFTPAREN&gt; ( <A HREF="#prod51">UpdateClause</A> ( &lt;COMMA&gt; <A HREF="#prod51">UpdateClause</A> )* ) &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod51">UpdateClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;SET&gt; <A HREF="#prod44">Expression</A> &lt;EQ&gt; <A HREF="#prod44">Expression</A> | <A HREF="#prod10">InsertStatement</A> | <A HREF="#prod11">DeleteStatement</A> | <A HREF="#prod12">UpdateStatement</A> | &lt;IF&gt; &lt;LEFTPAREN&gt; <A HREF="#prod44">Expression</A> &lt;RIGHTPAREN&gt; &lt;THEN&gt; <A HREF="#prod51">UpdateClause</A> ( &lt;ELSE&gt; <A HREF="#prod51">UpdateClause</A> )? )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod9">SetStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;SET&gt; <A HREF="#prod18">Identifier</A> <A HREF="#prod41">ConstantString</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod8">WriteStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;WRITE&gt; &lt;OUTPUT&gt; &lt;TO&gt; <A HREF="#prod18">Identifier</A> &lt;COLON&gt; <A HREF="#prod41">ConstantString</A> ( &lt;USING&gt; <A HREF="#prod41">ConstantString</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod6">LoadStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LOAD&gt; <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> &lt;USING&gt; <A HREF="#prod32">AdapterName</A> <A HREF="#prod33">Configuration</A> ( &lt;PRESORTED&gt; )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod32">AdapterName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod14">CompactStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;COMPACT&gt; <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod13">FeedStatement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;CONNECT&gt; &lt;FEED&gt; <A HREF="#prod31">QualifiedName</A> &lt;TO&gt; <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> ( <A HREF="#prod46">GetPolicy</A> )? | &lt;DISCONNECT&gt; &lt;FEED&gt; <A HREF="#prod31">QualifiedName</A> &lt;FROM&gt; <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod33">Configuration</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTPAREN&gt; ( <A HREF="#prod52">KeyValuePair</A> ( &lt;COMMA&gt; <A HREF="#prod52">KeyValuePair</A> )* )? &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod52">KeyValuePair</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTPAREN&gt; <A HREF="#prod41">ConstantString</A> &lt;EQ&gt; <A HREF="#prod41">ConstantString</A> &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod34">Properties</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;LEFTPAREN&gt; <A HREF="#prod53">Property</A> ( &lt;COMMA&gt; <A HREF="#prod53">Property</A> )* &lt;RIGHTPAREN&gt; )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod53">Property</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod18">Identifier</A> | <A HREF="#prod54">StringLiteral</A> ) &lt;EQ&gt; ( <A HREF="#prod41">ConstantString</A> | &lt;INTEGER_LITERAL&gt; )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod55">IndexedTypeExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod56">TypeReference</A> | <A HREF="#prod57">OrderedListTypeDef</A> | <A HREF="#prod58">UnorderedListTypeDef</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod29">TypeExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod59">RecordTypeDef</A> | <A HREF="#prod56">TypeReference</A> | <A HREF="#prod57">OrderedListTypeDef</A> | <A HREF="#prod58">UnorderedListTypeDef</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod59">RecordTypeDef</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;CLOSED&gt; | &lt;OPEN&gt; )? &lt;LEFTBRACE&gt; ( <A HREF="#prod60">RecordField</A> ( &lt;COMMA&gt; <A HREF="#prod60">RecordField</A> )* )? &lt;RIGHTBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod60">RecordField</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> &lt;COLON&gt; <A HREF="#prod29">TypeExpr</A> ( &lt;QUES&gt; )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod56">TypeReference</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod57">OrderedListTypeDef</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTBRACKET&gt; ( <A HREF="#prod29">TypeExpr</A> ) &lt;RIGHTBRACKET&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod58">UnorderedListTypeDef</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTDBLBRACE&gt; ( <A HREF="#prod29">TypeExpr</A> ) &lt;RIGHTDBLBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod42">FunctionName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> ( &lt;SHARP&gt; <A HREF="#prod18">Identifier</A> )? | &lt;SHARP&gt; <A HREF="#prod18">Identifier</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod27">TypeName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod31">QualifiedName</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod18">Identifier</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;IDENTIFIER&gt; | <A HREF="#prod61">QuotedString</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod30">Dataset</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;DATASET&gt; | &lt;COLLECTION&gt; )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod38">OpenField</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod37">NestedField</A> ( &lt;COLON&gt; <A HREF="#prod55">IndexedTypeExpr</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod37">NestedField</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> ( &lt;LEFTPAREN&gt; &lt;RIGHTPAREN&gt; )? ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod41">ConstantString</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod61">QuotedString</A> | <A HREF="#prod54">StringLiteral</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod61">QuotedString</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;QUOTED_STRING&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod54">StringLiteral</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;STRING_LITERAL&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod31">QualifiedName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod49">DoubleQualifiedName</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod18">Identifier</A> &lt;DOT&gt; <A HREF="#prod18">Identifier</A> ( &lt;DOT&gt; <A HREF="#prod18">Identifier</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod4">FunctionDeclaration</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DECLARE&gt; &lt;FUNCTION&gt; <A HREF="#prod18">Identifier</A> <A HREF="#prod43">ParameterList</A> &lt;LEFTBRACE&gt; <A HREF="#prod44">Expression</A> &lt;RIGHTBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod15">Query</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod44">Expression</A> | <A HREF="#prod62">SelectExpression</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod44">Expression</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod63">OperatorExpr</A> | <A HREF="#prod64">CaseExpr</A> | <A HREF="#prod65">QuantifiedExpression</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod63">OperatorExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod66">AndExpr</A> ( &lt;OR&gt; <A HREF="#prod66">AndExpr</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod66">AndExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod67">NotExpr</A> ( &lt;AND&gt; <A HREF="#prod67">NotExpr</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod67">NotExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;NOT&gt; )? <A HREF="#prod68">RelExpr</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod68">RelExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod69">IsExpr</A> ( ( &lt;LT&gt; | &lt;GT&gt; | &lt;LE&gt; | &lt;GE&gt; | &lt;EQ&gt; | &lt;NE&gt; | &lt;SIMILAR&gt; | ( &lt;NOT&gt; )? ( &lt;LIKE&gt; | &lt;IN&gt; ) ) <A HREF="#prod69">IsExpr</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod69">IsExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod70">AddExpr</A> ( &lt;IS&gt; ( &lt;NOT&gt; )? ( &lt;NULL&gt; | &lt;MISSING&gt; | &lt;UNKOWN&gt; ) )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod70">AddExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod71">MultExpr</A> ( ( &lt;PLUS&gt; | &lt;MINUS&gt; ) <A HREF="#prod71">MultExpr</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod71">MultExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod72">UnaryExpr</A> ( ( &lt;MUL&gt; | &lt;DIV&gt; | &lt;MOD&gt; | &lt;CARET&gt; | &lt;IDIV&gt; ) <A HREF="#prod72">UnaryExpr</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod72">UnaryExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( ( &lt;PLUS&gt; | &lt;MINUS&gt; | ( &lt;NOT&gt; )? &lt;EXISTS&gt; ) )? <A HREF="#prod73">ValueExpr</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod73">ValueExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod74">PrimaryExpr</A> ( <A HREF="#prod75">Field</A> | <A HREF="#prod76">Index</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod75">Field</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DOT&gt; <A HREF="#prod18">Identifier</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod76">Index</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTBRACKET&gt; ( <A HREF="#prod44">Expression</A> | &lt;QUES&gt; ) &lt;RIGHTBRACKET&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod74">PrimaryExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod77">FunctionCallExpr</A> | <A HREF="#prod78">Literal</A> | <A HREF="#prod79">VariableRef</A> | <A HREF="#prod80">ListConstructor</A> | <A HREF="#prod81">RecordConstructor</A> | <A HREF="#prod82">ParenthesizedExpression</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod78">Literal</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod54">StringLiteral</A> | &lt;INTEGER_LITERAL&gt; | &lt;FLOAT_LITERAL&gt; | &lt;DOUBLE_LITERAL&gt; | &lt;MISSING&gt; | &lt;NULL&gt; | &lt;TRUE&gt; | &lt;FALSE&gt; )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod79">VariableRef</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;IDENTIFIER&gt; | <A HREF="#prod61">QuotedString</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod50">Variable</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;IDENTIFIER&gt; | <A HREF="#prod61">QuotedString</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod80">ListConstructor</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod83">OrderedListConstructor</A> | <A HREF="#prod84">UnorderedListConstructor</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod83">OrderedListConstructor</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTBRACKET&gt; <A HREF="#prod85">ExpressionList</A> &lt;RIGHTBRACKET&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod84">UnorderedListConstructor</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTDBLBRACE&gt; <A HREF="#prod85">ExpressionList</A> &lt;RIGHTDBLBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod85">ExpressionList</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod44">Expression</A> ( &lt;COMMA&gt; <A HREF="#prod85">ExpressionList</A> )? )? ( <A HREF="#prod86">Comma</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod86">Comma</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;COMMA&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod81">RecordConstructor</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTBRACE&gt; ( <A HREF="#prod87">FieldBinding</A> ( &lt;COMMA&gt; <A HREF="#prod87">FieldBinding</A> )* )? &lt;RIGHTBRACE&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod87">FieldBinding</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod44">Expression</A> &lt;COLON&gt; <A HREF="#prod44">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod77">FunctionCallExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod42">FunctionName</A> &lt;LEFTPAREN&gt; ( <A HREF="#prod44">Expression</A> ( &lt;COMMA&gt; <A HREF="#prod44">Expression</A> )* )? &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod82">ParenthesizedExpression</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;LEFTPAREN&gt; <A HREF="#prod44">Expression</A> &lt;RIGHTPAREN&gt; | <A HREF="#prod88">Subquery</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod64">CaseExpr</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;CASE&gt; ( <A HREF="#prod44">Expression</A> )? ( &lt;WHEN&gt; <A HREF="#prod44">Expression</A> &lt;THEN&gt; <A HREF="#prod44">Expression</A> )* ( &lt;ELSE&gt; <A HREF="#prod44">Expression</A> )? &lt;END&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod62">SelectExpression</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod89">LetClause</A> )? <A HREF="#prod90">SelectSetOperation</A> ( <A HREF="#prod91">OrderbyClause</A> )? ( <A HREF="#prod92">LimitClause</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod90">SelectSetOperation</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod93">SelectBlock</A> ( ( &lt;UNION&gt; | &lt;INTERSECT&gt; | &lt;EXCEPT&gt; ) ( &lt;ALL&gt; )? ( <A HREF="#prod93">SelectBlock</A> | <A HREF="#prod88">Subquery</A> ) )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod88">Subquery</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTPAREN&gt; <A HREF="#prod62">SelectExpression</A> &lt;RIGHTPAREN&gt;</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod93">SelectBlock</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod94">SelectClause</A> ( <A HREF="#prod95">FromClause</A> ( <A HREF="#prod89">LetClause</A> )? )? ( <A HREF="#prod96">WhereClause</A> )? ( <A HREF="#prod97">GroupbyClause</A> ( <A HREF="#prod89">LetClause</A> )? ( <A HREF="#prod98">HavingClause</A> )? )? | <A HREF="#prod95">FromClause</A> ( <A HREF="#prod89">LetClause</A> )? ( <A HREF="#prod96">WhereClause</A> )? ( <A HREF="#prod97">GroupbyClause</A> ( <A HREF="#prod89">LetClause</A> )? ( <A HREF="#prod98">HavingClause</A> )? )? <A HREF="#prod94">SelectClause</A> )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod94">SelectClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;SELECT&gt; ( &lt;ALL&gt; | &lt;DISTINCT&gt; )? ( <A HREF="#prod99">SelectRegular</A> | <A HREF="#prod100">SelectElement</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod99">SelectRegular</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod101">Projection</A> ( &lt;COMMA&gt; <A HREF="#prod101">Projection</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod100">SelectElement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;RAW&gt; | &lt;ELEMENT&gt; | &lt;VALUE&gt; ) <A HREF="#prod44">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod101">Projection</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod44">Expression</A> ( ( &lt;AS&gt; )? <A HREF="#prod18">Identifier</A> )? | <A HREF="#prod44">Expression</A> &lt;DOT&gt; &lt;MUL&gt; | &lt;MUL&gt; )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod95">FromClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;FROM&gt; <A HREF="#prod102">FromTerm</A> ( &lt;COMMA&gt; <A HREF="#prod102">FromTerm</A> )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod102">FromTerm</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod44">Expression</A> ( ( &lt;AS&gt; )? <A HREF="#prod50">Variable</A> )? ( &lt;AT&gt; <A HREF="#prod50">Variable</A> )? ( ( <A HREF="#prod103">JoinType</A> )? ( <A HREF="#prod104">JoinClause</A> | <A HREF="#prod105">UnnestClause</A> ) )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod104">JoinClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;JOIN&gt; <A HREF="#prod44">Expression</A> ( ( &lt;AS&gt; )? <A HREF="#prod50">Variable</A> )? ( &lt;AT&gt; <A HREF="#prod50">Variable</A> )? &lt;ON&gt; <A HREF="#prod44">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod105">UnnestClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;UNNEST&gt; | &lt;CORRELATE&gt; | &lt;FLATTEN&gt; ) <A HREF="#prod44">Expression</A> ( ( &lt;AS&gt; )? <A HREF="#prod50">Variable</A> ) ( &lt;AT&gt; <A HREF="#prod50">Variable</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod103">JoinType</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;INNER&gt; | &lt;LEFT&gt; ( &lt;OUTER&gt; )? )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod89">LetClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( ( &lt;LET&gt; | &lt;LETTING&gt; ) <A HREF="#prod106">LetElement</A> ( &lt;COMMA&gt; <A HREF="#prod106">LetElement</A> )* | &lt;WITH&gt; <A HREF="#prod107">WithElement</A> ( &lt;COMMA&gt; <A HREF="#prod107">WithElement</A> )* )</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod96">WhereClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;WHERE&gt; <A HREF="#prod44">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod91">OrderbyClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;ORDER&gt; &lt;BY&gt; <A HREF="#prod44">Expression</A> ( ( &lt;ASC&gt; ) | ( &lt;DESC&gt; ) )? ( &lt;COMMA&gt; <A HREF="#prod44">Expression</A> ( ( &lt;ASC&gt; ) | ( &lt;DESC&gt; ) )? )*</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod97">GroupbyClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;GROUP&gt; &lt;BY&gt; ( <A HREF="#prod44">Expression</A> ( ( &lt;AS&gt; )? <A HREF="#prod50">Variable</A> )? ( &lt;COMMA&gt; <A HREF="#prod44">Expression</A> ( ( &lt;AS&gt; )? <A HREF="#prod50">Variable</A> )? )* ) ( &lt;GROUP&gt; &lt;AS&gt; <A HREF="#prod50">Variable</A> ( &lt;LEFTPAREN&gt; <A HREF="#prod79">VariableRef</A> &lt;AS&gt; <A HREF="#prod18">Identifier</A> ( &lt;COMMA&gt; <A HREF="#prod79">VariableRef</A> &lt;AS&gt; <A HREF="#prod18">Identifier</A> )* &lt;RIGHTPAREN&gt; )? )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod98">HavingClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;HAVING&gt; <A HREF="#prod44">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod92">LimitClause</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LIMIT&gt; <A HREF="#prod44">Expression</A> ( &lt;OFFSET&gt; <A HREF="#prod44">Expression</A> )?</TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod65">QuantifiedExpression</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( ( &lt;SOME&gt; ) | ( &lt;EVERY&gt; ) ) <A HREF="#prod50">Variable</A> &lt;IN&gt; <A HREF="#prod44">Expression</A> ( &lt;COMMA&gt; <A HREF="#prod50">Variable</A> &lt;IN&gt; <A HREF="#prod44">Expression</A> )* &lt;SATISFIES&gt; <A HREF="#prod44">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod106">LetElement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod50">Variable</A> &lt;EQ&gt; <A HREF="#prod44">Expression</A></TD>
-</TR>
-<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod107">WithElement</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod50">Variable</A> &lt;AS&gt; <A HREF="#prod44">Expression</A></TD>
-</TR>
-</TABLE>
-</BODY>
-</HTML>
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 2378060..15104bd 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -1816,7 +1816,7 @@
     boolean not = false;
 }
 {
-    operand = AddExpr()
+    operand = ConcatExpr()
     ( <IS> (<NOT> { not = true; })? (<NULL> | <MISSING> | <UNKOWN>)
       {
         String functionName = "is-" + token.image.toLowerCase();
@@ -1833,6 +1833,38 @@
     }
 }
 
+Expression ConcatExpr()throws ParseException:
+{
+  OperatorExpr op = null;
+  Expression operand = null;
+}
+{
+    operand = AddExpr()
+    (
+      LOOKAHEAD(1)
+      (<CONCAT>)
+      {
+        if (op == null) {
+          op = new OperatorExpr();
+          op.addOperand(operand);
+          op.setCurrentop(true);
+        }
+        try{
+            ((OperatorExpr)op).addOperator(token.image);
+        } catch (Exception e){
+            throw new ParseException(e.getMessage());
+        }
+    }
+    operand = AddExpr()
+    {
+      op.addOperand(operand);
+    }
+    )*
+
+    {
+       return op==null? operand: op;
+    }
+}
 
 Expression AddExpr()throws ParseException:
 {
@@ -1842,7 +1874,7 @@
 {
     operand = MultExpr()
     (
-       LOOKAHEAD(1)
+      LOOKAHEAD(1)
       (<PLUS> | <MINUS>)
       {
         if (op == null) {
@@ -2302,7 +2334,7 @@
    List<Expression> whenExprs = new ArrayList<Expression>();
    List<Expression> thenExprs = new ArrayList<Expression>();
    Expression elseExpr = null;
-   
+
    Expression whenExpr = null;
    Expression thenExpr = null;
 }
@@ -3005,6 +3037,7 @@
 TOKEN :
 {
     <CARET : "^">
+  | <CONCAT : "||">
   | <DIV : "/">
   | <IDIV : "idiv">
   | <MINUS : "-">
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
index d17be1a..dc2412c 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -89,6 +89,7 @@
 import org.apache.asterix.om.typecomputer.impl.RecordRemoveFieldsTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.ScalarVersionOfAggregateResultType;
 import org.apache.asterix.om.typecomputer.impl.StringBooleanTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.StringInt32TypeComputer;
 import org.apache.asterix.om.typecomputer.impl.StringStringTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.SubsetCollectionTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.Substring2TypeComputer;
@@ -251,10 +252,34 @@
             "matches", 2);
     public static final FunctionIdentifier STRING_MATCHES_WITH_FLAG = new FunctionIdentifier(
             FunctionConstants.ASTERIX_NS, "matches", 3);
+    public static final FunctionIdentifier STRING_REGEXP_LIKE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "regexp-like", 2);
+    public static final FunctionIdentifier STRING_REGEXP_LIKE_WITH_FLAG = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "regexp-like", 3);
+    public static final FunctionIdentifier STRING_REGEXP_POSITION = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "regexp-position", 2);
+    public static final FunctionIdentifier STRING_REGEXP_POSITION_WITH_FLAG = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "regexp-position", 3);
     public static final FunctionIdentifier STRING_LOWERCASE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "lowercase", 1);
     public static final FunctionIdentifier STRING_UPPERCASE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "uppercase", 1);
+    public static final FunctionIdentifier STRING_INITCAP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "initcap", 1);
+    public static final FunctionIdentifier STRING_TRIM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "trim",
+            1);
+    public static final FunctionIdentifier STRING_LTRIM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "ltrim",
+            1);
+    public static final FunctionIdentifier STRING_RTRIM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "rtrim",
+            1);
+    public static final FunctionIdentifier STRING_TRIM2 = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "trim",
+            2);
+    public static final FunctionIdentifier STRING_LTRIM2 = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "ltrim", 2);
+    public static final FunctionIdentifier STRING_RTRIM2 = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "rtrim", 2);
+    public static final FunctionIdentifier STRING_POSITION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "position", 2);
     public static final FunctionIdentifier STRING_REPLACE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "replace", 3);
     public static final FunctionIdentifier STRING_REPLACE_WITH_FLAG = new FunctionIdentifier(
@@ -603,8 +628,6 @@
             "spatial-cell", 4);
     public static final FunctionIdentifier SWITCH_CASE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "switch-case", FunctionIdentifier.VARARGS);
-    public static final FunctionIdentifier REG_EXP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "reg-exp", 2);
-
     public static final FunctionIdentifier INJECT_FAILURE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "inject-failure", 2);
     public static final FunctionIdentifier FLOW_RECORD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -868,10 +891,22 @@
         addFunction(STRING_LENGTH, UnaryStringInt64TypeComputer.INSTANCE, true);
         addFunction(STRING_LOWERCASE, StringStringTypeComputer.INSTANCE, true);
         addFunction(STRING_UPPERCASE, StringStringTypeComputer.INSTANCE, true);
+        addFunction(STRING_INITCAP, StringStringTypeComputer.INSTANCE, true);
+        addFunction(STRING_TRIM, StringStringTypeComputer.INSTANCE, true);
+        addFunction(STRING_LTRIM, StringStringTypeComputer.INSTANCE, true);
+        addFunction(STRING_RTRIM, StringStringTypeComputer.INSTANCE, true);
+        addFunction(STRING_TRIM2, StringStringTypeComputer.INSTANCE, true);
+        addFunction(STRING_LTRIM2, StringStringTypeComputer.INSTANCE, true);
+        addFunction(STRING_RTRIM2, StringStringTypeComputer.INSTANCE, true);
+        addFunction(STRING_POSITION, StringInt32TypeComputer.INSTANCE, true);
         addFunction(STRING_STARTS_WITH, StringBooleanTypeComputer.INSTANCE, true);
         addFunction(STRING_ENDS_WITH, StringBooleanTypeComputer.INSTANCE, true);
         addFunction(STRING_MATCHES, StringBooleanTypeComputer.INSTANCE, true);
         addFunction(STRING_MATCHES_WITH_FLAG, StringBooleanTypeComputer.INSTANCE, true);
+        addFunction(STRING_REGEXP_LIKE, StringBooleanTypeComputer.INSTANCE, true);
+        addFunction(STRING_REGEXP_LIKE_WITH_FLAG, StringBooleanTypeComputer.INSTANCE, true);
+        addFunction(STRING_REGEXP_POSITION, StringInt32TypeComputer.INSTANCE, true);
+        addFunction(STRING_REGEXP_POSITION_WITH_FLAG, StringInt32TypeComputer.INSTANCE, true);
         addFunction(STRING_REPLACE, StringStringTypeComputer.INSTANCE, true);
         addFunction(STRING_REPLACE_WITH_FLAG, StringStringTypeComputer.INSTANCE, true);
         addFunction(SUBSTRING_BEFORE, StringStringTypeComputer.INSTANCE, true);
@@ -975,7 +1010,6 @@
         addPrivateFunction(SUBSET_COLLECTION, SubsetCollectionTypeComputer.INSTANCE, true);
         addFunction(SUBSTRING, SubstringTypeComputer.INSTANCE, true);
         addFunction(SWITCH_CASE, SwitchCaseComputer.INSTANCE, true);
-        addPrivateFunction(REG_EXP, ABooleanTypeComputer.INSTANCE, true);
         addPrivateFunction(INJECT_FAILURE, InjectFailureTypeComputer.INSTANCE, true);
         addPrivateFunction(CAST_TYPE, CastTypeComputer.INSTANCE, true);
 
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
new file mode 100644
index 0000000..22b3246
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.om.typecomputer.impl;
+
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+
+public class StringInt32TypeComputer extends AbstractStringTypeComputer {
+    public static final StringInt32TypeComputer INSTANCE = new StringInt32TypeComputer();
+
+    private StringInt32TypeComputer() {
+    }
+
+    @Override
+    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
+        return BuiltinType.AINT32;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringBoolEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringBoolEval.java
index fd89493..99ba91a 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringBoolEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringBoolEval.java
@@ -18,84 +18,49 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
-import java.io.DataOutput;
+import java.io.IOException;
 
 import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import org.apache.asterix.om.base.ABoolean;
-import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.EnumDeserializer;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
-import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
-public abstract class AbstractBinaryStringBoolEval implements IScalarEvaluator {
+public abstract class AbstractBinaryStringBoolEval extends AbstractBinaryStringEval {
 
-    private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-    private DataOutput dout = resultStorage.getDataOutput();
-
-    private IPointable ptr0 = new VoidPointable();
-    private IPointable ptr1 = new VoidPointable();
-    private IScalarEvaluator evalLeft;
-    private IScalarEvaluator evalRight;
-    private final FunctionIdentifier funcID;
-
-    private final UTF8StringPointable leftPtr = new UTF8StringPointable();
-    private final UTF8StringPointable rightPtr = new UTF8StringPointable();
-
+    // For outputting results.
     @SuppressWarnings({ "rawtypes" })
     private ISerializerDeserializer boolSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ABOOLEAN);
 
     public AbstractBinaryStringBoolEval(IHyracksTaskContext context, IScalarEvaluatorFactory evalLeftFactory,
             IScalarEvaluatorFactory evalRightFactory, FunctionIdentifier funcID) throws AlgebricksException {
-        this.evalLeft = evalLeftFactory.createScalarEvaluator(context);
-        this.evalRight = evalRightFactory.createScalarEvaluator(context);
-        this.funcID = funcID;
+        super(context, evalLeftFactory, evalRightFactory, funcID);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
-        evalLeft.evaluate(tuple, ptr0);
-        evalRight.evaluate(tuple, ptr1);
-
-        byte[] bytes0 = ptr0.getByteArray();
-        int offset0 = ptr0.getStartOffset();
-        int len0 = ptr0.getLength();
-        byte[] bytes1 = ptr1.getByteArray();
-        int offset1 = ptr1.getStartOffset();
-        int len1 = ptr1.getLength();
-
-        resultStorage.reset();
-        if (bytes0[offset0] != ATypeTag.SERIALIZED_STRING_TYPE_TAG
-                || bytes1[offset1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-            throw new AlgebricksException(funcID.getName() + ": expects input type STRING or NULL, but got "
-                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes0[offset0]) + " and "
-                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes1[offset1]) + ")!");
-        }
-
-        leftPtr.set(bytes0, offset0 + 1, len0 - 1);
-        rightPtr.set(bytes1, offset1 + 1, len1 - 1);
-
+    public void process(UTF8StringPointable leftPtr, UTF8StringPointable rightPtr, IPointable result)
+            throws IOException {
         ABoolean res = compute(leftPtr, rightPtr) ? ABoolean.TRUE : ABoolean.FALSE;
-        try {
-            boolSerde.serialize(res, dout);
-        } catch (HyracksDataException e) {
-            throw new AlgebricksException(e);
-        }
+        boolSerde.serialize(res, dataOutput);
         result.set(resultStorage);
     }
 
-    protected abstract boolean compute(UTF8StringPointable left, UTF8StringPointable right) throws AlgebricksException;
+    /**
+     * Computes a boolean value from two input strings.
+     *
+     * @param left
+     *            , the first input argument.
+     * @param right
+     *            , the second input argument.
+     * @return a boolean value.
+     * @throws IOException
+     */
+    protected abstract boolean compute(UTF8StringPointable left, UTF8StringPointable right) throws IOException;
 
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringEval.java
new file mode 100644
index 0000000..ab66ac6
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringEval.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public abstract class AbstractBinaryStringEval implements IScalarEvaluator {
+
+    // Argument evaluators.
+    private IScalarEvaluator evalLeft;
+    private IScalarEvaluator evalRight;
+
+    // Argument pointables.
+    private IPointable argPtrLeft = new VoidPointable();
+    private IPointable argPtrSecond = new VoidPointable();
+    private final UTF8StringPointable leftPtr = new UTF8StringPointable();
+    private final UTF8StringPointable rightPtr = new UTF8StringPointable();
+
+    // For results.
+    protected ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+    protected DataOutput dataOutput = resultStorage.getDataOutput();
+
+    // Function ID, for error reporting.
+    private final FunctionIdentifier funcID;
+
+    public AbstractBinaryStringEval(IHyracksTaskContext context, IScalarEvaluatorFactory evalLeftFactory,
+            IScalarEvaluatorFactory evalRightFactory, FunctionIdentifier funcID) throws AlgebricksException {
+        this.evalLeft = evalLeftFactory.createScalarEvaluator(context);
+        this.evalRight = evalRightFactory.createScalarEvaluator(context);
+        this.funcID = funcID;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void evaluate(IFrameTupleReference tuple, IPointable resultPointable) throws AlgebricksException {
+        resultStorage.reset();
+
+        // Gets the first argument.
+        evalLeft.evaluate(tuple, argPtrLeft);
+        byte[] bytes0 = argPtrLeft.getByteArray();
+        int offset0 = argPtrLeft.getStartOffset();
+        int len0 = argPtrLeft.getLength();
+
+        // Gets the second argument.
+        evalRight.evaluate(tuple, argPtrSecond);
+        byte[] bytes1 = argPtrSecond.getByteArray();
+        int offset1 = argPtrSecond.getStartOffset();
+        int len1 = argPtrSecond.getLength();
+
+        // Type check.
+        if (bytes0[offset0] != ATypeTag.SERIALIZED_STRING_TYPE_TAG
+                || bytes1[offset1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+            throw new AlgebricksException(funcID.getName() + ": expects input type STRING, but got "
+                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes0[offset0]) + " and "
+                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes1[offset1]) + ")!");
+        }
+
+        // Sets StringUTF8Pointables.
+        leftPtr.set(bytes0, offset0 + 1, len0 - 1);
+        rightPtr.set(bytes1, offset1 + 1, len1 - 1);
+
+        // The actual processing.
+        try {
+            process(leftPtr, rightPtr, resultPointable);
+        } catch (IOException e) {
+            throw new AlgebricksException(e);
+        }
+    }
+
+    /**
+     * The actual processing of a string function.
+     *
+     * @param left
+     *            , the first argument.
+     * @param right
+     *            , the second argument.
+     * @param resultPointable
+     *            , the result.
+     * @throws IOException
+     */
+    protected abstract void process(UTF8StringPointable left, UTF8StringPointable right, IPointable resultPointable)
+            throws IOException;
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringIntEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringIntEval.java
new file mode 100644
index 0000000..cd7f6c4
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringIntEval.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public abstract class AbstractBinaryStringIntEval extends AbstractBinaryStringEval {
+
+    // For outputting results.
+    @SuppressWarnings({ "rawtypes" })
+    private ISerializerDeserializer intSerde = AqlSerializerDeserializerProvider.INSTANCE
+            .getSerializerDeserializer(BuiltinType.AINT32);
+    private AMutableInt32 resultValue = new AMutableInt32(0);
+
+    public AbstractBinaryStringIntEval(IHyracksTaskContext context, IScalarEvaluatorFactory evalLeftFactory,
+            IScalarEvaluatorFactory evalRightFactory, FunctionIdentifier funcID) throws AlgebricksException {
+        super(context, evalLeftFactory, evalRightFactory, funcID);
+    }
+
+    @Override
+    public void process(UTF8StringPointable leftPtr, UTF8StringPointable rightPtr, IPointable result)
+            throws IOException {
+        resultValue.setValue(compute(leftPtr, rightPtr));
+        intSerde.serialize(resultValue, dataOutput);
+        result.set(resultStorage);
+    }
+
+    /**
+     * Computes an integer value from two input strings.
+     *
+     * @param left
+     *            , the first input argument.
+     * @param right
+     *            , the second input argument.
+     * @return an integer value.
+     * @throws IOException
+     */
+    protected abstract int compute(UTF8StringPointable left, UTF8StringPointable right) throws IOException;
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringStringEval.java
new file mode 100644
index 0000000..a944de3
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringStringEval.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+import org.apache.hyracks.data.std.util.GrowableArray;
+import org.apache.hyracks.data.std.util.UTF8StringBuilder;
+
+public abstract class AbstractBinaryStringStringEval extends AbstractBinaryStringEval {
+
+    // For outputting results.
+    protected final UTF8StringPointable resultStrPtr = new UTF8StringPointable();
+    protected final GrowableArray resultArray = new GrowableArray();
+    protected final UTF8StringBuilder resultBuilder = new UTF8StringBuilder();
+
+    public AbstractBinaryStringStringEval(IHyracksTaskContext context, IScalarEvaluatorFactory evalLeftFactory,
+            IScalarEvaluatorFactory evalRightFactory, FunctionIdentifier funcID) throws AlgebricksException {
+        super(context, evalLeftFactory, evalRightFactory, funcID);
+    }
+
+    @Override
+    public void process(UTF8StringPointable leftPtr, UTF8StringPointable rightPtr, IPointable resultPointable)
+            throws IOException {
+        resultArray.reset();
+        compute(leftPtr, rightPtr, resultStrPtr);
+        writeResult(resultPointable);
+    }
+
+    /**
+     * Computes a string value from two input strings.
+     *
+     * @param left
+     *            , the first input argument.
+     * @param right
+     *            , the second input argument.
+     * @param resultStrPtr
+     *            , a pointable that is supposed to point to the result string.
+     * @throws AlgebricksException
+     */
+    protected abstract void compute(UTF8StringPointable left, UTF8StringPointable right,
+            UTF8StringPointable resultStrPtr) throws IOException;
+
+    // Writes the result.
+    private void writeResult(IPointable resultPointable) throws IOException {
+        dataOutput.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+        dataOutput.write(resultStrPtr.getByteArray(), 0, resultStrPtr.getLength());
+        resultPointable.set(resultStorage);
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java
index daa9a54..6eb6272 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractQuadStringStringEval.java
@@ -23,6 +23,7 @@
 package org.apache.asterix.runtime.evaluators.functions;
 
 import java.io.DataOutput;
+import java.io.IOException;
 
 import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import org.apache.asterix.om.base.AMutableString;
@@ -35,7 +36,6 @@
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
-import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
 import org.apache.hyracks.data.std.primitive.VoidPointable;
@@ -107,17 +107,17 @@
         strPtr3rd.set(array2.getByteArray(), array2.getStartOffset() + 1, array2.getLength());
         strPtr4th.set(array3.getByteArray(), array3.getStartOffset() + 1, array3.getLength());
 
-        String res = compute(strPtr1st, strPtr2nd, strPtr3rd, strPtr4th);
-        resultBuffer.setValue(res);
         try {
+            String res = compute(strPtr1st, strPtr2nd, strPtr3rd, strPtr4th);
+            resultBuffer.setValue(res);
             strSerde.serialize(resultBuffer, dout);
-        } catch (HyracksDataException e) {
+        } catch (IOException e) {
             throw new AlgebricksException(e);
         }
         result.set(resultStorage);
     }
 
     protected abstract String compute(UTF8StringPointable strPtr1st, UTF8StringPointable strPtr2nd,
-            UTF8StringPointable strPtr3rd, UTF8StringPointable strPtr4th) throws AlgebricksException;
+            UTF8StringPointable strPtr3rd, UTF8StringPointable strPtr4th) throws IOException;
 
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringBoolEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringBoolEval.java
index 6f1ce15..50e7135 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringBoolEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringBoolEval.java
@@ -18,91 +18,53 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
-import java.io.DataOutput;
+import java.io.IOException;
 
 import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import org.apache.asterix.om.base.ABoolean;
-import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.EnumDeserializer;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
-import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
-public abstract class AbstractTripleStringBoolEval implements IScalarEvaluator {
-
-    private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-    private DataOutput dout = resultStorage.getDataOutput();
-    private IPointable array0 = new VoidPointable();
-    private IPointable array1 = new VoidPointable();
-    private IPointable array2 = new VoidPointable();
-    private IScalarEvaluator eval0;
-    private IScalarEvaluator eval1;
-    private IScalarEvaluator eval2;
+public abstract class AbstractTripleStringBoolEval extends AbstractTripleStringEval {
 
     @SuppressWarnings("rawtypes")
     private ISerializerDeserializer boolSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ABOOLEAN);
 
-    private final FunctionIdentifier funcID;
-
-    private final UTF8StringPointable strPtr1st = new UTF8StringPointable();
-    private final UTF8StringPointable strPtr2nd = new UTF8StringPointable();
-    private final UTF8StringPointable strPtr3rd = new UTF8StringPointable();
-
     public AbstractTripleStringBoolEval(IHyracksTaskContext context, IScalarEvaluatorFactory eval0,
             IScalarEvaluatorFactory eval1, IScalarEvaluatorFactory eval2, FunctionIdentifier funcID)
             throws AlgebricksException {
-        this.eval0 = eval0.createScalarEvaluator(context);
-        this.eval1 = eval1.createScalarEvaluator(context);
-        this.eval2 = eval2.createScalarEvaluator(context);
-        this.funcID = funcID;
+        super(context, eval0, eval1, eval2, funcID);
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
-        eval0.evaluate(tuple, array0);
-        eval1.evaluate(tuple, array1);
-        eval2.evaluate(tuple, array2);
-
-        resultStorage.reset();
-        if (array0.getByteArray()[array0.getStartOffset()] != ATypeTag.SERIALIZED_STRING_TYPE_TAG
-                || array1.getByteArray()[array1.getStartOffset()] != ATypeTag.SERIALIZED_STRING_TYPE_TAG
-                || array2.getByteArray()[array2.getStartOffset()] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-            throw new AlgebricksException(funcID.getName()
-                    + ": expects iput type (STRING/NULL, STRING/NULL, STRING/NULL) but got ("
-                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(array0.getByteArray()[array0.getStartOffset()])
-                    + ", "
-                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(array1.getByteArray()[array1.getStartOffset()])
-                    + ", "
-                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(array2.getByteArray()[array2.getStartOffset()])
-                    + ")");
-        }
-
-        strPtr1st.set(array0.getByteArray(), array0.getStartOffset() + 1, array0.getLength());
-        strPtr2nd.set(array1.getByteArray(), array1.getStartOffset() + 1, array1.getLength());
-        strPtr3rd.set(array2.getByteArray(), array2.getStartOffset() + 1, array2.getLength());
-
-        ABoolean res = compute(strPtr1st, strPtr2nd, strPtr3rd) ? ABoolean.TRUE : ABoolean.FALSE;
-        try {
-            boolSerde.serialize(res, dout);
-        } catch (HyracksDataException e) {
-            throw new AlgebricksException(e);
-        }
+    protected void process(UTF8StringPointable first, UTF8StringPointable second, UTF8StringPointable thrid,
+            IPointable result) throws IOException {
+        ABoolean res = compute(first, second, thrid) ? ABoolean.TRUE : ABoolean.FALSE;
+        boolSerde.serialize(res, dout);
         result.set(resultStorage);
     }
 
-    protected abstract boolean compute(UTF8StringPointable strPtr1st, UTF8StringPointable strPtr2nd,
-            UTF8StringPointable strPtr3rd) throws AlgebricksException;
+    /**
+     * Computes a boolean value from three input strings.
+     *
+     * @param first
+     *            , the first input argument.
+     * @param second
+     *            , the second input argument.
+     * @param third
+     *            , the second input argument.
+     * @return a boolean value.
+     * @throws IOException
+     */
+    protected abstract boolean compute(UTF8StringPointable first, UTF8StringPointable second, UTF8StringPointable third)
+            throws IOException;
 
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringEval.java
new file mode 100644
index 0000000..e54ac3f
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringEval.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+abstract class AbstractTripleStringEval implements IScalarEvaluator {
+
+    // Argument evaluators.
+    private IScalarEvaluator eval0;
+    private IScalarEvaluator eval1;
+    private IScalarEvaluator eval2;
+
+    // Argument pointables.
+    private IPointable argPtrFirst = new VoidPointable();
+    private IPointable argPtrSecond = new VoidPointable();
+    private IPointable argPtrThird = new VoidPointable();
+    private final UTF8StringPointable strPtr1st = new UTF8StringPointable();
+    private final UTF8StringPointable strPtr2nd = new UTF8StringPointable();
+    private final UTF8StringPointable strPtr3rd = new UTF8StringPointable();
+
+    // For outputting results.
+    ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+    DataOutput dout = resultStorage.getDataOutput();
+
+    // Function ID, for error reporting.
+    private final FunctionIdentifier funcID;
+
+    AbstractTripleStringEval(IHyracksTaskContext context, IScalarEvaluatorFactory eval0, IScalarEvaluatorFactory eval1,
+            IScalarEvaluatorFactory eval2, FunctionIdentifier funcID) throws AlgebricksException {
+        this.eval0 = eval0.createScalarEvaluator(context);
+        this.eval1 = eval1.createScalarEvaluator(context);
+        this.eval2 = eval2.createScalarEvaluator(context);
+        this.funcID = funcID;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
+        // Gets the first argument.
+        eval0.evaluate(tuple, argPtrFirst);
+        byte[] bytes0 = argPtrFirst.getByteArray();
+        int start0 = argPtrFirst.getStartOffset();
+        int len0 = argPtrFirst.getLength();
+
+        // Gets the second argument.
+        eval1.evaluate(tuple, argPtrSecond);
+        byte[] bytes1 = argPtrSecond.getByteArray();
+        int start1 = argPtrSecond.getStartOffset();
+        int len1 = argPtrSecond.getLength();
+
+        // Gets the third argument.
+        eval2.evaluate(tuple, argPtrThird);
+        byte[] bytes2 = argPtrThird.getByteArray();
+        int start2 = argPtrThird.getStartOffset();
+        int len2 = argPtrThird.getLength();
+
+        // Type check.
+        if (bytes0[start0] != ATypeTag.SERIALIZED_STRING_TYPE_TAG
+                || bytes1[start1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG
+                || bytes2[start2] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+            throw new AlgebricksException(funcID.getName() + ": expects iput type (STRING, STRING, STRING) but got ("
+                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes0[start0]) + ", "
+                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes1[start1]) + ", "
+                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes2[start2]) + ")");
+        }
+
+        // Sets argument UTF8Pointables.
+        strPtr1st.set(bytes0, start0 + 1, len0 - 1);
+        strPtr2nd.set(bytes1, start1 + 1, len1 - 1);
+        strPtr3rd.set(bytes2, start2 + 1, len2 - 1);
+
+        // Resets the output storage.
+        resultStorage.reset();
+        // The actual processing.
+        try {
+            process(strPtr1st, strPtr2nd, strPtr3rd, result);
+        } catch (IOException e) {
+            throw new AlgebricksException(e);
+        }
+    }
+
+    /**
+     * The actual processing of a string function.
+     *
+     * @param first
+     *            , the first argument.
+     * @param second
+     *            , the second argument.
+     * @param third
+     *            , the second argument.
+     * @param resultPointable
+     *            , the result.
+     * @throws IOException
+     */
+    protected abstract void process(UTF8StringPointable first, UTF8StringPointable second, UTF8StringPointable third,
+            IPointable resultPointable) throws IOException;
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringIntEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringIntEval.java
new file mode 100644
index 0000000..97c843a
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringIntEval.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public abstract class AbstractTripleStringIntEval extends AbstractTripleStringEval {
+
+    @SuppressWarnings("rawtypes")
+    private final ISerializerDeserializer intSerde = AqlSerializerDeserializerProvider.INSTANCE
+            .getSerializerDeserializer(BuiltinType.AINT32);
+    private final AMutableInt32 resultValue = new AMutableInt32(0);
+
+    public AbstractTripleStringIntEval(IHyracksTaskContext context, IScalarEvaluatorFactory eval0,
+            IScalarEvaluatorFactory eval1, IScalarEvaluatorFactory eval2, FunctionIdentifier funcID)
+            throws AlgebricksException {
+        super(context, eval0, eval1, eval2, funcID);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void process(UTF8StringPointable first, UTF8StringPointable second, UTF8StringPointable thrid,
+            IPointable result)
+ throws IOException {
+        resultValue.setValue(compute(first, second, thrid));
+        intSerde.serialize(resultValue, dout);
+        result.set(resultStorage);
+    }
+
+    /**
+     * Computes an integer value from three input strings.
+     *
+     * @param first
+     *            , the first input argument.
+     * @param second
+     *            , the second input argument.
+     * @param third
+     *            , the second input argument.
+     * @return an integer value.
+     * @throws IOException
+     */
+    protected abstract int compute(UTF8StringPointable first, UTF8StringPointable second, UTF8StringPointable third)
+            throws IOException;
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringStringEval.java
index bcbee23..6f6fdc4 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringStringEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringStringEval.java
@@ -18,92 +18,53 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
-import java.io.DataOutput;
+import java.io.IOException;
 
 import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import org.apache.asterix.om.base.AMutableString;
-import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.EnumDeserializer;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
-import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
-public abstract class AbstractTripleStringStringEval implements IScalarEvaluator {
+public abstract class AbstractTripleStringStringEval extends AbstractTripleStringEval {
 
-    private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-    private DataOutput dout = resultStorage.getDataOutput();
-    private IPointable array0 = new VoidPointable();
-    private IPointable array1 = new VoidPointable();
-    private IPointable array2 = new VoidPointable();
-    private IScalarEvaluator eval0;
-    private IScalarEvaluator eval1;
-    private IScalarEvaluator eval2;
-
-    private AMutableString resultBuffer = new AMutableString("");
     @SuppressWarnings("rawtypes")
-    private ISerializerDeserializer strSerde = AqlSerializerDeserializerProvider.INSTANCE
+    private final ISerializerDeserializer stringSerde = AqlSerializerDeserializerProvider.INSTANCE
             .getSerializerDeserializer(BuiltinType.ASTRING);
-
-    private final UTF8StringPointable strPtr1st = new UTF8StringPointable();
-    private final UTF8StringPointable strPtr2nd = new UTF8StringPointable();
-    private final UTF8StringPointable strPtr3rd = new UTF8StringPointable();
-
-    private final FunctionIdentifier funcID;
+    private final AMutableString resultValue = new AMutableString("");
 
     public AbstractTripleStringStringEval(IHyracksTaskContext context, IScalarEvaluatorFactory eval0,
             IScalarEvaluatorFactory eval1, IScalarEvaluatorFactory eval2, FunctionIdentifier funcID)
             throws AlgebricksException {
-        this.eval0 = eval0.createScalarEvaluator(context);
-        this.eval1 = eval1.createScalarEvaluator(context);
-        this.eval2 = eval2.createScalarEvaluator(context);
-        this.funcID = funcID;
+        super(context, eval0, eval1, eval2, funcID);
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
-        eval0.evaluate(tuple, array0);
-        eval1.evaluate(tuple, array1);
-        eval2.evaluate(tuple, array2);
-
-        resultStorage.reset();
-        if (array0.getByteArray()[array0.getStartOffset()] != ATypeTag.SERIALIZED_STRING_TYPE_TAG
-                || array1.getByteArray()[array1.getStartOffset()] != ATypeTag.SERIALIZED_STRING_TYPE_TAG
-                || array2.getByteArray()[array2.getStartOffset()] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-            throw new AlgebricksException(funcID.getName()
-                    + ": expects input type (STRING/NULL, STRING/NULL, STRING/NULL), but got ("
-                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(array0.getByteArray()[array0.getStartOffset()])
-                    + ", "
-                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(array1.getByteArray()[array1.getStartOffset()])
-                    + ", "
-                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(array2.getByteArray()[array2.getStartOffset()])
-                    + ".");
-        }
-
-        strPtr1st.set(array0.getByteArray(), array0.getStartOffset() + 1, array0.getLength());
-        strPtr2nd.set(array1.getByteArray(), array1.getStartOffset() + 1, array1.getLength());
-        strPtr3rd.set(array2.getByteArray(), array2.getStartOffset() + 1, array2.getLength());
-
-        String res = compute(strPtr1st, strPtr2nd, strPtr3rd);
-        resultBuffer.setValue(res);
-        try {
-            strSerde.serialize(resultBuffer, dout);
-        } catch (HyracksDataException e) {
-            throw new AlgebricksException(e);
-        }
+    protected void process(UTF8StringPointable first, UTF8StringPointable second, UTF8StringPointable thrid,
+            IPointable result) throws IOException {
+        resultValue.setValue(compute(first, second, thrid));
+        stringSerde.serialize(resultValue, dout);
         result.set(resultStorage);
     }
 
-    protected abstract String compute(UTF8StringPointable strPtr1st, UTF8StringPointable strPtr2nd,
-            UTF8StringPointable strPtr3rd) throws AlgebricksException;
+    /**
+     * Computes a string value from three input strings.
+     *
+     * @param first
+     *            , the first input argument.
+     * @param second
+     *            , the second input argument.
+     * @param third
+     *            , the second input argument.
+     * @return a string value.
+     * @throws IOException
+     */
+    protected abstract String compute(UTF8StringPointable first, UTF8StringPointable second, UTF8StringPointable third)
+            throws IOException;
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractUnaryStringStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractUnaryStringStringEval.java
new file mode 100644
index 0000000..8e68143
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractUnaryStringStringEval.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.data.std.util.GrowableArray;
+import org.apache.hyracks.data.std.util.UTF8StringBuilder;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+abstract class AbstractUnaryStringStringEval implements IScalarEvaluator {
+
+    // For the argument.
+    private final IScalarEvaluator argEval;
+    private final VoidPointable argPtr = new VoidPointable();
+    private final UTF8StringPointable stringPtr = new UTF8StringPointable();
+
+    // For writing results.
+    final GrowableArray resultArray = new GrowableArray();
+    final UTF8StringBuilder resultBuilder = new UTF8StringBuilder();
+    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+    private final DataOutput dataOutput = resultStorage.getDataOutput();
+    private final FunctionIdentifier funcID;
+
+    AbstractUnaryStringStringEval(IHyracksTaskContext context, IScalarEvaluatorFactory argEvalFactory,
+            FunctionIdentifier funcID) throws AlgebricksException {
+        this.argEval = argEvalFactory.createScalarEvaluator(context);
+        this.funcID = funcID;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void evaluate(IFrameTupleReference tuple, IPointable resultPointable) throws AlgebricksException {
+        resultStorage.reset();
+        argEval.evaluate(tuple, argPtr);
+        byte[] argBytes = argPtr.getByteArray();
+        int offset = argPtr.getStartOffset();
+        byte inputTypeTag = argBytes[offset];
+        if (inputTypeTag != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+            throw new AlgebricksException(funcID.getName() + ": expects input type to be STRING, but got ("
+                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(inputTypeTag) + ".");
+        }
+        stringPtr.set(argBytes, offset + 1, argPtr.getLength() - 1);
+        resultArray.reset();
+        try {
+            process(stringPtr, resultPointable);
+            writeResult(resultPointable);
+        } catch (IOException e) {
+            throw new AlgebricksException(e);
+        }
+    }
+
+    /**
+     * Processes an input UTF8 string.
+     *
+     * @param inputString
+     *            , the input string.
+     * @param resultPointable
+     *            , a pointable that is supposed to point to the result.
+     */
+    abstract void process(UTF8StringPointable inputString, IPointable resultPointable) throws IOException;
+
+    // Writes the result.
+    void writeResult(IPointable resultPointable) throws IOException {
+        dataOutput.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+        dataOutput.write(resultArray.getByteArray(), 0, resultArray.getLength());
+        resultPointable.set(resultStorage);
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/RegExpDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/RegExpDescriptor.java
deleted file mode 100644
index 7b9ca73..0000000
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/RegExpDescriptor.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.asterix.runtime.evaluators.functions;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.DataOutput;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
-import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
-import org.apache.asterix.om.base.ABoolean;
-import org.apache.asterix.om.base.AString;
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
-import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.EnumDeserializer;
-import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
-import org.apache.hyracks.api.context.IHyracksTaskContext;
-import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
-import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
-import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.data.std.api.IPointable;
-import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
-import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
-import org.apache.hyracks.data.std.util.UTF8CharSequence;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-
-/**
- * Creates new Matcher and Pattern objects each time the value of the pattern
- * argument (the second argument) changes.
- */
-
-public class RegExpDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-    private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new RegExpDescriptor();
-        }
-    };
-
-    @Override
-    public FunctionIdentifier getIdentifier() {
-        return AsterixBuiltinFunctions.REG_EXP;
-    }
-
-    @Override
-    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
-            throws AlgebricksException {
-
-        return new IScalarEvaluatorFactory() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
-
-                return new IScalarEvaluator() {
-
-                    private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-                    private DataOutput dout = resultStorage.getDataOutput();
-                    private boolean first = true;
-                    private IPointable array0 = new VoidPointable();
-                    private IScalarEvaluator evalString = args[0].createScalarEvaluator(ctx);
-                    private IScalarEvaluator evalPattern = args[1].createScalarEvaluator(ctx);
-                    private ByteArrayAccessibleOutputStream lastPattern = new ByteArrayAccessibleOutputStream();
-                    private UTF8CharSequence carSeq = new UTF8CharSequence();
-                    private UTF8StringPointable utf8Ptr = new UTF8StringPointable();
-                    private IBinaryComparator strComp = AqlBinaryComparatorFactoryProvider.INSTANCE
-                            .getBinaryComparatorFactory(BuiltinType.ASTRING, true).createBinaryComparator();
-                    @SuppressWarnings("unchecked")
-                    private ISerializerDeserializer<AString> stringSerde = AqlSerializerDeserializerProvider.INSTANCE
-                            .getSerializerDeserializer(BuiltinType.ASTRING);
-                    @SuppressWarnings("unchecked")
-                    private ISerializerDeserializer<ABoolean> booleanSerde = AqlSerializerDeserializerProvider.INSTANCE
-                            .getSerializerDeserializer(BuiltinType.ABOOLEAN);
-                    private Matcher matcher;
-                    private Pattern pattern;
-
-                    @Override
-                    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
-                        resultStorage.reset();
-                        // evaluate the pattern first
-                        try {
-                            evalPattern.evaluate(tuple, array0);
-                            evalString.evaluate(tuple, array0);
-
-                            byte[] patternBytes = array0.getByteArray();
-                            int patternOffset = array0.getStartOffset();
-                            int patternLen = array0.getLength();
-                            if (patternBytes[patternOffset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                                throw new AlgebricksException(AsterixBuiltinFunctions.REG_EXP.getName()
-                                        + ": expects type STRING/NULL for the first input argument but got "
-                                        + EnumDeserializer.ATYPETAGDESERIALIZER
-                                                .deserialize(patternBytes[patternOffset]));
-                            }
-                            boolean newPattern = false;
-                            if (first) {
-                                first = false;
-                                newPattern = true;
-                            } else {
-                                int c = strComp.compare(patternBytes, patternOffset, patternLen,
-                                        lastPattern.getByteArray(), 0, lastPattern.size());
-                                if (c != 0) {
-                                    newPattern = true;
-                                }
-                            }
-                            if (newPattern) {
-                                lastPattern.reset();
-                                lastPattern.write(patternBytes, patternOffset, patternLen);
-                                // ! object creation !
-                                DataInputStream di = new DataInputStream(
-                                        new ByteArrayInputStream(lastPattern.getByteArray()));
-                                AString strPattern = stringSerde.deserialize(di);
-                                pattern = Pattern.compile(strPattern.getStringValue());
-
-                            }
-                            byte[] data = array0.getByteArray();
-                            int offset = array0.getStartOffset();
-                            int len = array0.getLength();
-                            if (data[offset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                                throw new AlgebricksException(AsterixBuiltinFunctions.REG_EXP.getName()
-                                        + ": expects type STRING/NULL for the second input argument but got "
-                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(data[offset]));
-                            }
-                            utf8Ptr.set(data, offset + 1, len - 1);
-                            carSeq.reset(utf8Ptr);
-                            if (newPattern) {
-                                matcher = pattern.matcher(carSeq);
-                            } else {
-                                matcher.reset(carSeq);
-                            }
-                            ABoolean res = (matcher.find(0)) ? ABoolean.TRUE : ABoolean.FALSE;
-                            booleanSerde.serialize(res, dout);
-                            result.set(resultStorage);
-                        } catch (HyracksDataException e) {
-                            throw new AlgebricksException(e);
-                        }
-                    }
-                };
-            }
-        };
-    }
-}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringContainsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringContainsDescriptor.java
index 941a84c..5d88b6c 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringContainsDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringContainsDescriptor.java
@@ -18,6 +18,8 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
+import java.io.IOException;
+
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
@@ -52,8 +54,7 @@
                 return new AbstractBinaryStringBoolEval(ctx, args[0], args[1],
                         AsterixBuiltinFunctions.STRING_CONTAINS) {
                     @Override
-                    protected boolean compute(UTF8StringPointable left, UTF8StringPointable right)
-                            throws AlgebricksException {
+                    protected boolean compute(UTF8StringPointable left, UTF8StringPointable right) throws IOException {
                         return UTF8StringPointable.contains(left, right, false);
                     }
                 };
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringEndsWithDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringEndsWithDescriptor.java
index 0c251d4..c0996b7 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringEndsWithDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringEndsWithDescriptor.java
@@ -18,6 +18,8 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
+import java.io.IOException;
+
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
@@ -53,8 +55,7 @@
                         AsterixBuiltinFunctions.STRING_ENDS_WITH) {
 
                     @Override
-                    protected boolean compute(UTF8StringPointable left, UTF8StringPointable right)
-                            throws AlgebricksException {
+                    protected boolean compute(UTF8StringPointable left, UTF8StringPointable right) throws IOException {
                         return UTF8StringPointable.endsWith(left, right, false);
                     }
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringEqualDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringEqualDescriptor.java
index 441c3e1..78fdba6 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringEqualDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringEqualDescriptor.java
@@ -18,6 +18,8 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
+import java.io.IOException;
+
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
@@ -53,8 +55,7 @@
                         AsterixBuiltinFunctions.STRING_EQUAL) {
 
                     @Override
-                    protected boolean compute(UTF8StringPointable left, UTF8StringPointable right)
-                            throws AlgebricksException {
+                    protected boolean compute(UTF8StringPointable left, UTF8StringPointable right) throws IOException {
                         return left.compareTo(right) == 0;
                     }
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringInitCapDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringInitCapDescriptor.java
new file mode 100644
index 0000000..fee7e06
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringInitCapDescriptor.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringInitCapDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringInitCapDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(IScalarEvaluatorFactory[] args) {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractUnaryStringStringEval(ctx, args[0], StringInitCapDescriptor.this.getIdentifier()) {
+                    @Override
+                    protected void process(UTF8StringPointable inputString, IPointable resultPointable)
+                            throws IOException {
+                        inputString.initCap(resultBuilder, resultArray);
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_INITCAP;
+    }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrim2Descriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrim2Descriptor.java
new file mode 100644
index 0000000..bcb70e1
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrim2Descriptor.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.StringTrimmer;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringLTrim2Descriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringLTrim2Descriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_LTRIM2;
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractBinaryStringStringEval(ctx, args[0], args[1],
+                        StringLTrim2Descriptor.this.getIdentifier()) {
+                    private StringTrimmer stringTrimmer = new StringTrimmer(resultBuilder, resultArray);
+
+                    @Override
+                    protected void compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
+                            UTF8StringPointable resultStrPtr) throws IOException {
+                        stringTrimmer.build(patternPtr);
+                        stringTrimmer.trim(srcPtr, resultStrPtr, true, false);
+                    }
+                };
+            }
+        };
+    }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrimDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrimDescriptor.java
new file mode 100644
index 0000000..a21b6b4
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrimDescriptor.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.StringTrimmer;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringLTrimDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringLTrimDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_LTRIM;
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractUnaryStringStringEval(ctx, args[0], StringLTrimDescriptor.this.getIdentifier()) {
+                    private StringTrimmer stringTrimmer = new StringTrimmer(resultBuilder, resultArray, " ");
+
+                    @Override
+                    protected void process(UTF8StringPointable srcPtr, IPointable resultStrPtr) throws IOException {
+                        stringTrimmer.trim(srcPtr, resultStrPtr, true, false);
+                    }
+                };
+            }
+        };
+    }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLikeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLikeDescriptor.java
index 9b2a8b3..8adb7b3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLikeDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLikeDescriptor.java
@@ -18,21 +18,19 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.io.IOException;
 
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
-import org.apache.hyracks.data.std.util.UTF8CharSequence;
 
 /**
  * Creates new Matcher and Pattern objects each time the value of the pattern
@@ -58,47 +56,33 @@
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
             throws AlgebricksException {
-
         return new IScalarEvaluatorFactory() {
             private static final long serialVersionUID = 1L;
 
             @Override
             public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
-
                 return new AbstractBinaryStringBoolEval(ctx, args[0], args[1],
-                        AsterixBuiltinFunctions.STRING_MATCHES) {
-
-                    private Pattern pattern = null;
-                    private Matcher matcher = null;
-                    private ByteArrayAccessibleOutputStream lastPatternStorage = new ByteArrayAccessibleOutputStream();
-                    private UTF8StringPointable lastPatternPtr = new UTF8StringPointable();
-                    private UTF8CharSequence carSeq = new UTF8CharSequence();
+                        StringLikeDescriptor.this.getIdentifier()) {
+                    private final RegExpMatcher matcher = new RegExpMatcher();
+                    private final RegExpMatcher.IRegExpPatternGenerator patternGenerator = new LikePatternGenerator();
 
                     @Override
                     protected boolean compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr)
-                            throws AlgebricksException {
-                        boolean newPattern = false;
-                        if (pattern == null || lastPatternPtr.compareTo(patternPtr) != 0) {
-                            newPattern = true;
-                        }
-                        if (newPattern) {
-                            StringEvaluatorUtils.copyResetUTF8Pointable(patternPtr, lastPatternStorage, lastPatternPtr);
-                            // ! object creation !
-                            pattern = Pattern.compile(StringEvaluatorUtils.toRegex(lastPatternPtr.toString()));
-                        }
-
-                        carSeq.reset(srcPtr);
-                        if (newPattern) {
-                            matcher = pattern.matcher(carSeq);
-                        } else {
-                            matcher.reset(carSeq);
-                        }
-                        return matcher.find();
+                            throws IOException {
+                        matcher.build(srcPtr, patternPtr, null, patternGenerator);
+                        return matcher.matches();
                     }
-
                 };
             }
         };
     }
 
+    class LikePatternGenerator implements RegExpMatcher.IRegExpPatternGenerator {
+
+        @Override
+        public String toRegExpPatternString(String input) {
+            return StringEvaluatorUtils.toRegex(input);
+        }
+    }
+
 };
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLowerCaseDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLowerCaseDescriptor.java
index 341a26a..bc27a11 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLowerCaseDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLowerCaseDescriptor.java
@@ -18,14 +18,11 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
-import java.io.DataOutput;
 import java.io.IOException;
 
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.EnumDeserializer;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -34,11 +31,6 @@
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
-import org.apache.hyracks.data.std.util.GrowableArray;
-import org.apache.hyracks.data.std.util.UTF8StringBuilder;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 public class StringLowerCaseDescriptor extends AbstractScalarFunctionDynamicDescriptor {
     private static final long serialVersionUID = 1L;
@@ -51,49 +43,18 @@
     };
 
     @Override
-    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+    public IScalarEvaluatorFactory createEvaluatorFactory(IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
             private static final long serialVersionUID = 1L;
 
             @Override
-            public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws AlgebricksException {
-                return new IScalarEvaluator() {
-
-                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-                    private final DataOutput out = resultStorage.getDataOutput();
-                    private final IPointable inputArg = new VoidPointable();
-                    private final IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
-
-                    private final GrowableArray array = new GrowableArray();
-                    private final UTF8StringBuilder builder = new UTF8StringBuilder();
-                    private final UTF8StringPointable string = new UTF8StringPointable();
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractUnaryStringStringEval(ctx, args[0], StringLowerCaseDescriptor.this.getIdentifier()) {
 
                     @Override
-                    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
-
-                        try {
-                            resultStorage.reset();
-                            eval.evaluate(tuple, inputArg);
-                            byte[] serString = inputArg.getByteArray();
-                            int offset = inputArg.getStartOffset();
-                            int len = inputArg.getLength() - 1;
-
-                            if (serString[offset] == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                                string.set(serString, offset + 1, len - 1);
-                                array.reset();
-                                UTF8StringPointable.lowercase(string, builder, array);
-
-                                out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
-                                out.write(array.getByteArray(), 0, array.getLength());
-                            } else {
-                                throw new AlgebricksException(AsterixBuiltinFunctions.STRING_LOWERCASE.getName()
-                                        + ": expects input type STRING/NULL but got "
-                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serString[offset]));
-                            }
-                            result.set(resultStorage);
-                        } catch (IOException e1) {
-                            throw new AlgebricksException(e1);
-                        }
+                    protected void process(UTF8StringPointable inputString, IPointable resultPointable)
+                            throws IOException {
+                        inputString.lowercase(resultBuilder, resultArray);
                     }
                 };
             }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringMatchesWithFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringMatchesWithFlagDescriptor.java
deleted file mode 100644
index 10de2e4..0000000
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringMatchesWithFlagDescriptor.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.apache.asterix.runtime.evaluators.functions;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
-import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
-import org.apache.hyracks.api.context.IHyracksTaskContext;
-import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
-import org.apache.hyracks.data.std.util.UTF8CharSequence;
-
-public class StringMatchesWithFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-
-    private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new StringMatchesWithFlagDescriptor();
-        }
-    };
-
-    @Override
-    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
-            throws AlgebricksException {
-
-        return new IScalarEvaluatorFactory() {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
-
-                return new AbstractTripleStringBoolEval(ctx, args[0], args[1], args[2],
-                        AsterixBuiltinFunctions.STRING_MATCHES_WITH_FLAG) {
-                    private Pattern pattern = null;
-                    private Matcher matcher = null;
-                    private ByteArrayAccessibleOutputStream lastPatternStorage = new ByteArrayAccessibleOutputStream();
-                    private ByteArrayAccessibleOutputStream lastFlagsStorage = new ByteArrayAccessibleOutputStream();
-                    private UTF8StringPointable lastPatternPtr = new UTF8StringPointable();
-                    private UTF8StringPointable lastFlagPtr = new UTF8StringPointable();
-                    private UTF8CharSequence carSeq = new UTF8CharSequence();
-
-                    @Override
-                    protected boolean compute(UTF8StringPointable strSrc, UTF8StringPointable strPattern,
-                            UTF8StringPointable strFlag) throws AlgebricksException {
-                        final boolean newPattern = (pattern == null || lastPatternPtr.compareTo(strPattern) != 0);
-                        final boolean newFlag = (pattern == null || lastFlagPtr.compareTo(strFlag) != 0);
-
-                        if (newPattern) {
-                            StringEvaluatorUtils.copyResetUTF8Pointable(strPattern, lastPatternStorage, lastPatternPtr);
-                        }
-
-                        if (newFlag) {
-                            StringEvaluatorUtils.copyResetUTF8Pointable(strFlag, lastFlagsStorage, lastFlagPtr);
-                        }
-
-                        if (newPattern || newFlag) {
-                            pattern = Pattern.compile(lastPatternPtr.toString(),
-                                    StringEvaluatorUtils.toFlag(lastFlagPtr.toString()));
-                        }
-                        carSeq.reset(strSrc);
-                        if (newPattern || newFlag) {
-                            matcher = pattern.matcher(carSeq);
-                        } else {
-                            matcher.reset(carSeq);
-                        }
-                        return matcher.find();
-                    }
-                };
-            }
-        };
-    }
-
-    @Override
-    public FunctionIdentifier getIdentifier() {
-        return AsterixBuiltinFunctions.STRING_MATCHES_WITH_FLAG;
-    }
-}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringPositionDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringPositionDescriptor.java
new file mode 100644
index 0000000..6194571
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringPositionDescriptor.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringPositionDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringPositionDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractBinaryStringIntEval(ctx, args[0], args[1],
+                        StringPositionDescriptor.this.getIdentifier()) {
+
+                    @Override
+                    protected int compute(UTF8StringPointable left, UTF8StringPointable right) throws IOException {
+                        return UTF8StringPointable.find(left, right, false);
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_POSITION;
+    }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrim2Descriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrim2Descriptor.java
new file mode 100644
index 0000000..bbd4822
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrim2Descriptor.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.StringTrimmer;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringRTrim2Descriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringRTrim2Descriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_RTRIM2;
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractBinaryStringStringEval(ctx, args[0], args[1],
+                        StringRTrim2Descriptor.this.getIdentifier()) {
+                    private StringTrimmer stringTrimmer = new StringTrimmer(resultBuilder, resultArray);
+
+                    @Override
+                    protected void compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
+                            UTF8StringPointable resultStrPtr) throws IOException {
+                        stringTrimmer.build(patternPtr);
+                        stringTrimmer.trim(srcPtr, resultStrPtr, false, true);
+                    }
+                };
+            }
+        };
+    }
+
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrimDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrimDescriptor.java
new file mode 100644
index 0000000..89071d5
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrimDescriptor.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.StringTrimmer;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringRTrimDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringRTrimDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_RTRIM;
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractUnaryStringStringEval(ctx, args[0], StringRTrimDescriptor.this.getIdentifier()) {
+                    private StringTrimmer stringTrimmer = new StringTrimmer(resultBuilder, resultArray, " ");
+
+                    @Override
+                    protected void process(UTF8StringPointable srcPtr, IPointable resultStrPtr) throws IOException {
+                        stringTrimmer.trim(srcPtr, resultStrPtr, false, true);
+                    }
+                };
+            }
+        };
+    }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringMatchesDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpContainsDescriptor.java
similarity index 61%
rename from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringMatchesDescriptor.java
rename to asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpContainsDescriptor.java
index 5551942..e7017ab 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringMatchesDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpContainsDescriptor.java
@@ -18,73 +18,48 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.io.IOException;
 
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
-import org.apache.hyracks.data.std.util.UTF8CharSequence;
 
-public class StringMatchesDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+public class StringRegExpContainsDescriptor extends AbstractScalarFunctionDynamicDescriptor {
     private static final long serialVersionUID = 1L;
 
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         @Override
         public IFunctionDescriptor createFunctionDescriptor() {
-            return new StringMatchesDescriptor();
+            return new StringRegExpContainsDescriptor();
         }
     };
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
             throws AlgebricksException {
-
         return new IScalarEvaluatorFactory() {
             private static final long serialVersionUID = 1L;
 
             @Override
             public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
-
                 return new AbstractBinaryStringBoolEval(ctx, args[0], args[1],
-                        AsterixBuiltinFunctions.STRING_MATCHES) {
-
-                    private Pattern pattern = null;
-                    private Matcher matcher = null;
-                    private ByteArrayAccessibleOutputStream lastPatternStorage = new ByteArrayAccessibleOutputStream();
-                    private UTF8StringPointable lastPatternPtr = new UTF8StringPointable();
-                    private UTF8CharSequence carSeq = new UTF8CharSequence();
+                        StringRegExpContainsDescriptor.this.getIdentifier()) {
+                    private final RegExpMatcher matcher = new RegExpMatcher();
 
                     @Override
                     protected boolean compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr)
-                            throws AlgebricksException {
-                        boolean newPattern = false;
-                        if (pattern == null || lastPatternPtr.compareTo(patternPtr) != 0) {
-                            newPattern = true;
-                        }
-                        if (newPattern) {
-                            StringEvaluatorUtils.copyResetUTF8Pointable(patternPtr, lastPatternStorage, lastPatternPtr);
-                            // ! object creation !
-                            pattern = Pattern.compile(lastPatternPtr.toString());
-                        }
-
-                        carSeq.reset(srcPtr);
-                        if (newPattern) {
-                            matcher = pattern.matcher(carSeq);
-                        } else {
-                            matcher.reset(carSeq);
-                        }
+                            throws IOException {
+                        matcher.build(srcPtr, patternPtr);
                         return matcher.find();
                     }
-
                 };
             }
         };
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpContainsWithFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpContainsWithFlagDescriptor.java
new file mode 100644
index 0000000..45f72b3
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpContainsWithFlagDescriptor.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringRegExpContainsWithFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringRegExpContainsWithFlagDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractTripleStringBoolEval(ctx, args[0], args[1], args[2],
+                        StringRegExpContainsWithFlagDescriptor.this.getIdentifier()) {
+                    private final RegExpMatcher matcher = new RegExpMatcher();
+
+                    @Override
+                    protected boolean compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
+                            UTF8StringPointable flagPtr) throws IOException {
+                        matcher.build(srcPtr, patternPtr, flagPtr);
+                        return matcher.find();
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_MATCHES_WITH_FLAG;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpLikeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpLikeDescriptor.java
new file mode 100644
index 0000000..16e70b9
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpLikeDescriptor.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringRegExpLikeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringRegExpLikeDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractBinaryStringBoolEval(ctx, args[0], args[1],
+                        StringRegExpLikeDescriptor.this.getIdentifier()) {
+                    private final RegExpMatcher matcher = new RegExpMatcher();
+
+                    @Override
+                    protected boolean compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr)
+                            throws IOException {
+                        matcher.build(srcPtr, patternPtr);
+                        return matcher.matches();
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_REGEXP_LIKE;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpLikeWithFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpLikeWithFlagDescriptor.java
new file mode 100644
index 0000000..274b36a
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpLikeWithFlagDescriptor.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringRegExpLikeWithFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringRegExpLikeWithFlagDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractTripleStringBoolEval(ctx, args[0], args[1], args[2],
+                        StringRegExpLikeWithFlagDescriptor.this.getIdentifier()) {
+                    private final RegExpMatcher matcher = new RegExpMatcher();
+
+                    @Override
+                    protected boolean compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
+                            UTF8StringPointable flagPtr) throws IOException {
+                        matcher.build(srcPtr, patternPtr, flagPtr);
+                        return matcher.matches();
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_REGEXP_LIKE_WITH_FLAG;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpPositionDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpPositionDescriptor.java
new file mode 100644
index 0000000..3fd8544
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpPositionDescriptor.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringRegExpPositionDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringRegExpPositionDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractBinaryStringIntEval(ctx, args[0], args[1],
+                        StringRegExpPositionDescriptor.this.getIdentifier()) {
+                    private final RegExpMatcher matcher = new RegExpMatcher();
+
+                    @Override
+                    protected int compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr)
+                            throws IOException {
+                        matcher.build(srcPtr, patternPtr);
+                        return matcher.postion();
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_REGEXP_POSITION;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpPositionWithFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpPositionWithFlagDescriptor.java
new file mode 100644
index 0000000..1085d89
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpPositionWithFlagDescriptor.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringRegExpPositionWithFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringRegExpPositionWithFlagDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractTripleStringIntEval(ctx, args[0], args[1], args[2],
+                        StringRegExpPositionWithFlagDescriptor.this.getIdentifier()) {
+                    private final RegExpMatcher matcher = new RegExpMatcher();
+
+                    @Override
+                    protected int compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
+                            UTF8StringPointable flagPtr) throws IOException {
+                        matcher.build(srcPtr, patternPtr, flagPtr);
+                        return matcher.postion();
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_REGEXP_POSITION_WITH_FLAG;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceDescriptor.java
new file mode 100644
index 0000000..bdaf7cf
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceDescriptor.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringRegExpReplaceDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringRegExpReplaceDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractTripleStringStringEval(ctx, args[0], args[1], args[2],
+                        StringRegExpReplaceDescriptor.this.getIdentifier()) {
+                    private final RegExpMatcher matcher = new RegExpMatcher();
+
+                    @Override
+                    protected String compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
+                            UTF8StringPointable replacePtr) throws IOException {
+                        matcher.build(srcPtr, patternPtr);
+                        return matcher.replace(replacePtr);
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_REPLACE;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagsDescriptor.java
new file mode 100644
index 0000000..cf6eeca
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRegExpReplaceWithFlagsDescriptor.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.RegExpMatcher;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringRegExpReplaceWithFlagsDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringRegExpReplaceWithFlagsDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractQuadStringStringEval(ctx, args[0], args[1], args[2], args[3],
+                        StringRegExpReplaceWithFlagsDescriptor.this.getIdentifier()) {
+                    private final RegExpMatcher matcher = new RegExpMatcher();
+
+                    @Override
+                    protected String compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
+                            UTF8StringPointable replacePtr, UTF8StringPointable flagsPtr) throws IOException {
+                        matcher.build(srcPtr, patternPtr, flagsPtr);
+                        return matcher.replace(replacePtr);
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_REPLACE_WITH_FLAG;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringReplaceDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringReplaceDescriptor.java
deleted file mode 100644
index eec9f41..0000000
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringReplaceDescriptor.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.asterix.runtime.evaluators.functions;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
-import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
-import org.apache.hyracks.api.context.IHyracksTaskContext;
-import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
-import org.apache.hyracks.data.std.util.UTF8CharSequence;
-
-public class StringReplaceDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-
-    private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new StringReplaceDescriptor();
-        }
-    };
-
-    @Override
-    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
-            throws AlgebricksException {
-
-        return new IScalarEvaluatorFactory() {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
-
-                return new AbstractTripleStringStringEval(ctx, args[0], args[1], args[2],
-                        AsterixBuiltinFunctions.STRING_REPLACE) {
-
-                    private Pattern pattern = null;
-                    private Matcher matcher = null;
-                    private String replaceStr;
-                    private StringBuffer resultBuf = new StringBuffer();
-                    private ByteArrayAccessibleOutputStream lastPatternStorage = new ByteArrayAccessibleOutputStream();
-                    private UTF8StringPointable lastPatternPtr = new UTF8StringPointable();
-                    private ByteArrayAccessibleOutputStream lastReplaceStorage = new ByteArrayAccessibleOutputStream();
-                    private UTF8StringPointable lastReplacePtr = new UTF8StringPointable();
-                    private UTF8CharSequence carSeq = new UTF8CharSequence();
-
-                    @Override
-                    protected String compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
-                            UTF8StringPointable replacePtr) throws AlgebricksException {
-                        resultBuf.setLength(0);
-                        final boolean newPattern = (pattern == null || lastPatternPtr.compareTo(patternPtr) != 0);
-                        final boolean newReplace = (pattern == null || lastReplacePtr.compareTo(replacePtr) != 0);
-                        if (newPattern) {
-                            StringEvaluatorUtils.copyResetUTF8Pointable(patternPtr, lastPatternStorage, lastPatternPtr);
-                            // ! object creation !
-                            pattern = Pattern.compile(lastPatternPtr.toString());
-                        }
-                        if (newReplace) {
-                            StringEvaluatorUtils.copyResetUTF8Pointable(replacePtr, lastReplaceStorage, lastReplacePtr);
-                            replaceStr = replacePtr.toString();
-                        }
-
-                        carSeq.reset(srcPtr);
-                        if (newPattern) {
-                            matcher = pattern.matcher(carSeq);
-                        } else {
-                            matcher.reset(carSeq);
-                        }
-
-                        while (matcher.find()) {
-                            matcher.appendReplacement(resultBuf, replaceStr);
-                        }
-                        matcher.appendTail(resultBuf);
-                        return resultBuf.toString();
-                    }
-                };
-            }
-        };
-    }
-
-    @Override
-    public FunctionIdentifier getIdentifier() {
-        return AsterixBuiltinFunctions.STRING_REPLACE;
-    }
-}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringReplaceWithFlagsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringReplaceWithFlagsDescriptor.java
deleted file mode 100644
index a65b437..0000000
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringReplaceWithFlagsDescriptor.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.asterix.runtime.evaluators.functions;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
-import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
-import org.apache.hyracks.api.context.IHyracksTaskContext;
-import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
-import org.apache.hyracks.data.std.util.UTF8CharSequence;
-
-public class StringReplaceWithFlagsDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-
-    private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new StringReplaceWithFlagsDescriptor();
-        }
-    };
-
-    @Override
-    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
-            throws AlgebricksException {
-
-        return new IScalarEvaluatorFactory() {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
-
-                return new AbstractQuadStringStringEval(ctx, args[0], args[1], args[2], args[3],
-                        AsterixBuiltinFunctions.STRING_REPLACE_WITH_FLAG) {
-                    private Pattern pattern = null;
-                    private Matcher matcher = null;
-                    private String replaceStr;
-                    private String flagStr;
-                    private StringBuffer resultBuf = new StringBuffer();
-                    private ByteArrayAccessibleOutputStream lastPatternStorage = new ByteArrayAccessibleOutputStream();
-                    private ByteArrayAccessibleOutputStream lastReplaceStorage = new ByteArrayAccessibleOutputStream();
-                    private ByteArrayAccessibleOutputStream lastFlagStorage = new ByteArrayAccessibleOutputStream();
-                    private UTF8StringPointable lastPatternPtr = new UTF8StringPointable();
-                    private UTF8StringPointable lastReplacePtr = new UTF8StringPointable();
-                    private UTF8StringPointable lastFlagPtr = new UTF8StringPointable();
-                    private UTF8CharSequence carSeq = new UTF8CharSequence();
-
-                    @Override
-                    protected String compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
-                            UTF8StringPointable replacePtr, UTF8StringPointable flagPtr) throws AlgebricksException {
-                        resultBuf.setLength(0);
-                        final boolean newPattern = (pattern == null || lastPatternPtr.compareTo(patternPtr) != 0);
-                        final boolean newReplace = (pattern == null || lastReplacePtr.compareTo(replacePtr) != 0);
-                        final boolean newFlag = (pattern == null || lastFlagPtr.compareTo(flagPtr) != 0);
-
-                        if (newFlag) {
-                            StringEvaluatorUtils.copyResetUTF8Pointable(flagPtr, lastFlagStorage, lastFlagPtr);
-                            flagStr = lastFlagPtr.toString();
-                        }
-                        if (newPattern) {
-                            StringEvaluatorUtils.copyResetUTF8Pointable(patternPtr, lastPatternStorage, lastPatternPtr);
-                        }
-
-                        if (newPattern || newFlag) {
-                            pattern = Pattern.compile(lastPatternPtr.toString(), StringEvaluatorUtils.toFlag(flagStr));
-                        }
-
-                        if (newReplace) {
-                            StringEvaluatorUtils.copyResetUTF8Pointable(replacePtr, lastReplaceStorage, lastReplacePtr);
-                            replaceStr = replacePtr.toString();
-                        }
-
-                        carSeq.reset(srcPtr);
-                        if (newPattern || newFlag) {
-                            matcher = pattern.matcher(carSeq);
-                        } else {
-                            matcher.reset(carSeq);
-                        }
-
-                        while (matcher.find()) {
-                            matcher.appendReplacement(resultBuf, replaceStr);
-                        }
-                        matcher.appendTail(resultBuf);
-                        return resultBuf.toString();
-                    }
-
-                };
-            }
-        };
-    }
-
-    @Override
-    public FunctionIdentifier getIdentifier() {
-        return AsterixBuiltinFunctions.STRING_REPLACE_WITH_FLAG;
-    }
-}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringStartsWithDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringStartsWithDescriptor.java
index c3d80d4..6a3910e 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringStartsWithDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringStartsWithDescriptor.java
@@ -18,6 +18,8 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
+import java.io.IOException;
+
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
@@ -53,8 +55,7 @@
                         AsterixBuiltinFunctions.STRING_STARTS_WITH) {
 
                     @Override
-                    protected boolean compute(UTF8StringPointable left, UTF8StringPointable right)
-                            throws AlgebricksException {
+                    protected boolean compute(UTF8StringPointable left, UTF8StringPointable right) throws IOException {
                         return UTF8StringPointable.startsWith(left, right, false);
                     }
                 };
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrim2Descriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrim2Descriptor.java
new file mode 100644
index 0000000..d2b2d36
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrim2Descriptor.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.StringTrimmer;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringTrim2Descriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringTrim2Descriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_TRIM2;
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractBinaryStringStringEval(ctx, args[0], args[1],
+                        StringTrim2Descriptor.this.getIdentifier()) {
+                    private StringTrimmer stringTrimmer = new StringTrimmer(resultBuilder, resultArray);
+
+                    @Override
+                    protected void compute(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr,
+                            UTF8StringPointable resultStrPtr) throws IOException {
+                        stringTrimmer.build(patternPtr);
+                        stringTrimmer.trim(srcPtr, resultStrPtr, true, true);
+                    }
+                };
+            }
+        };
+    }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrimDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrimDescriptor.java
new file mode 100644
index 0000000..2e5ece0
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrimDescriptor.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.utils.StringTrimmer;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class StringTrimDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new StringTrimDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.STRING_TRIM;
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractUnaryStringStringEval(ctx, args[0], StringTrimDescriptor.this.getIdentifier()) {
+                    private StringTrimmer stringTrimmer = new StringTrimmer(resultBuilder, resultArray, " ");
+
+                    @Override
+                    protected void process(UTF8StringPointable srcPtr, IPointable resultStrPtr) throws IOException {
+                        stringTrimmer.trim(srcPtr, resultStrPtr, true, true);
+                    }
+                };
+            }
+        };
+    }
+
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringUpperCaseDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringUpperCaseDescriptor.java
index 9676b8f..9677f46 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringUpperCaseDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringUpperCaseDescriptor.java
@@ -18,14 +18,11 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
-import java.io.DataOutput;
 import java.io.IOException;
 
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.EnumDeserializer;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -34,11 +31,6 @@
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
-import org.apache.hyracks.data.std.util.GrowableArray;
-import org.apache.hyracks.data.std.util.UTF8StringBuilder;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 public class StringUpperCaseDescriptor extends AbstractScalarFunctionDynamicDescriptor {
     private static final long serialVersionUID = 1L;
@@ -51,49 +43,18 @@
     };
 
     @Override
-    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+    public IScalarEvaluatorFactory createEvaluatorFactory(IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
             private static final long serialVersionUID = 1L;
 
             @Override
-            public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws AlgebricksException {
-                return new IScalarEvaluator() {
-
-                    private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-                    private DataOutput out = resultStorage.getDataOutput();
-                    private IPointable inputArg = new VoidPointable();
-                    private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
-
-                    private final byte stt = ATypeTag.SERIALIZED_STRING_TYPE_TAG;
-
-                    private final GrowableArray array = new GrowableArray();
-                    private final UTF8StringBuilder builder = new UTF8StringBuilder();
-                    private final UTF8StringPointable string = new UTF8StringPointable();
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new AbstractUnaryStringStringEval(ctx, args[0], StringUpperCaseDescriptor.this.getIdentifier()) {
 
                     @Override
-                    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
-                        try {
-                            resultStorage.reset();
-                            eval.evaluate(tuple, inputArg);
-                            byte[] serString = inputArg.getByteArray();
-                            int offset = inputArg.getStartOffset();
-
-                            if (serString[offset] == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                                string.set(serString, offset + 1, serString.length);
-                                array.reset();
-                                UTF8StringPointable.uppercase(string, builder, array);
-
-                                out.writeByte(stt);
-                                out.write(array.getByteArray(), 0, array.getLength());
-                            } else {
-                                throw new AlgebricksException(AsterixBuiltinFunctions.STRING_UPPERCASE.getName()
-                                        + ": expects input type STRING/NULL but got "
-                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serString[offset]));
-                            }
-                            result.set(resultStorage);
-                        } catch (IOException e1) {
-                            throw new AlgebricksException(e1);
-                        }
+                    protected void process(UTF8StringPointable inputString, IPointable resultPointable)
+                            throws IOException {
+                        inputString.uppercase(resultBuilder, resultArray);
                     }
                 };
             }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/RegExpMatcher.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/RegExpMatcher.java
new file mode 100644
index 0000000..9206262
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/RegExpMatcher.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.utils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.asterix.runtime.evaluators.functions.StringEvaluatorUtils;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
+import org.apache.hyracks.data.std.util.UTF8CharSequence;
+
+/**
+ * A wrapper for regular expression processing methods.
+ */
+public class RegExpMatcher {
+
+    // Library regular expression processing objects.
+    private Pattern pattern = null;
+    private Matcher matcher = null;
+
+    // For storing the pattern string.
+    private final ByteArrayAccessibleOutputStream lastPatternStorage = new ByteArrayAccessibleOutputStream();
+    private final UTF8StringPointable lastPatternPtr = new UTF8StringPointable();
+
+    // For storing the flag string.
+    private final ByteArrayAccessibleOutputStream lastFlagsStorage = new ByteArrayAccessibleOutputStream();
+    private final UTF8StringPointable lastFlagPtr = new UTF8StringPointable();
+
+    // The char sequence for the source string.
+    private final UTF8CharSequence charSeq = new UTF8CharSequence();
+
+    //  For storing the replacement string.
+    private final ByteArrayAccessibleOutputStream lastReplaceStorage = new ByteArrayAccessibleOutputStream();
+    private final UTF8StringPointable lastReplaceStrPtr = new UTF8StringPointable();
+    private String replaceStr = null;
+
+    // For storing the string replacement result.
+    private final StringBuffer resultBuf = new StringBuffer();
+
+    @FunctionalInterface
+    public interface IRegExpPatternGenerator {
+        String toRegExpPatternString(String inputString);
+    }
+
+    /**
+     * Builds the matcher.
+     *
+     * @param srcPtr
+     *            , the source string for regular expression operations.
+     * @param patternPtr
+     *            , the definition of the regular expression.
+     */
+    public void build(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr) {
+        build(srcPtr, patternPtr, null);
+    }
+
+    /**
+     * Builds the matcher.
+     *
+     * @param srcPtr
+     *            , the source string for regular expression operations.
+     * @param patternPtr
+     *            , the definition of the regular expression.
+     * @param flagPtr
+     *            , the flags.
+     */
+    public void build(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr, UTF8StringPointable flagPtr) {
+        build(srcPtr, patternPtr, flagPtr, null);
+    }
+
+    /**
+     * Builds the matcher.
+     *
+     * @param srcPtr
+     *            , the source string for regular expression operations.
+     * @param patternPtr
+     *            , the definition of the regular expression.
+     * @param flagPtr
+     *            , the flags.
+     * @param patternGenerator
+     *            , the regular expression pattern generator.
+     */
+    public void build(UTF8StringPointable srcPtr, UTF8StringPointable patternPtr, UTF8StringPointable flagPtr,
+            IRegExpPatternGenerator patternGenerator) {
+        // Builds a new pattern if necessary.
+        final boolean newPattern = patternPtr != null && (pattern == null || lastPatternPtr.compareTo(patternPtr) != 0);
+        final boolean newFlag = flagPtr != null && (pattern == null || lastFlagPtr.compareTo(flagPtr) != 0);
+        if (newPattern) {
+            StringEvaluatorUtils.copyResetUTF8Pointable(patternPtr, lastPatternStorage, lastPatternPtr);
+        }
+        if (newFlag) {
+            StringEvaluatorUtils.copyResetUTF8Pointable(flagPtr, lastFlagsStorage, lastFlagPtr);
+        }
+        if (newPattern || newFlag) {
+            StringEvaluatorUtils.copyResetUTF8Pointable(patternPtr, lastPatternStorage, lastPatternPtr);
+            // ! object creation !
+            String inputPatternString = lastPatternPtr.toString();
+            String patternString = patternGenerator == null ? inputPatternString : patternGenerator
+                    .toRegExpPatternString(inputPatternString);
+            if (newFlag) {
+                pattern = Pattern.compile(patternString, StringEvaluatorUtils.toFlag(flagPtr.toString()));
+
+            } else {
+                pattern = Pattern.compile(patternString);
+            }
+        }
+
+        // Resets the matcher.
+        charSeq.reset(srcPtr);
+        if (newPattern || newFlag) {
+            matcher = pattern.matcher(charSeq);
+        } else {
+            matcher.reset(charSeq);
+        }
+    }
+
+    /**
+     * Whether the source string matches the regular expression defined pattern.
+     *
+     * @return true if it contains the pattern; false otherwise.
+     */
+    public boolean matches() {
+        return matcher.matches();
+    }
+
+    /**
+     * Whether the source string contains the regular expression defined pattern.
+     *
+     * @return true if it contains the pattern; false otherwise.
+     */
+    public boolean find() {
+        return matcher.find();
+    }
+
+    /**
+     * @return the first matched position of the regular expression pattern in the source string.
+     */
+    public int postion() {
+        return matcher.find() ? matcher.start() : -1;
+    }
+
+    /**
+     * Replaces the appearances of a regular expression defined pattern in a source string with a given
+     * replacement string.
+     *
+     * @param replaceStrPtr
+     *            , the string for replacing the regular expression.
+     * @return a new string with contained regular expressions replaced.
+     */
+    public String replace(UTF8StringPointable replaceStrPtr) {
+        // Sets up a new replacement string if necessary.
+        final boolean newReplace = replaceStrPtr != null
+                && (replaceStr == null || lastReplaceStrPtr.compareTo(replaceStrPtr) != 0);
+        if (newReplace) {
+            StringEvaluatorUtils.copyResetUTF8Pointable(replaceStrPtr, lastReplaceStorage, lastReplaceStrPtr);
+            replaceStr = replaceStrPtr.toString();
+        }
+
+        // Does the actual replacement.
+        resultBuf.setLength(0);
+        while (matcher.find()) {
+            matcher.appendReplacement(resultBuf, replaceStr);
+        }
+        matcher.appendTail(resultBuf);
+        return resultBuf.toString();
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/StringTrimmer.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/StringTrimmer.java
new file mode 100644
index 0000000..3e41b1b
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/utils/StringTrimmer.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.utils;
+
+import java.io.IOException;
+
+import org.apache.asterix.runtime.evaluators.functions.StringEvaluatorUtils;
+import org.apache.commons.lang3.CharSet;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+import org.apache.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
+import org.apache.hyracks.data.std.util.GrowableArray;
+import org.apache.hyracks.data.std.util.UTF8StringBuilder;
+
+/**
+ * A wrapper for string trim methods.
+ */
+public class StringTrimmer {
+
+    // For the char set to trim.
+    private final ByteArrayAccessibleOutputStream lastPatternStorage = new ByteArrayAccessibleOutputStream();
+    private final UTF8StringPointable lastPatternPtr = new UTF8StringPointable();
+    private CharSet charSet;
+
+    // For outputting the result.
+    private final UTF8StringBuilder resultBuilder;
+    private final GrowableArray resultArray;
+
+    /**
+     * @param resultBuilder
+     *            , the builder for result strings.
+     * @param resultArray
+     *            , the byte array to hold results.
+     */
+    public StringTrimmer(UTF8StringBuilder resultBuilder, GrowableArray resultArray) {
+        this(resultBuilder, resultArray, null);
+    }
+
+    /**
+     * @param resultBuilder
+     *            , the builder for result strings.
+     * @param resultArray
+     *            , the byte array to hold results.
+     * @param pattern
+     *            , the string that is used to construct the charset for trimming.
+     */
+    public StringTrimmer(UTF8StringBuilder resultBuilder, GrowableArray resultArray, String pattern) {
+        this.resultBuilder = resultBuilder;
+        this.resultArray = resultArray;
+        if (pattern != null) {
+            charSet = CharSet.getInstance(pattern);
+        }
+    }
+
+    /**
+     * Builds the charset from a pattern string.
+     *
+     * @param patternPtr
+     *            , a pattern string.
+     */
+    public void build(UTF8StringPointable patternPtr) {
+        final boolean newPattern = charSet == null || lastPatternPtr.compareTo(patternPtr) != 0;
+        if (newPattern) {
+            StringEvaluatorUtils.copyResetUTF8Pointable(patternPtr, lastPatternStorage, lastPatternPtr);
+            charSet = CharSet.getInstance(patternPtr.toString());
+        }
+    }
+
+    /**
+     * Trims an input source string and lets <code>resultStrPtr</code> points to the resulting string.
+     *
+     * @param srcPtr
+     *            , an input source string.
+     * @param resultStrPtr
+     *            , a pointable that is supposed to point to the resulting string.
+     * @param left
+     *            , whether to trim the left side.
+     * @param right
+     *            , whether to trim the right side.
+     * @throws IOException
+     */
+    public void trim(UTF8StringPointable srcPtr, IPointable resultStrPtr, boolean left, boolean right)
+            throws IOException {
+        UTF8StringPointable.trim(srcPtr, resultBuilder, resultArray, left, right, charSet);
+        resultStrPtr.set(resultArray.getByteArray(), 0, resultArray.getLength());
+    }
+}
diff --git a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/primitive/UTF8StringPointable.java b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/primitive/UTF8StringPointable.java
index 7e834db..8592bd2 100644
--- a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/primitive/UTF8StringPointable.java
+++ b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/primitive/UTF8StringPointable.java
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.nio.charset.Charset;
 
+import org.apache.commons.lang3.CharSet;
 import org.apache.hyracks.api.dataflow.value.ITypeTraits;
 import org.apache.hyracks.data.std.api.AbstractPointable;
 import org.apache.hyracks.data.std.api.IComparable;
@@ -411,6 +412,17 @@
         lowercase(this, builder, out);
     }
 
+    /**
+     * Generates a lower case string of an input string.
+     *
+     * @param src
+     *            , the input source string.
+     * @param builder
+     *            , a builder for the resulting string.
+     * @param out
+     *            , the storage for a result string.
+     * @throws IOException
+     */
     public static void lowercase(UTF8StringPointable src, UTF8StringBuilder builder, GrowableArray out)
             throws IOException {
         final int srcUtfLen = src.getUTF8Length();
@@ -429,6 +441,17 @@
         uppercase(this, builder, out);
     }
 
+    /**
+     * Generates an upper case string of an input string.
+     *
+     * @param src
+     *            , the input source string.
+     * @param builder
+     *            , a builder for the resulting string.
+     * @param out
+     *            , the storage for a result string.
+     * @throws IOException
+     */
     public static void uppercase(UTF8StringPointable src, UTF8StringBuilder builder, GrowableArray out)
             throws IOException {
         final int srcUtfLen = src.getUTF8Length();
@@ -443,4 +466,103 @@
         builder.finish();
     }
 
+    public void initCap(UTF8StringBuilder builder, GrowableArray out) throws IOException {
+        initCap(this, builder, out);
+    }
+
+    /**
+     * Generates a "title" format string from an input source string, i.e., the first letter of each word
+     * is in the upper case while the other letter is in the lower case.
+     *
+     * @param src
+     *            , the input source string.
+     * @param builder
+     *            , a builder for the resulting string.
+     * @param out
+     *            , the storage for a result string.
+     * @throws IOException
+     */
+    public static void initCap(UTF8StringPointable src, UTF8StringBuilder builder, GrowableArray out)
+            throws IOException {
+        final int srcUtfLen = src.getUTF8Length();
+        final int srcStart = src.getMetaDataLength();
+
+        builder.reset(out, srcUtfLen);
+        boolean toUpperCase = true;
+        int byteIndex = 0;
+        while (byteIndex < srcUtfLen) {
+            char originalChar = src.charAt(srcStart + byteIndex);
+            boolean isLetter = Character.isLetter(originalChar);
+
+            // Make the first character into upper case while the later ones into lower case.
+            char resultChar = toUpperCase && isLetter ? Character.toUpperCase(originalChar) : (isLetter ? Character
+                    .toLowerCase(originalChar) : originalChar);
+            builder.appendChar(resultChar);
+            byteIndex += src.charSize(srcStart + byteIndex);
+
+            // Whether the next letter needs to switch to the upper case.
+            toUpperCase = !isLetter;
+        }
+        builder.finish();
+    }
+
+    public void trim(UTF8StringBuilder builder, GrowableArray out, boolean left, boolean right, CharSet charSet)
+            throws IOException {
+        trim(this, builder, out, left, right, charSet);
+    }
+
+    /**
+     * Generates a trimmed string of an input source string.
+     *
+     * @param srcPtr
+     *            , the input source string.
+     * @param builder
+     *            , the result string builder.
+     * @param out
+     *            , the storage for the output string.
+     * @param left
+     *            , whether to trim the left side.
+     * @param right
+     *            , whether to trim the right side.
+     * @param charSet
+     *            , the chars that should be trimmed.
+     * @throws IOException
+     */
+    public static void trim(UTF8StringPointable srcPtr, UTF8StringBuilder builder, GrowableArray out, boolean left,
+            boolean right, CharSet charSet) throws IOException {
+        final int srcUtfLen = srcPtr.getUTF8Length();
+        final int srcStart = srcPtr.getMetaDataLength();
+        // Finds the start Index (inclusive).
+        int startIndex = 0;
+        if (left) {
+            while (startIndex < srcUtfLen) {
+                char ch = srcPtr.charAt(srcStart + startIndex);
+                if (!charSet.contains(ch)) {
+                    break;
+                }
+                startIndex += srcPtr.charSize(srcStart + startIndex);
+            }
+        }
+
+        // Finds the end index (exclusive).
+        int endIndex = srcUtfLen;
+        if (right) {
+            endIndex = startIndex;
+            int cursorIndex = startIndex;
+            while (cursorIndex < srcUtfLen) {
+                char ch = srcPtr.charAt(srcStart + cursorIndex);
+                cursorIndex += srcPtr.charSize(srcStart + cursorIndex);
+                if (!charSet.contains(ch)) {
+                    endIndex = cursorIndex;
+                }
+            }
+        }
+
+        // Outputs the desired substring.
+        int len = endIndex - startIndex;
+        builder.reset(out, len);
+        builder.appendUtf8StringPointable(srcPtr, srcPtr.getStartOffset() + srcStart + startIndex, len);
+        builder.finish();
+    }
+
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/test/java/org/apache/hyracks/data/std/primitive/UTF8StringPointableTest.java b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/test/java/org/apache/hyracks/data/std/primitive/UTF8StringPointableTest.java
index c47cc36..93b2290 100644
--- a/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/test/java/org/apache/hyracks/data/std/primitive/UTF8StringPointableTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/test/java/org/apache/hyracks/data/std/primitive/UTF8StringPointableTest.java
@@ -19,10 +19,12 @@
 
 package org.apache.hyracks.data.std.primitive;
 
+import static org.apache.hyracks.data.std.primitive.UTF8StringPointable.generateUTF8Pointable;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import org.apache.commons.lang3.CharSet;
 import org.apache.hyracks.data.std.util.GrowableArray;
 import org.apache.hyracks.data.std.util.UTF8StringBuilder;
 import org.apache.hyracks.util.string.UTF8StringSample;
@@ -30,21 +32,17 @@
 import org.junit.Test;
 
 public class UTF8StringPointableTest {
-    public static UTF8StringPointable STRING_EMPTY = UTF8StringPointable
-            .generateUTF8Pointable(UTF8StringSample.EMPTY_STRING);
-    public static UTF8StringPointable STRING_UTF8_MIX = UTF8StringPointable
-            .generateUTF8Pointable(UTF8StringSample.STRING_UTF8_MIX);
-    public static UTF8StringPointable STRING_UTF8_MIX_LOWERCASE = UTF8StringPointable.generateUTF8Pointable(
+    public static UTF8StringPointable STRING_EMPTY = generateUTF8Pointable(UTF8StringSample.EMPTY_STRING);
+    public static UTF8StringPointable STRING_UTF8_MIX = generateUTF8Pointable(UTF8StringSample.STRING_UTF8_MIX);
+    public static UTF8StringPointable STRING_UTF8_MIX_LOWERCASE = generateUTF8Pointable(
             UTF8StringSample.STRING_UTF8_MIX_LOWERCASE);
 
-    public static UTF8StringPointable STRING_LEN_127 = UTF8StringPointable
-            .generateUTF8Pointable(UTF8StringSample.STRING_LEN_127);
-    public static UTF8StringPointable STRING_LEN_128 = UTF8StringPointable
-            .generateUTF8Pointable(UTF8StringSample.STRING_LEN_128);
+    public static UTF8StringPointable STRING_LEN_127 = generateUTF8Pointable(UTF8StringSample.STRING_LEN_127);
+    public static UTF8StringPointable STRING_LEN_128 = generateUTF8Pointable(UTF8StringSample.STRING_LEN_128);
 
     @Test
     public void testGetStringLength() throws Exception {
-        UTF8StringPointable utf8Ptr = UTF8StringPointable.generateUTF8Pointable(UTF8StringSample.STRING_LEN_127);
+        UTF8StringPointable utf8Ptr = generateUTF8Pointable(UTF8StringSample.STRING_LEN_127);
         assertEquals(127, utf8Ptr.getUTF8Length());
         assertEquals(1, utf8Ptr.getMetaDataLength());
         assertEquals(127, utf8Ptr.getStringLength());
@@ -84,7 +82,7 @@
 
     @Test
     public void testConcat() throws Exception {
-        UTF8StringPointable expected = UTF8StringPointable.generateUTF8Pointable(
+        UTF8StringPointable expected = generateUTF8Pointable(
                 UTF8StringSample.generateStringRepeatBy(UTF8StringSample.ONE_ASCII_CHAR, 127 + 128));
 
         GrowableArray storage = new GrowableArray();
@@ -132,9 +130,9 @@
         assertEquals(0, STRING_EMPTY.compareTo(result));
 
         storage.reset();
-        UTF8StringPointable testPtr = UTF8StringPointable.generateUTF8Pointable("Mix中文123");
-        UTF8StringPointable pattern = UTF8StringPointable.generateUTF8Pointable("文");
-        UTF8StringPointable expect = UTF8StringPointable.generateUTF8Pointable("Mix中");
+        UTF8StringPointable testPtr = generateUTF8Pointable("Mix中文123");
+        UTF8StringPointable pattern = generateUTF8Pointable("文");
+        UTF8StringPointable expect = generateUTF8Pointable("Mix中");
         testPtr.substrBefore(pattern, builder, storage);
         result.set(storage.getByteArray(), 0, storage.getLength());
         assertEquals(0, expect.compareTo(result));
@@ -149,14 +147,13 @@
         UTF8StringPointable result = new UTF8StringPointable();
         result.set(storage.getByteArray(), 0, storage.getLength());
 
-        UTF8StringPointable expect = UTF8StringPointable
-                .generateUTF8Pointable(Character.toString(UTF8StringSample.ONE_ASCII_CHAR));
+        UTF8StringPointable expect = generateUTF8Pointable(Character.toString(UTF8StringSample.ONE_ASCII_CHAR));
         assertEquals(0, expect.compareTo(result));
 
         storage.reset();
-        UTF8StringPointable testPtr = UTF8StringPointable.generateUTF8Pointable("Mix中文123");
-        UTF8StringPointable pattern = UTF8StringPointable.generateUTF8Pointable("文");
-        expect = UTF8StringPointable.generateUTF8Pointable("123");
+        UTF8StringPointable testPtr = generateUTF8Pointable("Mix中文123");
+        UTF8StringPointable pattern = generateUTF8Pointable("文");
+        expect = generateUTF8Pointable("123");
         testPtr.substrAfter(pattern, builder, storage);
         result.set(storage.getByteArray(), 0, storage.getLength());
         assertEquals(0, expect.compareTo(result));
@@ -185,9 +182,79 @@
 
         result.set(storage.getByteArray(), 0, storage.getLength());
 
-        UTF8StringPointable expected = UTF8StringPointable
-                .generateUTF8Pointable(UTF8StringSample.STRING_UTF8_MIX_LOWERCASE.toUpperCase());
+        UTF8StringPointable expected = generateUTF8Pointable(UTF8StringSample.STRING_UTF8_MIX_LOWERCASE.toUpperCase());
+        assertEquals(0, expected.compareTo(result));
+    }
+
+    @Test
+    public void testInitCap() throws Exception {
+        UTF8StringBuilder builder = new UTF8StringBuilder();
+        GrowableArray storage = new GrowableArray();
+
+        UTF8StringPointable result = new UTF8StringPointable();
+        UTF8StringPointable input = generateUTF8Pointable("this is it.i am;here.");
+        input.initCap(builder, storage);
+
+        result.set(storage.getByteArray(), 0, storage.getLength());
+
+        UTF8StringPointable expected = generateUTF8Pointable("This Is It.I Am;Here.");
+        assertEquals(0, expected.compareTo(result));
+    }
+
+    @Test
+    public void testTrim() throws Exception {
+        UTF8StringBuilder builder = new UTF8StringBuilder();
+        GrowableArray storage = new GrowableArray();
+        UTF8StringPointable result = new UTF8StringPointable();
+        UTF8StringPointable input = generateUTF8Pointable("  this is it.i am;here.  ");
+
+        // Trims both sides.
+        input.trim(builder, storage, true, true, CharSet.getInstance(" "));
+        result.set(storage.getByteArray(), 0, storage.getLength());
+        UTF8StringPointable expected = generateUTF8Pointable("this is it.i am;here.");
         assertEquals(0, expected.compareTo(result));
 
+        // Only trims the right side.
+        storage.reset();
+        input.trim(builder, storage, false, true, CharSet.getInstance(" "));
+        result.set(storage.getByteArray(), 0, storage.getLength());
+        expected = generateUTF8Pointable("  this is it.i am;here.");
+        assertEquals(0, expected.compareTo(result));
+
+        // Only trims the left side.
+        storage.reset();
+        input.trim(builder, storage, true, false, CharSet.getInstance(" "));
+        result.set(storage.getByteArray(), 0, storage.getLength());
+        expected = generateUTF8Pointable("this is it.i am;here.  ");
+        assertEquals(0, expected.compareTo(result));
     }
+
+    @Test
+    public void testTrimWithPattern() throws Exception {
+        UTF8StringBuilder builder = new UTF8StringBuilder();
+        GrowableArray storage = new GrowableArray();
+        UTF8StringPointable result = new UTF8StringPointable();
+        UTF8StringPointable input = generateUTF8Pointable("  this is it.i am;here.  ");
+
+        // Trims both sides.
+        input.trim(builder, storage, true, true, CharSet.getInstance(" hert."));
+        result.set(storage.getByteArray(), 0, storage.getLength());
+        UTF8StringPointable expected = generateUTF8Pointable("is is it.i am;");
+        assertEquals(0, expected.compareTo(result));
+
+        // Only trims the right side.
+        storage.reset();
+        input.trim(builder, storage, false, true, CharSet.getInstance(" hert."));
+        result.set(storage.getByteArray(), 0, storage.getLength());
+        expected = generateUTF8Pointable("  this is it.i am;");
+        assertEquals(0, expected.compareTo(result));
+
+        // Only trims the left side.
+        storage.reset();
+        input.trim(builder, storage, true, false, CharSet.getInstance(" hert."));
+        result.set(storage.getByteArray(), 0, storage.getLength());
+        expected = generateUTF8Pointable("is is it.i am;here.  ");
+        assertEquals(0, expected.compareTo(result));
+    }
+
 }