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>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<ASC: "asc">
-| <AT: "at">
-| <BY: "by">
-| <DATASET: "dataset">
-| <DECOR: "decor">
-| <DESC: "desc">
-| <DISTINCT: "distinct">
-| <ELSE: "else">
-| <EVERY: "every">
-| <FOR: "for">
-| <FROM: "from">
-| <GROUP: "group">
-| <IF: "if">
-| <IN: "in">
-| <LET: "let">
-| <LIMIT: "limit">
-| <OFFSET: "offset">
-| <ORDER: "order">
-| <RETURN: "return">
-| <SATISFIES: "satisfies">
-| <SELECT: "select">
-| <SOME: "some">
-| <THEN: "then">
-| <UNION: "union">
-| <WHERE: "where">
-| <WITH: "with">
-| <KEEPING: "keeping">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<CARET: "^">
-| <DIV: "/">
-| <IDIV: "idiv">
-| <MINUS: "-">
-| <MOD: "%">
-| <MUL: "*">
-| <PLUS: "+">
-| <LEFTPAREN: "(">
-| <RIGHTPAREN: ")">
-| <LEFTBRACKET: "[">
-| <RIGHTBRACKET: "]">
-| <COLON: ":">
-| <COMMA: ",">
-| <DOT: ".">
-| <QUES: "?">
-| <LT: "<">
-| <GT: ">">
-| <LE: "<=">
-| <GE: ">=">
-| <EQ: "=">
-| <NE: "!=">
-| <SIMILAR: "~=">
-| <ASSIGN: ":=">
-| <AND: "and">
-| <OR: "or">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<LEFTBRACE: "{"> : DEFAULT
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT> TOKEN : {
-<RIGHTBRACE: "}"> : {
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<LEFTDBLBRACE: "{{"> : IN_DBL_BRACE
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<IN_DBL_BRACE> TOKEN : {
-<RIGHTDBLBRACE: "}}"> : {
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<INTEGER_LITERAL: (<DIGIT>)+>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<NULL: "null">
-| <TRUE: "true">
-| <FALSE: "false">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<#DIGIT: ["0"-"9"]>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<DOUBLE_LITERAL: <DIGITS> | <DIGITS> ("." <DIGITS>)? | "." <DIGITS>>
-| <FLOAT_LITERAL: <DIGITS> ("f" | "F") | <DIGITS> ("." <DIGITS> ("f" | "F"))? | "." <DIGITS> ("f" | "F")>
-| <DIGITS: (<DIGIT>)+>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<#LETTER: ["A"-"Z","a"-"z"]>
-| <SPECIALCHARS: ["$","_","-"]>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<STRING_LITERAL: "\"" (<EscapeQuot> | <EscapeBslash> | <EscapeSlash> | <EscapeBspace> | <EscapeFormf> | <EscapeNl> | <EscapeCr> | <EscapeTab> | ~["\"","\\"])* "\"" | "\'" (<EscapeApos> | <EscapeBslash> | <EscapeSlash> | <EscapeBspace> | <EscapeFormf> | <EscapeNl> | <EscapeCr> | <EscapeTab> | ~["\'","\\"])* "\'">
-| <#EscapeQuot: "\\\"">
-| <#EscapeApos: "\\\'">
-| <#EscapeBslash: "\\\\">
-| <#EscapeSlash: "\\/">
-| <#EscapeBspace: "\\b">
-| <#EscapeFormf: "\\f">
-| <#EscapeNl: "\\n">
-| <#EscapeCr: "\\r">
-| <#EscapeTab: "\\t">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<IDENTIFIER: <LETTER> (<LETTER> | <DIGIT> | <SPECIALCHARS>)*>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<VARIABLE: "$" <LETTER> (<LETTER> | <DIGIT> | "_")*>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> SKIP : {
-" "
-| "\t"
-| "\r"
-| "\n"
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> SKIP : {
-<"//" (~["\n"])* "\n">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> SKIP : {
-<"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")?>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> SKIP : {
-"/*" : INSIDE_COMMENT
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<INSIDE_COMMENT> SPECIAL : {
-<"+" (" ")* (~["*"])*>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<INSIDE_COMMENT> SKIP : {
-"/*" : {
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<INSIDE_COMMENT> SKIP : {
-"*/" : {
-| <~[]>
-}
-
- </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> ( ";" )? )* <EOF></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> ( <COMMA> <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" <DATASET> <A HREF="#prod30">QualifiedName</A> <LEFTPAREN> <A HREF="#prod27">TypeName</A> <RIGHTPAREN> <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" )? <DATASET> <A HREF="#prod30">QualifiedName</A> <LEFTPAREN> <A HREF="#prod27">TypeName</A> <RIGHTPAREN> ( <WITH> <A HREF="#prod18">Identifier</A> <LEFTPAREN> <A HREF="#prod27">TypeName</A> <RIGHTPAREN> )? <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" <DATASET> <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> <LEFTPAREN> ( <A HREF="#prod18">Identifier</A> ( <COMMA> )? )* <RIGHTPAREN> <FROM> <DATASET> <A HREF="#prod30">QualifiedName</A> "to" <DATASET> <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> <LEFTPAREN> ( <A HREF="#prod37">OpenField</A> ) ( <COMMA> <A HREF="#prod37">OpenField</A> )* <RIGHTPAREN> ( "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" <LEFTPAREN> <INTEGER_LITERAL> <RIGHTPAREN> )</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> <LEFTBRACE> <A HREF="#prod43">Expression</A> <RIGHTBRACE></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> <FROM> "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> <FROM> ( "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><LEFTPAREN> ( <VARIABLE> ( <COMMA> <VARIABLE> )* )? <RIGHTPAREN></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> "@" <INTEGER_LITERAL></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> ( <COMMA> <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" ( <DATASET> <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>( <IF> "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" <DATASET> <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> <FROM> <DATASET> <A HREF="#prod30">QualifiedName</A> ( <WHERE> <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> <IN> <A HREF="#prod43">Expression</A> <WHERE> <A HREF="#prod43">Expression</A> <LEFTPAREN> ( <A HREF="#prod50">UpdateClause</A> ( <COMMA> <A HREF="#prod50">UpdateClause</A> )* ) <RIGHTPAREN></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> <ASSIGN> <A HREF="#prod43">Expression</A> | <A HREF="#prod10">InsertStatement</A> | <A HREF="#prod11">DeleteStatement</A> | <A HREF="#prod12">UpdateStatement</A> | <IF> <LEFTPAREN> <A HREF="#prod43">Expression</A> <RIGHTPAREN> <THEN> <A HREF="#prod50">UpdateClause</A> ( <ELSE> <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> <COLON> <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" <DATASET> <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" <DATASET> <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" <DATASET> <A HREF="#prod30">QualifiedName</A> ( <A HREF="#prod45">GetPolicy</A> )? | "disconnect" "feed" <A HREF="#prod30">QualifiedName</A> <FROM> <DATASET> <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><LEFTPAREN> ( <A HREF="#prod51">KeyValuePair</A> ( <COMMA> <A HREF="#prod51">KeyValuePair</A> )* )? <RIGHTPAREN></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><LEFTPAREN> <A HREF="#prod40">StringLiteral</A> <EQ> <A HREF="#prod40">StringLiteral</A> <RIGHTPAREN></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>( <LEFTPAREN> <A HREF="#prod52">Property</A> ( <COMMA> <A HREF="#prod52">Property</A> )* <RIGHTPAREN> )?</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> <EQ> ( <A HREF="#prod40">StringLiteral</A> | <INTEGER_LITERAL> )</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" )? <LEFTBRACE> ( <A HREF="#prod58">RecordField</A> ( <COMMA> <A HREF="#prod58">RecordField</A> )* )? <RIGHTBRACE></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> <COLON> <A HREF="#prod29">TypeExpr</A> ( <QUES> )?</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><LEFTBRACKET> ( <A HREF="#prod29">TypeExpr</A> ) <RIGHTBRACKET></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><LEFTDBLBRACE> ( <A HREF="#prod29">TypeExpr</A> ) <RIGHTDBLBRACE></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> ( <DOT> <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>( <IDENTIFIER> | <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> ( <COLON> <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> ( <LEFTPAREN> <RIGHTPAREN> )? ( <DOT> <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><STRING_LITERAL></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> ( <DOT> <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> <DOT> <A HREF="#prod18">Identifier</A> ( <DOT> <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> <LEFTBRACE> <A HREF="#prod43">Expression</A> <RIGHTBRACE></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> ( <OR> <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> ( <AND> <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> | <GT> | <LE> | <GE> | <EQ> | <NE> | <SIMILAR> ) <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> ( ( <PLUS> | <MINUS> ) <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> ( ( <MUL> | <DIV> | <MOD> | <CARET> | <IDIV> ) <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> ( <UNION> ( <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>( ( <PLUS> | <MINUS> ) )? <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><DOT> <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><LEFTBRACKET> ( <A HREF="#prod43">Expression</A> | <QUES> ) <RIGHTBRACKET></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> | <INTEGER_LITERAL> | <FLOAT_LITERAL> | <DOUBLE_LITERAL> | <NULL> | <TRUE> | <FALSE> )</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><VARIABLE></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><VARIABLE></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><LEFTBRACKET> <A HREF="#prod82">ExpressionList</A> <RIGHTBRACKET></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><LEFTDBLBRACE> <A HREF="#prod82">ExpressionList</A> <RIGHTDBLBRACE></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> ( <COMMA> <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><COMMA></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><LEFTBRACE> ( <A HREF="#prod84">FieldBinding</A> ( <COMMA> <A HREF="#prod84">FieldBinding</A> )* )? <RIGHTBRACE></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> <COLON> <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> <LEFTPAREN> ( <A HREF="#prod43">Expression</A> ( <COMMA> <A HREF="#prod43">Expression</A> )* )? <RIGHTPAREN></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><DATASET> ( ( <A HREF="#prod18">Identifier</A> ( <DOT> <A HREF="#prod18">Identifier</A> )? ) | ( <LEFTPAREN> <A HREF="#prod43">Expression</A> <RIGHTPAREN> ) )</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><LEFTPAREN> <A HREF="#prod43">Expression</A> <RIGHTPAREN></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><IF> <LEFTPAREN> <A HREF="#prod43">Expression</A> <RIGHTPAREN> <THEN> <A HREF="#prod43">Expression</A> <ELSE> <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> )* ( <RETURN> | <SELECT> ) <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>( <FOR> | <FROM> ) <A HREF="#prod49">Variable</A> ( <AT> <A HREF="#prod49">Variable</A> )? <IN> ( <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>( <LET> | <WITH> ) <A HREF="#prod49">Variable</A> <ASSIGN> <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><WHERE> <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>( <ORDER> <BY> <A HREF="#prod43">Expression</A> ( ( <ASC> ) | ( <DESC> ) )? ( <COMMA> <A HREF="#prod43">Expression</A> ( ( <ASC> ) | ( <DESC> ) )? )* )</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><GROUP> <BY> ( <A HREF="#prod49">Variable</A> <ASSIGN> )? <A HREF="#prod43">Expression</A> ( <COMMA> ( <A HREF="#prod49">Variable</A> <ASSIGN> )? <A HREF="#prod43">Expression</A> )* ( <DECOR> <A HREF="#prod49">Variable</A> <ASSIGN> <A HREF="#prod43">Expression</A> ( <COMMA> <DECOR> <A HREF="#prod49">Variable</A> <ASSIGN> <A HREF="#prod43">Expression</A> )* )? ( <WITH> | <KEEPING> ) <A HREF="#prod76">VariableRef</A> ( <COMMA> <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><LIMIT> <A HREF="#prod43">Expression</A> ( <OFFSET> <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><DISTINCT> <BY> <A HREF="#prod43">Expression</A> ( <COMMA> <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>( ( <SOME> ) | ( <EVERY> ) ) <A HREF="#prod49">Variable</A> <IN> <A HREF="#prod43">Expression</A> ( <COMMA> <A HREF="#prod49">Variable</A> <IN> <A HREF="#prod43">Expression</A> )* <SATISFIES> <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>
-<DEFAULT,IN_DBL_BRACE> TOKEN [IGNORE_CASE] : {
-<ALL: "all">
-| <AND: "and">
-| <APPLY: "apply">
-| <AS: "as">
-| <ASC: "asc">
-| <AT: "at">
-| <AUTOGENERATED: "autogenerated">
-| <BETWEEN: "between">
-| <BTREE: "btree">
-| <BY: "by">
-| <CASE: "case">
-| <CLOSED: "closed">
-| <CREATE: "create">
-| <COMPACTION: "compaction">
-| <COMPACT: "compact">
-| <CONNECT: "connect">
-| <CORRELATE: "correlate">
-| <DATASET: "table">
-| <COLLECTION: "collection">
-| <DATAVERSE: "database">
-| <DECLARE: "declare">
-| <DEFINITION: "definition">
-| <DELETE: "delete">
-| <DESC: "desc">
-| <DISCONNECT: "disconnect">
-| <DISTINCT: "distinct">
-| <DROP: "drop">
-| <ELEMENT: "element">
-| <ELSE: "else">
-| <ENFORCED: "enforced">
-| <END: "end">
-| <EVERY: "every">
-| <EXCEPT: "except">
-| <EXISTS: "exists">
-| <EXTERNAL: "external">
-| <FEED: "feed">
-| <FILTER: "filter">
-| <FLATTEN: "flatten">
-| <FOR: "for">
-| <FORMAT: "format">
-| <FROM: "from">
-| <FULL: "full">
-| <FUNCTION: "function">
-| <GROUP: "group">
-| <HAVING: "having">
-| <HINTS: "hints">
-| <IF: "if">
-| <INTO: "into">
-| <IN: "in">
-| <INDEX: "index">
-| <INGESTION: "ingestion">
-| <INNER: "inner">
-| <INSERT: "insert">
-| <INTERNAL: "internal">
-| <INTERSECT: "intersect">
-| <IS: "is">
-| <JOIN: "join">
-| <KEYWORD: "keyword">
-| <KEY: "key">
-| <LEFT: "left">
-| <LETTING: "letting">
-| <LET: "let">
-| <LIKE: "like">
-| <LIMIT: "limit">
-| <LOAD: "load">
-| <NODEGROUP: "nodegroup">
-| <NGRAM: "ngram">
-| <NOT: "not">
-| <OFFSET: "offset">
-| <ON: "on">
-| <OPEN: "open">
-| <OR: "or">
-| <ORDER: "order">
-| <OUTER: "outer">
-| <OUTPUT: "output">
-| <PATH: "path">
-| <POLICY: "policy">
-| <PRESORTED: "pre-sorted">
-| <PRIMARY: "primary">
-| <RAW: "raw">
-| <REFRESH: "refresh">
-| <RETURN: "return">
-| <RTREE: "rtree">
-| <RUN: "run">
-| <SATISFIES: "satisfies">
-| <SECONDARY: "secondary">
-| <SELECT: "select">
-| <SET: "set">
-| <SOME: "some">
-| <TEMPORARY: "temporary">
-| <THEN: "then">
-| <TYPE: "type">
-| <TO: "to">
-| <UNION: "union">
-| <UNKOWN: "unknown">
-| <UNNEST: "unnest">
-| <UPDATE: "update">
-| <USE: "use">
-| <USING: "using">
-| <VALUE: "value">
-| <WHEN: "when">
-| <WHERE: "where">
-| <WITH: "with">
-| <WRITE: "write">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<CARET: "^">
-| <DIV: "/">
-| <IDIV: "idiv">
-| <MINUS: "-">
-| <MOD: "%">
-| <MUL: "*">
-| <PLUS: "+">
-| <LEFTPAREN: "(">
-| <RIGHTPAREN: ")">
-| <LEFTBRACKET: "[">
-| <RIGHTBRACKET: "]">
-| <ATT: "@">
-| <COLON: ":">
-| <COMMA: ",">
-| <DOT: ".">
-| <QUES: "?">
-| <SEMICOLON: ";">
-| <SHARP: "#">
-| <LT: "<">
-| <GT: ">">
-| <LE: "<=">
-| <GE: ">=">
-| <EQ: "=">
-| <NE: "!=">
-| <SIMILAR: "~=">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<LEFTBRACE: "{"> : DEFAULT
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT> TOKEN : {
-<RIGHTBRACE: "}"> : {
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<LEFTDBLBRACE: "{{"> : IN_DBL_BRACE
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<IN_DBL_BRACE> TOKEN : {
-<RIGHTDBLBRACE: "}}"> : {
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<INTEGER_LITERAL: (<DIGIT>)+>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN [IGNORE_CASE] : {
-<MISSING: "missing">
-| <NULL: "null">
-| <TRUE: "true">
-| <FALSE: "false">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<#DIGIT: ["0"-"9"]>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<DOUBLE_LITERAL: <DIGITS> | <DIGITS> ("." <DIGITS>)? | "." <DIGITS>>
-| <FLOAT_LITERAL: <DIGITS> ("f" | "F") | <DIGITS> ("." <DIGITS> ("f" | "F"))? | "." <DIGITS> ("f" | "F")>
-| <DIGITS: (<DIGIT>)+>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<#LETTER: ["A"-"Z","a"-"z"]>
-| <SPECIALCHARS: ["$","_"]>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<QUOTED_STRING: "`" (<EscapeQuot> | <EscapeBslash> | <EscapeSlash> | <EscapeBspace> | <EscapeFormf> | <EscapeNl> | <EscapeCr> | <EscapeTab> | ~["`","\\"])* "`">
-| <STRING_LITERAL: "\"" (<EscapeQuot> | <EscapeBslash> | <EscapeSlash> | <EscapeBspace> | <EscapeFormf> | <EscapeNl> | <EscapeCr> | <EscapeTab> | ~["\"","\\"])* "\"" | "\'" (<EscapeApos> | <EscapeBslash> | <EscapeSlash> | <EscapeBspace> | <EscapeFormf> | <EscapeNl> | <EscapeCr> | <EscapeTab> | ~["\'","\\"])* "\'">
-| <#EscapeQuot: "\\\"">
-| <#EscapeApos: "\\\'">
-| <#EscapeBslash: "\\\\">
-| <#EscapeSlash: "\\/">
-| <#EscapeBspace: "\\b">
-| <#EscapeFormf: "\\f">
-| <#EscapeNl: "\\n">
-| <#EscapeCr: "\\r">
-| <#EscapeTab: "\\t">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> TOKEN : {
-<IDENTIFIER: <LETTER> (<LETTER> | <DIGIT> | <SPECIALCHARS>)*>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> SKIP : {
-" "
-| "\t"
-| "\r"
-| "\n"
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> SKIP : {
-<"//" (~["\n"])* "\n">
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> SKIP : {
-<"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")?>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<DEFAULT,IN_DBL_BRACE> SKIP : {
-"/*" : INSIDE_COMMENT
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<INSIDE_COMMENT> SPECIAL : {
-<"+" (" ")* (~["*"])*>
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<INSIDE_COMMENT> SKIP : {
-"/*" : {
-}
-
- </PRE>
- </TD>
- </TR>
- <!-- Token -->
- <TR>
- <TD>
- <PRE>
-<INSIDE_COMMENT> SKIP : {
-"*/" : {
-| <~[]>
-}
-
- </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> ( <SEMICOLON> )* )* <EOF></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> <SEMICOLON> | <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> <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> ( <COMMA> <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> <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> <LEFTPAREN> <A HREF="#prod27">TypeName</A> <RIGHTPAREN> <A HREF="#prod28">IfNotExists</A> <USING> <A HREF="#prod32">AdapterName</A> <A HREF="#prod33">Configuration</A> ( <ON> <A HREF="#prod18">Identifier</A> )? ( <HINTS> <A HREF="#prod34">Properties</A> )? ( <USING> <COMPACTION> <POLICY> <A HREF="#prod35">CompactionPolicy</A> ( <A HREF="#prod33">Configuration</A> )? )? | ( <INTERNAL> | <TEMPORARY> )? <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> <LEFTPAREN> <A HREF="#prod27">TypeName</A> <RIGHTPAREN> ( <WITH> <A HREF="#prod18">Identifier</A> <LEFTPAREN> <A HREF="#prod27">TypeName</A> <RIGHTPAREN> )? <A HREF="#prod28">IfNotExists</A> <A HREF="#prod36">PrimaryKey</A> ( <AUTOGENERATED> )? ( <ON> <A HREF="#prod18">Identifier</A> )? ( <HINTS> <A HREF="#prod34">Properties</A> )? ( <USING> <COMPACTION> <POLICY> <A HREF="#prod35">CompactionPolicy</A> ( <A HREF="#prod33">Configuration</A> )? )? ( <WITH> <FILTER> <ON> <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><REFRESH> <EXTERNAL> <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><RUN> <A HREF="#prod18">Identifier</A> <LEFTPAREN> ( <A HREF="#prod18">Identifier</A> ( <COMMA> )? )* <RIGHTPAREN> <FROM> <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> <TO> <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><INDEX> <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> <ON> <A HREF="#prod31">QualifiedName</A> <LEFTPAREN> ( <A HREF="#prod38">OpenField</A> ) ( <COMMA> <A HREF="#prod38">OpenField</A> )* <RIGHTPAREN> ( <TYPE> <A HREF="#prod39">IndexType</A> )? ( <ENFORCED> )?</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>( <BTREE> | <RTREE> | <KEYWORD> | <NGRAM> <LEFTPAREN> <INTEGER_LITERAL> <RIGHTPAREN> )</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="#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><FUNCTION> <A HREF="#prod42">FunctionName</A> <A HREF="#prod28">IfNotExists</A> <A HREF="#prod43">ParameterList</A> <LEFTBRACE> <A HREF="#prod44">Expression</A> <RIGHTBRACE></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="#prod31">QualifiedName</A> <A HREF="#prod28">IfNotExists</A> <FROM> <FEED> <A HREF="#prod31">QualifiedName</A> ( <A HREF="#prod45">ApplyFunction</A> )? | ( <PRIMARY> )? <FEED> <A HREF="#prod31">QualifiedName</A> <A HREF="#prod28">IfNotExists</A> <USING> <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>( <INGESTION> <POLICY> <A HREF="#prod18">Identifier</A> <A HREF="#prod28">IfNotExists</A> <FROM> ( <POLICY> <A HREF="#prod18">Identifier</A> <A HREF="#prod33">Configuration</A> ( <DEFINITION> <A HREF="#prod41">ConstantString</A> )? | <PATH> <A HREF="#prod18">Identifier</A> ( <DEFINITION> <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><LEFTPAREN> ( <IDENTIFIER> ( <COMMA> <IDENTIFIER> )* )? <RIGHTPAREN></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="prod45">ApplyFunction</A></TD>
-<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><APPLY> <FUNCTION> <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><USING> <POLICY> <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> <ATT> <INTEGER_LITERAL></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><PRIMARY> <KEY> <A HREF="#prod37">NestedField</A> ( <COMMA> <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><DROP> ( <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> <A HREF="#prod48">IfExists</A> | <INDEX> <A HREF="#prod49">DoubleQualifiedName</A> <A HREF="#prod48">IfExists</A> | <NODEGROUP> <A HREF="#prod18">Identifier</A> <A HREF="#prod48">IfExists</A> | <TYPE> <A HREF="#prod27">TypeName</A> <A HREF="#prod48">IfExists</A> | <DATAVERSE> <A HREF="#prod18">Identifier</A> <A HREF="#prod48">IfExists</A> | <FUNCTION> <A HREF="#prod47">FunctionSignature</A> <A HREF="#prod48">IfExists</A> | <FEED> <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>( <IF> <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> <INTO> <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><DELETE> <FROM> <A HREF="#prod31">QualifiedName</A> ( ( <AS> )? <A HREF="#prod50">Variable</A> )? ( <WHERE> <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><UPDATE> <A HREF="#prod50">Variable</A> <IN> <A HREF="#prod44">Expression</A> <WHERE> <A HREF="#prod44">Expression</A> <LEFTPAREN> ( <A HREF="#prod51">UpdateClause</A> ( <COMMA> <A HREF="#prod51">UpdateClause</A> )* ) <RIGHTPAREN></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>( <SET> <A HREF="#prod44">Expression</A> <EQ> <A HREF="#prod44">Expression</A> | <A HREF="#prod10">InsertStatement</A> | <A HREF="#prod11">DeleteStatement</A> | <A HREF="#prod12">UpdateStatement</A> | <IF> <LEFTPAREN> <A HREF="#prod44">Expression</A> <RIGHTPAREN> <THEN> <A HREF="#prod51">UpdateClause</A> ( <ELSE> <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><SET> <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><WRITE> <OUTPUT> <TO> <A HREF="#prod18">Identifier</A> <COLON> <A HREF="#prod41">ConstantString</A> ( <USING> <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><LOAD> <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> <USING> <A HREF="#prod32">AdapterName</A> <A HREF="#prod33">Configuration</A> ( <PRESORTED> )?</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><COMPACT> <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>( <CONNECT> <FEED> <A HREF="#prod31">QualifiedName</A> <TO> <A HREF="#prod30">Dataset</A> <A HREF="#prod31">QualifiedName</A> ( <A HREF="#prod46">GetPolicy</A> )? | <DISCONNECT> <FEED> <A HREF="#prod31">QualifiedName</A> <FROM> <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><LEFTPAREN> ( <A HREF="#prod52">KeyValuePair</A> ( <COMMA> <A HREF="#prod52">KeyValuePair</A> )* )? <RIGHTPAREN></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><LEFTPAREN> <A HREF="#prod41">ConstantString</A> <EQ> <A HREF="#prod41">ConstantString</A> <RIGHTPAREN></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>( <LEFTPAREN> <A HREF="#prod53">Property</A> ( <COMMA> <A HREF="#prod53">Property</A> )* <RIGHTPAREN> )?</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> ) <EQ> ( <A HREF="#prod41">ConstantString</A> | <INTEGER_LITERAL> )</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>( <CLOSED> | <OPEN> )? <LEFTBRACE> ( <A HREF="#prod60">RecordField</A> ( <COMMA> <A HREF="#prod60">RecordField</A> )* )? <RIGHTBRACE></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> <COLON> <A HREF="#prod29">TypeExpr</A> ( <QUES> )?</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><LEFTBRACKET> ( <A HREF="#prod29">TypeExpr</A> ) <RIGHTBRACKET></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><LEFTDBLBRACE> ( <A HREF="#prod29">TypeExpr</A> ) <RIGHTDBLBRACE></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> ( <DOT> <A HREF="#prod18">Identifier</A> ( <SHARP> <A HREF="#prod18">Identifier</A> )? | <SHARP> <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>( <IDENTIFIER> | <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>( <DATASET> | <COLLECTION> )</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> ( <COLON> <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> ( <LEFTPAREN> <RIGHTPAREN> )? ( <DOT> <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><QUOTED_STRING></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><STRING_LITERAL></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> ( <DOT> <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> <DOT> <A HREF="#prod18">Identifier</A> ( <DOT> <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="#prod43">ParameterList</A> <LEFTBRACE> <A HREF="#prod44">Expression</A> <RIGHTBRACE></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> ( <OR> <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> ( <AND> <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>( <NOT> )? <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> | <GT> | <LE> | <GE> | <EQ> | <NE> | <SIMILAR> | ( <NOT> )? ( <LIKE> | <IN> ) ) <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> ( <IS> ( <NOT> )? ( <NULL> | <MISSING> | <UNKOWN> ) )?</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> ( ( <PLUS> | <MINUS> ) <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> ( ( <MUL> | <DIV> | <MOD> | <CARET> | <IDIV> ) <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>( ( <PLUS> | <MINUS> | ( <NOT> )? <EXISTS> ) )? <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><DOT> <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><LEFTBRACKET> ( <A HREF="#prod44">Expression</A> | <QUES> ) <RIGHTBRACKET></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> | <INTEGER_LITERAL> | <FLOAT_LITERAL> | <DOUBLE_LITERAL> | <MISSING> | <NULL> | <TRUE> | <FALSE> )</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>( <IDENTIFIER> | <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>( <IDENTIFIER> | <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><LEFTBRACKET> <A HREF="#prod85">ExpressionList</A> <RIGHTBRACKET></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><LEFTDBLBRACE> <A HREF="#prod85">ExpressionList</A> <RIGHTDBLBRACE></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> ( <COMMA> <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><COMMA></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><LEFTBRACE> ( <A HREF="#prod87">FieldBinding</A> ( <COMMA> <A HREF="#prod87">FieldBinding</A> )* )? <RIGHTBRACE></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> <COLON> <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> <LEFTPAREN> ( <A HREF="#prod44">Expression</A> ( <COMMA> <A HREF="#prod44">Expression</A> )* )? <RIGHTPAREN></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>( <LEFTPAREN> <A HREF="#prod44">Expression</A> <RIGHTPAREN> | <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><CASE> ( <A HREF="#prod44">Expression</A> )? ( <WHEN> <A HREF="#prod44">Expression</A> <THEN> <A HREF="#prod44">Expression</A> )* ( <ELSE> <A HREF="#prod44">Expression</A> )? <END></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> ( ( <UNION> | <INTERSECT> | <EXCEPT> ) ( <ALL> )? ( <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><LEFTPAREN> <A HREF="#prod62">SelectExpression</A> <RIGHTPAREN></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><SELECT> ( <ALL> | <DISTINCT> )? ( <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> ( <COMMA> <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>( <RAW> | <ELEMENT> | <VALUE> ) <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> ( ( <AS> )? <A HREF="#prod18">Identifier</A> )? | <A HREF="#prod44">Expression</A> <DOT> <MUL> | <MUL> )</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><FROM> <A HREF="#prod102">FromTerm</A> ( <COMMA> <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> ( ( <AS> )? <A HREF="#prod50">Variable</A> )? ( <AT> <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><JOIN> <A HREF="#prod44">Expression</A> ( ( <AS> )? <A HREF="#prod50">Variable</A> )? ( <AT> <A HREF="#prod50">Variable</A> )? <ON> <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>( <UNNEST> | <CORRELATE> | <FLATTEN> ) <A HREF="#prod44">Expression</A> ( ( <AS> )? <A HREF="#prod50">Variable</A> ) ( <AT> <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>( <INNER> | <LEFT> ( <OUTER> )? )</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>( ( <LET> | <LETTING> ) <A HREF="#prod106">LetElement</A> ( <COMMA> <A HREF="#prod106">LetElement</A> )* | <WITH> <A HREF="#prod107">WithElement</A> ( <COMMA> <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><WHERE> <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><ORDER> <BY> <A HREF="#prod44">Expression</A> ( ( <ASC> ) | ( <DESC> ) )? ( <COMMA> <A HREF="#prod44">Expression</A> ( ( <ASC> ) | ( <DESC> ) )? )*</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><GROUP> <BY> ( <A HREF="#prod44">Expression</A> ( ( <AS> )? <A HREF="#prod50">Variable</A> )? ( <COMMA> <A HREF="#prod44">Expression</A> ( ( <AS> )? <A HREF="#prod50">Variable</A> )? )* ) ( <GROUP> <AS> <A HREF="#prod50">Variable</A> ( <LEFTPAREN> <A HREF="#prod79">VariableRef</A> <AS> <A HREF="#prod18">Identifier</A> ( <COMMA> <A HREF="#prod79">VariableRef</A> <AS> <A HREF="#prod18">Identifier</A> )* <RIGHTPAREN> )? )?</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><HAVING> <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><LIMIT> <A HREF="#prod44">Expression</A> ( <OFFSET> <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>( ( <SOME> ) | ( <EVERY> ) ) <A HREF="#prod50">Variable</A> <IN> <A HREF="#prod44">Expression</A> ( <COMMA> <A HREF="#prod50">Variable</A> <IN> <A HREF="#prod44">Expression</A> )* <SATISFIES> <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> <EQ> <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> <AS> <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));
+ }
+
}