You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by mm...@apache.org on 2018/05/23 15:13:08 UTC

calcite git commit: [CALCITE-2320] Filtering UDF when converting Filter to JDBCFilter (Piotr Bojko)

Repository: calcite
Updated Branches:
  refs/heads/master da568324a -> 2a79e837b


[CALCITE-2320] Filtering UDF when converting Filter to JDBCFilter (Piotr Bojko)

Close apache/calcite#693


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/2a79e837
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/2a79e837
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/2a79e837

Branch: refs/heads/master
Commit: 2a79e837b38ac1348d9acf4f2f9faf1bda323525
Parents: da56832
Author: Piotr Bojko <pt...@gmail.com>
Authored: Mon May 21 15:35:40 2018 +0200
Committer: Michael Mior <mm...@uwaterloo.ca>
Committed: Wed May 23 11:12:25 2018 -0400

----------------------------------------------------------------------
 .../apache/calcite/adapter/jdbc/JdbcRules.java  | 72 ++++++++++++--------
 .../calcite/chinook/ChosenCustomerEmail.java    | 30 ++++++++
 plus/src/main/resources/chinook/chinook.json    |  4 ++
 plus/src/test/resources/sql/functions.iq        | 11 +++
 4 files changed, 89 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/2a79e837/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
index dcfdb1a..87658d5 100644
--- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
+++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcRules.java
@@ -404,32 +404,6 @@ public class JdbcRules {
       return false;
     }
 
-    /**
-     * Visitor for checking whether part of projection is a user defined function or not
-     */
-    private static class CheckingUserDefinedFunctionVisitor extends RexVisitorImpl<Void> {
-
-      private boolean containsUsedDefinedFunction = false;
-
-      CheckingUserDefinedFunctionVisitor() {
-        super(true);
-      }
-
-      public boolean containsUserDefinedFunction() {
-        return containsUsedDefinedFunction;
-      }
-
-      @Override public Void visitCall(RexCall call) {
-        SqlOperator operator = call.getOperator();
-        if (operator instanceof SqlFunction
-            && ((SqlFunction) operator).getFunctionType().isUserDefined()) {
-          containsUsedDefinedFunction |= true;
-        }
-        return super.visitCall(call);
-      }
-
-    }
-
     public RelNode convert(RelNode rel) {
       final Project project = (Project) rel;
 
@@ -495,8 +469,23 @@ public class JdbcRules {
     /** Creates a JdbcFilterRule. */
     public JdbcFilterRule(JdbcConvention out,
         RelBuilderFactory relBuilderFactory) {
-      super(Filter.class, Predicates.<RelNode>alwaysTrue(), Convention.NONE,
-          out, relBuilderFactory, "JdbcFilterRule");
+      super(
+        Filter.class,
+        new PredicateImpl<Filter>() {
+          @Override public boolean test(Filter filter) {
+            return !userDefinedFunctionInFilter(filter);
+          }
+        },
+        Convention.NONE,
+        out,
+        relBuilderFactory,
+        "JdbcFilterRule");
+    }
+
+    private static boolean userDefinedFunctionInFilter(Filter filter) {
+      CheckingUserDefinedFunctionVisitor visitor = new CheckingUserDefinedFunctionVisitor();
+      filter.getCondition().accept(visitor);
+      return visitor.containsUserDefinedFunction();
     }
 
     public RelNode convert(RelNode rel) {
@@ -937,6 +926,33 @@ public class JdbcRules {
       return implementor.implement(this);
     }
   }
+
+  /**
+   * Visitor for checking whether part of projection is a user defined function or not
+   */
+  private static class CheckingUserDefinedFunctionVisitor extends RexVisitorImpl<Void> {
+
+    private boolean containsUsedDefinedFunction = false;
+
+    CheckingUserDefinedFunctionVisitor() {
+      super(true);
+    }
+
+    public boolean containsUserDefinedFunction() {
+      return containsUsedDefinedFunction;
+    }
+
+    @Override public Void visitCall(RexCall call) {
+      SqlOperator operator = call.getOperator();
+      if (operator instanceof SqlFunction
+          && ((SqlFunction) operator).getFunctionType().isUserDefined()) {
+        containsUsedDefinedFunction |= true;
+      }
+      return super.visitCall(call);
+    }
+
+  }
+
 }
 
 // End JdbcRules.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/2a79e837/plus/src/main/java/org/apache/calcite/chinook/ChosenCustomerEmail.java
----------------------------------------------------------------------
diff --git a/plus/src/main/java/org/apache/calcite/chinook/ChosenCustomerEmail.java b/plus/src/main/java/org/apache/calcite/chinook/ChosenCustomerEmail.java
new file mode 100644
index 0000000..de6187f
--- /dev/null
+++ b/plus/src/main/java/org/apache/calcite/chinook/ChosenCustomerEmail.java
@@ -0,0 +1,30 @@
+/*
+ * 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.calcite.chinook;
+
+/**
+ * Example UDF for where clause to check pushing to JDBC
+ */
+public class ChosenCustomerEmail {
+
+  public String eval() {
+    return "ftremblay@gmail.com";
+  }
+
+}
+
+// End ChosenCustomerEmail.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/2a79e837/plus/src/main/resources/chinook/chinook.json
----------------------------------------------------------------------
diff --git a/plus/src/main/resources/chinook/chinook.json b/plus/src/main/resources/chinook/chinook.json
index f506439..e8fee72 100644
--- a/plus/src/main/resources/chinook/chinook.json
+++ b/plus/src/main/resources/chinook/chinook.json
@@ -65,6 +65,10 @@
         {
           "name": "ASCONCATOFPARAMS",
           "className": "org.apache.calcite.chinook.StringConcatFunction"
+        },
+        {
+          "name": "CHOSENCUSTOMEREMAIL",
+          "className": "org.apache.calcite.chinook.ChosenCustomerEmail"
         }
       ]
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/2a79e837/plus/src/test/resources/sql/functions.iq
----------------------------------------------------------------------
diff --git a/plus/src/test/resources/sql/functions.iq b/plus/src/test/resources/sql/functions.iq
index 803b238..9d43762 100644
--- a/plus/src/test/resources/sql/functions.iq
+++ b/plus/src/test/resources/sql/functions.iq
@@ -28,3 +28,14 @@ SELECT email, ASCONCATOFPARAMS(firstname, lastname) AS joined FROM SIMPLE_CUSTOM
 (3 rows)
 
 !ok
+
+# Checks whether CHOOSENCUSTOMFUNCTION function is properly computed and not passed to subschema, like jdbc
+SELECT * FROM SIMPLE_CUSTOMER WHERE email = CHOSENCUSTOMEREMAIL();
++-----------+----------+---------------------+
+| FIRSTNAME | LASTNAME | EMAIL               |
++-----------+----------+---------------------+
+| François  | Tremblay | ftremblay@gmail.com |
++-----------+----------+---------------------+
+(1 row)
+
+!ok