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 <[email protected]> Authored: Mon May 21 15:35:40 2018 +0200 Committer: Michael Mior <[email protected]> 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 "[email protected]"; + } + +} + +// 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 | [email protected] | ++-----------+----------+---------------------+ +(1 row) + +!ok
