Xikui Wang has uploaded this change for review. ( 
https://asterix-gerrit.ics.uci.edu/3379


Change subject: [ASTERIX-2559] Prevent missing parameter in external UDF
......................................................................

[ASTERIX-2559] Prevent missing parameter in external UDF

- user model changes: yes
UNION typed parameters are not allowed in external UDF parameters
- storage format changes: no
- interface changes: no

Details:
When there is a UNION typed parameter in an external UDF, the
IntroduceDynamicTypeCastForExternalFunctionRule would repeatedly
introduce cast function. When such parameter appears, the external UDF
should throw an exception when the value is missing.

Change-Id: I1fe2098d1e1c5e179a0635d9d6cc3a1534278259
---
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.1.ddl.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.2.lib.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.3.ddl.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.4.query.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.5.query.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.7.ddl.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/parameter_casting/parameter_casting.1.adm
M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
9 files changed, 166 insertions(+), 14 deletions(-)



  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/79/3379/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 a00933a..fcf931d 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
@@ -75,40 +75,48 @@
         IAType inputType;
         IAType reqArgType;
         boolean castFlag;
+        boolean checkUnknown = false;
         for (int i = 0; i < funcCallExpr.getArguments().size(); i++) {
             Mutable<ILogicalExpression> argExpr = 
funcCallExpr.getArguments().get(i);
             inputType = (IAType) 
op.computeOutputTypeEnvironment(context).getType(argExpr.getValue());
             reqArgType = ((ExternalScalarFunctionInfo) 
funcCallExpr.getFunctionInfo()).getArgumentTypes().get(i);
-
+            while (NonTaggedFormatUtil.isOptional(inputType)) {
+                inputType = ((AUnionType) inputType).getActualType();
+                checkUnknown = true;
+            }
             if (reqArgType.getTypeTag() == ATypeTag.OBJECT) {
                 castFlag = 
!IntroduceDynamicTypeCastRule.compatible((ARecordType) reqArgType, inputType,
                         argExpr.getValue().getSourceLocation());
             } else {
                 castFlag = !reqArgType.equals(inputType);
             }
-            /**
-             * the input record type can be an union type
-             * for the case when it comes from a subplan or left-outer join
-             */
-            boolean checkUnknown = false;
-            while (NonTaggedFormatUtil.isOptional(inputType)) {
-                /** while-loop for the case there is a nested multi-level 
union */
-                inputType = ((AUnionType) inputType).getActualType();
-                checkUnknown = true;
+
+            if (checkUnknown) {
+                AbstractFunctionCallExpression chkUnknownFunc =
+                        new 
ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CHECK_UNKNOWN));
+                TypeCastUtils.setRequiredAndInputTypes(chkUnknownFunc, 
reqArgType, inputType);
+                wrapFunctionParameter(funcCallExpr, argExpr, chkUnknownFunc, 
i);
+                changed = true;
             }
-            if (castFlag || checkUnknown) {
+
+            if (castFlag) {
                 AbstractFunctionCallExpression castFunc =
                         new 
ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CAST_TYPE));
-                
castFunc.setSourceLocation(argExpr.getValue().getSourceLocation());
-                castFunc.getArguments().add(argExpr);
                 TypeCastUtils.setRequiredAndInputTypes(castFunc, reqArgType, 
inputType);
-                funcCallExpr.getArguments().set(i, new 
MutableObject<>(castFunc));
+                wrapFunctionParameter(funcCallExpr, argExpr, castFunc, i);
                 changed = true;
             }
         }
         return changed;
     }

+    private void wrapFunctionParameter(AbstractFunctionCallExpression 
funcCallExpr, Mutable<ILogicalExpression> argExpr,
+            AbstractFunctionCallExpression wrapperFunction, int idx) {
+        
wrapperFunction.setSourceLocation(argExpr.getValue().getSourceLocation());
+        wrapperFunction.getArguments().add(argExpr);
+        funcCallExpr.getArguments().set(idx, new 
MutableObject<>(wrapperFunction));
+    }
+
     @Override
     public boolean rewritePost(Mutable<ILogicalOperator> opRef, 
IOptimizationContext context)
             throws AlgebricksException {
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.1.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.1.ddl.sqlpp
new file mode 100644
index 0000000..7407c9d
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.1.ddl.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+CREATE DATAVERSE externallibtest;
+USE externallibtest;
+
+CREATE TYPE RankingResultType AS {
+  id: int
+};
+
+CREATE DATASET RankingResult(RankingResultType) PRIMARY KEY id;
+
+INSERT INTO RankingResult([
+{ "id": 1,
+  "score":1.3
+}]);
+
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.2.lib.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.2.lib.sqlpp
new file mode 100644
index 0000000..d1e0e87
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.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/parameter_casting/parameter_casting.3.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.3.ddl.sqlpp
new file mode 100644
index 0000000..d2c3e6c
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.3.ddl.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+create function test_using_rankdataset(newItem) {
+    LET rankingResult = (SELECT VALUE r FROM RankingResult r)[0]
+    SELECT VALUE testlib#mysum(newItem.score, rankingResult.score)
+};
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.4.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.4.query.sqlpp
new file mode 100644
index 0000000..6705773
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.4.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.
+ */
+use externallibtest;
+
+SELECT VALUE test_using_rankdataset({"id":1, "text": "test", "score": 1.4})[0];
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.5.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.5.query.sqlpp
new file mode 100644
index 0000000..635981d
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.5.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.
+ */
+use externallibtest;
+
+SELECT VALUE test_using_rankdataset({"id":1, "text": "test"})[0];
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.7.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.7.ddl.sqlpp
new file mode 100644
index 0000000..65733e4
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/parameter_casting/parameter_casting.7.ddl.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.
+ */
+DROP DATAVERSE externallibtest;
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/parameter_casting/parameter_casting.1.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/parameter_casting/parameter_casting.1.adm
new file mode 100644
index 0000000..d8263ee
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/parameter_casting/parameter_casting.1.adm
@@ -0,0 +1 @@
+2
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml 
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
index 71d0503..c7efda5 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
@@ -24,6 +24,12 @@

   <test-group name="external-library">
     <test-case FilePath="external-library">
+      <compilation-unit name="parameter_casting">
+        <output-dir compare="Text">parameter_casting</output-dir>
+        <expected-error>cannot process input type missing</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="external-library">
       <compilation-unit name="type_validation">
         <output-dir compare="Text">type_validation</output-dir>
       </compilation-unit>

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

Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1fe2098d1e1c5e179a0635d9d6cc3a1534278259
Gerrit-Change-Number: 3379
Gerrit-PatchSet: 1
Gerrit-Owner: Xikui Wang <xkk...@gmail.com>

Reply via email to