Xikui Wang has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/2010

Change subject: [ASTERIXDB-2096] Fix type casting for ExternalFunction
......................................................................

[ASTERIXDB-2096] Fix type casting for ExternalFunction

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
1. The current IntroduceDynamicTypeCastForExternalFunctionRule
cannot handle external function calls in nested record constructor.
2. The ResultExtractor should be able to handle multiple queries
in single statement file, as AQL does.

Change-Id: I65c298def75b18fab01f513012e28fc44fdc2fd4
---
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java
M 
asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
M 
asterixdb/asterix-app/src/test/resources/runtimets/queries/external-library/upperCase/upperCase.3.query.aql
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.1.ddl.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.2.lib.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.3.query.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.4.lib.sqlpp
M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
8 files changed, 135 insertions(+), 24 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/10/2010/1

diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java
index c9a873b..3b5a85c 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java
@@ -30,6 +30,8 @@
 import org.apache.asterix.om.utils.NonTaggedFormatUtil;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
@@ -37,9 +39,17 @@
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.StatefulFunctionCallExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
+import 
org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionReferenceTransform;
+import 
org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
 import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 
 /**
@@ -58,12 +68,21 @@
     private boolean rewriteFunctionArgs(ILogicalOperator op, 
Mutable<ILogicalExpression> expRef,
             IOptimizationContext context) throws AlgebricksException {
         ILogicalExpression expr = expRef.getValue();
-        if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL
-                || !(expr instanceof ScalarFunctionCallExpression)) {
+        if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
             return false;
         }
-        ScalarFunctionCallExpression funcCallExpr = 
(ScalarFunctionCallExpression) expr;
         boolean changed = false;
+        // go over all arguments recursively
+        AbstractFunctionCallExpression funcCallExpr = 
((AbstractFunctionCallExpression)expr);
+        for (Mutable<ILogicalExpression> functionArgRef : 
funcCallExpr.getArguments()) {
+            if (rewriteFunctionArgs(op, functionArgRef, context)) {
+                changed = true;
+            }
+        }
+        // if current function is builtin function, skip the type casting
+        if 
(BuiltinFunctions.getBuiltinFunctionIdentifier(funcCallExpr.getFunctionIdentifier())
 != null) {
+            return changed;
+        }
         IAType inputRecordType;
         ARecordType requiredRecordType;
         for (int iter1 = 0; iter1 < funcCallExpr.getArguments().size(); 
iter1++) {
@@ -105,19 +124,6 @@
         if (op.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
             return false;
         }
-        AssignOperator assignOp = (AssignOperator) op;
-        ILogicalExpression assignExpr = 
assignOp.getExpressions().get(0).getValue();
-        if (assignExpr.getExpressionTag() != 
LogicalExpressionTag.FUNCTION_CALL) {
-            return false;
-        }
-        if (BuiltinFunctions.getBuiltinFunctionIdentifier(
-                ((AbstractFunctionCallExpression) 
assignExpr).getFunctionIdentifier()) != null) {
-            return false;
-        }
-        if (op.acceptExpressionTransform(exprRef -> rewriteFunctionArgs(op, 
exprRef, context))) {
-            return true;
-        } else {
-            return false;
-        }
+        return op.acceptExpressionTransform(expr -> rewriteFunctionArgs(op, 
expr, context));
     }
 }
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
index 0bba635..abed617 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
@@ -54,9 +54,11 @@
         String status = "";
         String results = "";
         String field = "";
+        String fieldPrefix = "";
         for (Iterator<String> sIter = result.fieldNames(); sIter.hasNext();) {
             field = sIter.next();
-            switch (field) {
+            fieldPrefix = field.split("-")[0];
+            switch (fieldPrefix) {
                 case "requestID":
                     break;
                 case "clientContextID":
@@ -81,18 +83,18 @@
                 case "results":
                     if (result.get(field).size() <= 1) {
                         if (result.get(field).size() == 0) {
-                            results = "";
+                            results += "";
                         } else if (result.get(field).isArray()) {
                             if (result.get(field).get(0).isTextual()) {
-                                results = result.get(field).get(0).asText();
+                                results += result.get(field).get(0).asText();
                             } else {
                                 ObjectMapper omm = new ObjectMapper();
                                 omm.setDefaultPrettyPrinter(singleLine);
                                 omm.enable(SerializationFeature.INDENT_OUTPUT);
-                                results = 
omm.writer(singleLine).writeValueAsString(result.get(field));
+                                results += 
omm.writer(singleLine).writeValueAsString(result.get(field));
                             }
                         } else {
-                            results = om.writeValueAsString(result.get(field));
+                            results += 
om.writeValueAsString(result.get(field));
                         }
                     } else {
                         StringBuilder sb = new StringBuilder();
@@ -106,7 +108,7 @@
                                 }
                             }
                         }
-                        results = sb.toString();
+                        results += sb.toString();
                     }
                     break;
                 default:
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries/external-library/upperCase/upperCase.3.query.aql
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries/external-library/upperCase/upperCase.3.query.aql
index 61ed394..5f0b86c 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries/external-library/upperCase/upperCase.3.query.aql
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries/external-library/upperCase/upperCase.3.query.aql
@@ -23,3 +23,6 @@
 
 let $i:=testlib#toUpper({"id":1, "text":"lower text"})
 return $i;
+
+let $i:= {"field1" : testlib#toUpper({"id":1, "text":"lower text"}), "field2": 
123}
+return $i;
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.1.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.1.ddl.sqlpp
new file mode 100644
index 0000000..f7b2342
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.1.ddl.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+DROP DATAVERSE externallibtest if exists;
+CREATE DATAVERSE  externallibtest;
+USE externallibtest;
+
+create type TextType if not exists as open {
+    id: int32,
+    text: string
+};
+
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.2.lib.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.2.lib.sqlpp
new file mode 100644
index 0000000..d1e0e87
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.2.lib.sqlpp
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+install externallibtest testlib 
target/data/externallib/asterix-external-data-testlib.zip
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.3.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.3.query.sqlpp
new file mode 100644
index 0000000..f361232
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.3.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+use externallibtest;
+
+let i={"id":1, "text":"lower text"}
+select value `testlib#toUpper`(i);
+
+let i=`testlib#toUpper`({"id":1, "text":"lower text"})
+select value i;
+
+let i= {"field1" : `testlib#toUpper`({"id":1, "text":"lower text"}), "field2": 
123}
+select value i;
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.4.lib.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.4.lib.sqlpp
new file mode 100644
index 0000000..86af80f
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/upperCase/upperCase.4.lib.sqlpp
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+uninstall externallibtest testlib
\ No newline at end of file
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 16d4cb3..8fd1e53 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -8125,7 +8125,7 @@
       </compilation-unit>
     </test-case>
   </test-group>
-  <test-group>
+  <test-group name="big-object">
     <test-case FilePath="big-object">
       <compilation-unit name="big_object_sort">
         <output-dir compare="Text">big_object_sort</output-dir>
@@ -9058,4 +9058,11 @@
       </compilation-unit>
     </test-case>
   </test-group>
+  <test-group name="external-library">
+    <test-case FilePath="external-library">
+      <compilation-unit name="upperCase">
+        <output-dir compare="Text">upperCase</output-dir>
+      </compilation-unit>
+    </test-case>
+  </test-group>
 </test-suite>

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/2010
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I65c298def75b18fab01f513012e28fc44fdc2fd4
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Xikui Wang <[email protected]>

Reply via email to