Yingyi Bu has uploaded a new change for review.
https://asterix-gerrit.ics.uci.edu/1104
Change subject: Add several builtin functions.
......................................................................
Add several builtin functions.
- Added functions include: greatest, least, concat(||), initcap(title),
regexp_contains, ltrim, trim, rtrim.
Change-Id: I26351af22f67d66b56176f55b29a4e7ff63583f7
---
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/comparison/greatest_mixed/greatest_mixed.3.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/comparison/least_mixed/least_mixed.1.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_func/concat_func.1.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_pipe/concat_pipe.1.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_pipe_multi/concat_pipe.1.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/initcap/initcap.1.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/ltrim/ltrim.1.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_contains06/regexp_contains06.3.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/rtrim/rtrim.1.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/title/title.1.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/trim/trim.1.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/results/comparison/greatest_mixed/greatest_mixed.1.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/comparison/least_mixed/least_mixed.1.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/string/concat_pipe_multi/concat_pipe_multi.1.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/string/initcap/initcap.1.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/string/ltrim/ltrim.1.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/string/rtrim/rtrim.1.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/string/trim/trim.1.adm
M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
M
asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/OperatorExpressionVisitor.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
A
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppListInputFunctionRewriteVisitor.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/FunctionMapUtil.java
M asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
M
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
M
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringBoolEval.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringEval.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringStringEval.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractUnaryStringStringEval.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringInitCapDescriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrim2Descriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrimDescriptor.java
M
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLowerCaseDescriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrim2Descriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrimDescriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrim2Descriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrimDescriptor.java
M
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringUpperCaseDescriptor.java
M
hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/main/java/org/apache/hyracks/data/std/primitive/UTF8StringPointable.java
M
hyracks-fullstack/hyracks/hyracks-data/hyracks-data-std/src/test/java/org/apache/hyracks/data/std/primitive/UTF8StringPointableTest.java
44 files changed, 1,605 insertions(+), 187 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/04/1104/1
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..cd9e39d 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
@@ -205,16 +205,23 @@
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.StringRTrim2Descriptor;
+import org.apache.asterix.runtime.evaluators.functions.StringRTrimDescriptor;
import org.apache.asterix.runtime.evaluators.functions.StringReplaceDescriptor;
import
org.apache.asterix.runtime.evaluators.functions.StringReplaceWithFlagsDescriptor;
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;
@@ -491,6 +498,13 @@
functionsToInjectUnkownHandling.add(StringConcatDescriptor.FACTORY);
functionsToInjectUnkownHandling.add(StringJoinDescriptor.FACTORY);
functionsToInjectUnkownHandling.add(RegExpDescriptor.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);
// Constructors
functionsToInjectUnkownHandling.add(ABooleanConstructorDescriptor.FACTORY);
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.1.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/concat_pipe_multi/concat_pipe.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.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/regexp_contains06/regexp_contains06.3.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_contains06/regexp_contains06.3.query.sqlpp
new file mode 100644
index 0000000..4fed528
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/regexp_contains06/regexp_contains06.3.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 [
+ matches('mnop','.'),
+ matches('abcdefABCDEF','/d'),
+ matches('12345','\\d'),
+ matches('abcdefGHIJK','\\D'),
+ matches(' ','\\s'),
+ matches(' ','\\S'),
+ matches('Welcome to pattern matching!','[a-zA-Z_0-9]'),
+ matches('!@#$%^&*()','[a-zA-Z_0-9]'),
+ matches('!@#$%^&*()','[^\\W]'),
+ matches('!@#$%^&*','[^\\w]'),
+ matches('0xffff','[\\p{XDigit}]'),
+ matches('FFFFFFFF','[\\p{XDigit}]'),
+ matches('abcdefgh','[\\p{javaLowerCase}]'),
+ matches('ABCDEF','[\\p{javaLowerCase}]'),
+ matches(`codepoint-to-string`([163]),'[\\p{Sc}]')
+ ] as a
+;
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/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/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..410cb00
--- /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/testsuite_sqlpp.xml
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 9548259..3f3bcc2 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>
@@ -5170,6 +5200,11 @@
<test-case FilePath="string">
<compilation-unit name="lowercase">
<output-dir compare="Text">lowercase</output-dir>
+ </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">
@@ -5238,6 +5273,11 @@
</compilation-unit>
</test-case>
<test-case FilePath="string">
+ <compilation-unit name="regexp_contains06">
+ <output-dir compare="Text">matches06</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="string">
<compilation-unit name="replace1">
<output-dir compare="Text">replace1</output-dir>
</compilation-unit>
@@ -5260,6 +5300,11 @@
<test-case FilePath="string">
<compilation-unit name="replace3">
<output-dir compare="Text">replace3</output-dir>
+ </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">
@@ -5465,6 +5510,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 +5530,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-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..b68962f 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,31 @@
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) {
+ case LIKE:
+ case NOT_LIKE:
+ return processLikeOperator(operatorExpr, opType);
+ case IN:
+ case NOT_IN:
+ return processInOperator(operatorExpr, opType);
+ case CONCAT:
+ return processConcatOperator(operatorExpr);
+ default:
+ break;
}
return operatorExpr;
}
@@ -73,7 +74,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 +87,17 @@
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) {
+ 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/SqlppBuiltinFunctionRewriteVisitor.java
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
index fbf08ee..1f4e1f4 100644
---
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
+++
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
@@ -18,6 +18,8 @@
*/
package org.apache.asterix.lang.sqlpp.rewrites.visitor;
+import static
org.apache.asterix.lang.sqlpp.util.FunctionMapUtil.normalizedListInputFunctions;
+
import java.util.ArrayList;
import java.util.List;
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..1c4135e
--- /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 severael 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..8fcb7b3 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,25 @@
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: initcap
+ FUNCTION_NAME_MAP.put("regexp_contains", "matches"); //SQL: title,
SQL: initcap
+ FUNCTION_NAME_MAP.put("regexp_replace", "replace"); //SQL: title, SQL:
initcap
+ }
+
+ // 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 +137,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.jj
b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 2378060..6cdd396 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -1842,8 +1842,8 @@
{
operand = MultExpr()
(
- LOOKAHEAD(1)
- (<PLUS> | <MINUS>)
+ LOOKAHEAD(1)
+ (<PLUS> | <MINUS> | <CONCAT>)
{
if (op == null) {
op = new OperatorExpr();
@@ -2302,7 +2302,7 @@
List<Expression> whenExprs = new ArrayList<Expression>();
List<Expression> thenExprs = new ArrayList<Expression>();
Expression elseExpr = null;
-
+
Expression whenExpr = null;
Expression thenExpr = null;
}
@@ -3005,6 +3005,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..e276fa2 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
@@ -255,6 +255,20 @@
"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_REPLACE = new
FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"replace", 3);
public static final FunctionIdentifier STRING_REPLACE_WITH_FLAG = new
FunctionIdentifier(
@@ -868,6 +882,14 @@
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_STARTS_WITH, StringBooleanTypeComputer.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_STARTS_WITH, StringBooleanTypeComputer.INSTANCE,
true);
addFunction(STRING_ENDS_WITH, StringBooleanTypeComputer.INSTANCE,
true);
addFunction(STRING_MATCHES, StringBooleanTypeComputer.INSTANCE, true);
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..ae6fd52 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,75 +18,33 @@
*/
package org.apache.asterix.runtime.evaluators.functions;
-import java.io.DataOutput;
-
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 AlgebricksException {
ABoolean res = compute(leftPtr, rightPtr) ? ABoolean.TRUE :
ABoolean.FALSE;
try {
boolSerde.serialize(res, dout);
@@ -96,6 +54,7 @@
result.set(resultStorage);
}
+ // Computes a boolean value from two input strings.
protected abstract boolean compute(UTF8StringPointable left,
UTF8StringPointable right) throws AlgebricksException;
}
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..73c2237
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringEval.java
@@ -0,0 +1,110 @@
+/*
+ * 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 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 ptr0 = new VoidPointable();
+ private IPointable ptr1 = new VoidPointable();
+ private final UTF8StringPointable leftPtr = new UTF8StringPointable();
+ private final UTF8StringPointable rightPtr = new UTF8StringPointable();
+
+ // For results.
+ protected ArrayBackedValueStorage resultStorage = new
ArrayBackedValueStorage();
+ protected DataOutput dout = 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, ptr0);
+ byte[] bytes0 = ptr0.getByteArray();
+ int offset0 = ptr0.getStartOffset();
+ int len0 = ptr0.getLength();
+
+ // Gets the second argument.
+ evalRight.evaluate(tuple, ptr1);
+ byte[] bytes1 = ptr1.getByteArray();
+ int offset1 = ptr1.getStartOffset();
+ int len1 = ptr1.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.
+ process(leftPtr, rightPtr, resultPointable);
+ }
+
+ /**
+ * The actual processing of a string function.
+ *
+ * @param left
+ * , the first argument.
+ * @param right
+ * , the second argument.
+ * @param resultPointable
+ * , the result.
+ * @throws AlgebricksException
+ */
+ protected abstract void process(UTF8StringPointable left,
UTF8StringPointable right, IPointable resultPointable)
+ throws AlgebricksException;
+
+}
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..ee1559a
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringStringEval.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.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 AlgebricksException {
+ resultArray.reset();
+ compute(leftPtr, rightPtr, resultStrPtr);
+ writeResult(resultPointable);
+ }
+
+ // Computes a boolean value from two input strings.
+ protected abstract void compute(UTF8StringPointable left,
UTF8StringPointable right,
+ UTF8StringPointable resultStrPtr) throws AlgebricksException;
+
+ // Writes the result.
+ void writeResult(IPointable resultPointable) throws AlgebricksException {
+ try {
+ dout.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ dout.write(resultStrPtr.getByteArray(), 0,
resultStrPtr.getLength());
+ resultPointable.set(resultStorage);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+}
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..8c01472
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractUnaryStringStringEval.java
@@ -0,0 +1,92 @@
+/*
+ * 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();
+ process(stringPtr, resultPointable);
+ writeResult(resultPointable);
+ }
+
+ // Processes an input UTF8 string.
+ abstract void process(UTF8StringPointable inputString, IPointable
resultPointable)
+ throws AlgebricksException;
+
+ // Writes the result.
+ void writeResult(IPointable resultPointable) throws AlgebricksException {
+ try {
+ dataOutput.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ dataOutput.write(resultArray.getByteArray(), 0,
resultArray.getLength());
+ resultPointable.set(resultStorage);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+}
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..6dc1a39
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringInitCapDescriptor.java
@@ -0,0 +1,81 @@
+/*
+ * 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 InitCapEvaluator(ctx, args[0]);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return AsterixBuiltinFunctions.STRING_INITCAP;
+ }
+
+ class InitCapEvaluator extends AbstractUnaryStringStringEval {
+
+ InitCapEvaluator(IHyracksTaskContext context, IScalarEvaluatorFactory
argEvalFactory)
+ throws AlgebricksException {
+ super(context, argEvalFactory,
StringInitCapDescriptor.this.getIdentifier());
+ }
+
+ // Processes an input UTF8 string.
+ protected void process(UTF8StringPointable inputString, IPointable
resultPointable) throws AlgebricksException {
+ try {
+ inputString.initCap(resultBuilder, resultArray);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ }
+
+}
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..a204b5b
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrim2Descriptor.java
@@ -0,0 +1,78 @@
+/*
+ * 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;
+import org.apache.hyracks.data.std.util.GrowableArray;
+import org.apache.hyracks.data.std.util.UTF8StringBuilder;
+
+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() {
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext
ctx) throws AlgebricksException {
+ return new StringLTrimEvaluator(ctx, args[0], args[1]);
+ }
+ };
+ }
+
+ class StringLTrimEvaluator extends
StringTrim2Descriptor.StringTrim2Evaluator {
+
+ public StringLTrimEvaluator(IHyracksTaskContext context,
IScalarEvaluatorFactory evalLeftFactory,
+ IScalarEvaluatorFactory evalRightFactory) throws
AlgebricksException {
+ super(context, evalLeftFactory, evalRightFactory,
StringLTrim2Descriptor.this.getIdentifier());
+ }
+
+ @Override
+ protected void trim(UTF8StringPointable srcPtr, UTF8StringBuilder
builder, GrowableArray out)
+ throws IOException {
+ UTF8StringPointable.trim(srcPtr, builder, out, true, false,
charSet);
+ }
+ }
+
+}
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..45be85d
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLTrimDescriptor.java
@@ -0,0 +1,80 @@
+/*
+ * 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 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() {
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext
ctx) throws AlgebricksException {
+ return new StringTrimEvaluator(ctx, args[0],
StringLTrimDescriptor.this.getIdentifier());
+ }
+ };
+ }
+
+ static class StringTrimEvaluator extends
StringTrimDescriptor.StringTrimEvaluator {
+
+ public StringTrimEvaluator(IHyracksTaskContext context,
IScalarEvaluatorFactory evalFactory,
+ FunctionIdentifier funcId) throws AlgebricksException {
+ super(context, evalFactory, funcId);
+ }
+
+ @Override
+ protected void process(UTF8StringPointable srcPtr, IPointable
resultPointable) throws AlgebricksException {
+ try {
+ UTF8StringPointable.trim(srcPtr, resultBuilder, resultArray,
true, false, charSet);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+}
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..552fd70 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,51 +43,13 @@
};
@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();
-
- @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);
- }
- }
- };
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext
ctx) throws AlgebricksException {
+ return new LowerCaseEvaluator(ctx, args[0]);
}
};
}
@@ -105,4 +59,22 @@
return AsterixBuiltinFunctions.STRING_LOWERCASE;
}
+ class LowerCaseEvaluator extends AbstractUnaryStringStringEval {
+
+ public LowerCaseEvaluator(IHyracksTaskContext context,
IScalarEvaluatorFactory argEvalFactory)
+ throws AlgebricksException {
+ super(context, argEvalFactory,
StringLowerCaseDescriptor.this.getIdentifier());
+ }
+
+ // Processes an input UTF8 string.
+ protected void process(UTF8StringPointable inputString, IPointable
resultPointable) throws AlgebricksException {
+ try {
+ inputString.lowercase(resultBuilder, resultArray);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ }
+
}
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..1c80cb7
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrim2Descriptor.java
@@ -0,0 +1,78 @@
+/*
+ * 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;
+import org.apache.hyracks.data.std.util.GrowableArray;
+import org.apache.hyracks.data.std.util.UTF8StringBuilder;
+
+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() {
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext
ctx) throws AlgebricksException {
+ return new StringLTrimEvaluator(ctx, args[0], args[1]);
+ }
+ };
+ }
+
+ class StringLTrimEvaluator extends
StringTrim2Descriptor.StringTrim2Evaluator {
+
+ public StringLTrimEvaluator(IHyracksTaskContext context,
IScalarEvaluatorFactory evalLeftFactory,
+ IScalarEvaluatorFactory evalRightFactory) throws
AlgebricksException {
+ super(context, evalLeftFactory, evalRightFactory,
StringRTrim2Descriptor.this.getIdentifier());
+ }
+
+ @Override
+ protected void trim(UTF8StringPointable srcPtr, UTF8StringBuilder
builder, GrowableArray out)
+ throws IOException {
+ UTF8StringPointable.trim(srcPtr, builder, out, false, true,
charSet);
+ }
+ }
+
+}
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..1466a88
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringRTrimDescriptor.java
@@ -0,0 +1,80 @@
+/*
+ * 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 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() {
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext
ctx) throws AlgebricksException {
+ return new StringTrimEvaluator(ctx, args[0],
StringRTrimDescriptor.this.getIdentifier());
+ }
+ };
+ }
+
+ static class StringTrimEvaluator extends
StringTrimDescriptor.StringTrimEvaluator {
+
+ public StringTrimEvaluator(IHyracksTaskContext context,
IScalarEvaluatorFactory evalFactory,
+ FunctionIdentifier funcId) throws AlgebricksException {
+ super(context, evalFactory, funcId);
+ }
+
+ @Override
+ protected void process(UTF8StringPointable srcPtr, IPointable
resultPointable) throws AlgebricksException {
+ try {
+ UTF8StringPointable.trim(srcPtr, resultBuilder, resultArray,
false, true, charSet);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+}
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..3aed51f
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrim2Descriptor.java
@@ -0,0 +1,100 @@
+/*
+ * 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.commons.lang3.CharSet;
+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.GrowableArray;
+import org.apache.hyracks.data.std.util.UTF8StringBuilder;
+
+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() {
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext
ctx) throws AlgebricksException {
+ return new StringTrim2Evaluator(ctx, args[0], args[1],
StringTrim2Descriptor.this.getIdentifier());
+ }
+ };
+ }
+
+ static class StringTrim2Evaluator extends AbstractBinaryStringStringEval {
+ protected final ByteArrayAccessibleOutputStream lastPatternStorage =
new ByteArrayAccessibleOutputStream();
+ protected final UTF8StringPointable lastPatternPtr = new
UTF8StringPointable();
+ protected CharSet charSet;
+
+ public StringTrim2Evaluator(IHyracksTaskContext context,
IScalarEvaluatorFactory evalLeftFactory,
+ IScalarEvaluatorFactory evalRightFactory, FunctionIdentifier
funcId) throws AlgebricksException {
+ super(context, evalLeftFactory, evalRightFactory, funcId);
+ }
+
+ protected void compute(UTF8StringPointable srcPtr, UTF8StringPointable
patternPtr,
+ UTF8StringPointable resultStrPtr) throws AlgebricksException {
+ boolean newPattern = false;
+ if (charSet == null || lastPatternPtr.compareTo(patternPtr) != 0) {
+ newPattern = true;
+ }
+ if (newPattern) {
+ StringEvaluatorUtils.copyResetUTF8Pointable(patternPtr,
lastPatternStorage, lastPatternPtr);
+ charSet = CharSet.getInstance(patternPtr.toString());
+ }
+ try {
+ trim(srcPtr, resultBuilder, resultArray);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ resultStrPtr.set(resultArray.getByteArray(), 0,
resultArray.getLength());
+ }
+
+ protected void trim(UTF8StringPointable srcPtr, UTF8StringBuilder
builder, GrowableArray out)
+ throws IOException {
+ UTF8StringPointable.trim(srcPtr, builder, out, true, true,
charSet);
+ }
+ }
+
+}
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..2af4611
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringTrimDescriptor.java
@@ -0,0 +1,82 @@
+/*
+ * 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.commons.lang3.CharSet;
+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() {
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext
ctx) throws AlgebricksException {
+ return new StringTrimEvaluator(ctx, args[0],
StringTrimDescriptor.this.getIdentifier());
+ }
+ };
+ }
+
+ static class StringTrimEvaluator extends AbstractUnaryStringStringEval {
+ protected CharSet charSet = CharSet.getInstance(" ");
+
+ public StringTrimEvaluator(IHyracksTaskContext context,
IScalarEvaluatorFactory evalFactory,
+ FunctionIdentifier funcId) throws AlgebricksException {
+ super(context, evalFactory, funcId);
+ }
+
+ @Override
+ protected void process(UTF8StringPointable srcPtr, IPointable
resultPointable) throws AlgebricksException {
+ try {
+ UTF8StringPointable.trim(srcPtr, resultBuilder, resultArray,
true, true, charSet);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ }
+
+}
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..9887bd2 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,51 +43,13 @@
};
@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();
-
- @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);
- }
- }
- };
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext
ctx) throws AlgebricksException {
+ return new UpperCaseEvaluator(ctx, args[0]);
}
};
}
@@ -105,4 +59,21 @@
return AsterixBuiltinFunctions.STRING_UPPERCASE;
}
+ class UpperCaseEvaluator extends AbstractUnaryStringStringEval {
+
+ public UpperCaseEvaluator(IHyracksTaskContext context,
IScalarEvaluatorFactory argEvalFactory)
+ throws AlgebricksException {
+ super(context, argEvalFactory,
StringUpperCaseDescriptor.this.getIdentifier());
+ }
+
+ // Processes an input UTF8 string.
+ protected void process(UTF8StringPointable inputString, IPointable
resultPointable) throws AlgebricksException {
+ try {
+ inputString.uppercase(resultBuilder, resultArray);
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ }
}
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..1d07012 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;
@@ -443,4 +444,78 @@
builder.finish();
}
+ public void initCap(UTF8StringBuilder builder, GrowableArray out) throws
IOException {
+ initCap(this, builder, out);
+ }
+
+ 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;
+ char previousChar = ' ';
+ 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);
+ }
+
+ 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.
+ builder.reset(out, endIndex - startIndex);
+ while (startIndex < endIndex) {
+ char ch = srcPtr.charAt(srcStart + startIndex);
+ startIndex += srcPtr.charSize(srcStart + startIndex);
+ builder.appendChar(ch);
+ }
+ 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));
+ }
+
}
--
To view, visit https://asterix-gerrit.ics.uci.edu/1104
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I26351af22f67d66b56176f55b29a4e7ff63583f7
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Yingyi Bu <[email protected]>