Repository: asterixdb Updated Branches: refs/heads/master 7152182a3 -> 753576f38
ASTERIXDB-1806: let inject_failure not utilize an index - Change the condition check logic of index transformation rule so that only arguments of AND function can be checked. - Let Index TransFormation Rule ignore Inject_failure() since the function can't utilize the index because of its arguments. Change-Id: I5ca2da1eb08fbb7c27205bdff9795c0aa816794b Reviewed-on: https://asterix-gerrit.ics.uci.edu/1536 Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu> BAD: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Integration-Tests: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Reviewed-by: Yingyi Bu <buyin...@gmail.com> Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/753576f3 Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/753576f3 Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/753576f3 Branch: refs/heads/master Commit: 753576f3822e10f148ef37ee3ea4c67e243777a7 Parents: 7152182 Author: Taewoo Kim <wangs...@yahoo.com> Authored: Tue Feb 28 17:52:55 2017 -0800 Committer: Taewoo Kim <wangs...@gmail.com> Committed: Thu Mar 2 08:57:50 2017 -0800 ---------------------------------------------------------------------- .../am/AbstractIntroduceAccessMethodRule.java | 28 ++++---- .../optimizer/rules/am/BTreeAccessMethod.java | 14 +++- .../queries/query-ASTERIXDB-1806.sqlpp | 69 ++++++++++++++++++++ .../results/query-ASTERIXDB-1806.plan | 25 +++++++ .../asterix/common/exceptions/ErrorCode.java | 1 + .../main/resources/asx_errormsg/en.properties | 1 + 6 files changed, 124 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/asterixdb/blob/753576f3/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java index ca042f1..d7fb0ac 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java @@ -390,19 +390,25 @@ public abstract class AbstractIntroduceAccessMethodRule implements IAlgebraicRew // complicated for now). if (funcIdent == AlgebricksBuiltinFunctions.OR) { return false; - } - boolean found = analyzeFunctionExpr(funcExpr, assignsAndUnnests, analyzedAMs, context, typeEnvironment); - for (Mutable<ILogicalExpression> arg : funcExpr.getArguments()) { - ILogicalExpression argExpr = arg.getValue(); - if (argExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { - continue; + } else if (funcIdent == AlgebricksBuiltinFunctions.AND) { + // This is the only case that the optimizer can check the given function's arguments to see + // if one of its argument can utilize an index. + boolean found = false; + for (Mutable<ILogicalExpression> arg : funcExpr.getArguments()) { + ILogicalExpression argExpr = arg.getValue(); + if (argExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { + continue; + } + AbstractFunctionCallExpression argFuncExpr = (AbstractFunctionCallExpression) argExpr; + boolean matchFound = + analyzeFunctionExpr(argFuncExpr, assignsAndUnnests, analyzedAMs, context, typeEnvironment); + found = found || matchFound; } - AbstractFunctionCallExpression argFuncExpr = (AbstractFunctionCallExpression) argExpr; - boolean matchFound = - analyzeFunctionExpr(argFuncExpr, assignsAndUnnests, analyzedAMs, context, typeEnvironment); - found = found || matchFound; + return found; + } else { + // For single function or "NOT" case: + return analyzeFunctionExpr(funcExpr, assignsAndUnnests, analyzedAMs, context, typeEnvironment); } - return found; } /** http://git-wip-us.apache.org/repos/asf/asterixdb/blob/753576f3/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java index 79ef433..3acf1f5 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java @@ -31,6 +31,8 @@ import java.util.Set; import org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation; import org.apache.asterix.common.config.DatasetConfig.DatasetType; import org.apache.asterix.common.config.DatasetConfig.IndexType; +import org.apache.asterix.common.exceptions.CompilationException; +import org.apache.asterix.common.exceptions.ErrorCode; import org.apache.asterix.lang.common.util.FunctionUtil; import org.apache.asterix.metadata.entities.Dataset; import org.apache.asterix.metadata.entities.Index; @@ -541,7 +543,11 @@ public class BTreeAccessMethod implements IAccessMethod { // If not, we create a new condition based on remaining ones. if (!primaryIndexPostProccessingIsNeeded) { List<Mutable<ILogicalExpression>> remainingFuncExprs = new ArrayList<>(); - getNewConditionExprs(conditionRef, replacedFuncExprs, remainingFuncExprs); + try { + getNewConditionExprs(conditionRef, replacedFuncExprs, remainingFuncExprs); + } catch (CompilationException e) { + return null; + } // Generate new condition. if (!remainingFuncExprs.isEmpty()) { ILogicalExpression pulledCond = createSelectCondition(remainingFuncExprs); @@ -630,7 +636,8 @@ public class BTreeAccessMethod implements IAccessMethod { } private void getNewConditionExprs(Mutable<ILogicalExpression> conditionRef, - Set<ILogicalExpression> replacedFuncExprs, List<Mutable<ILogicalExpression>> remainingFuncExprs) { + Set<ILogicalExpression> replacedFuncExprs, List<Mutable<ILogicalExpression>> remainingFuncExprs) + throws CompilationException { remainingFuncExprs.clear(); if (replacedFuncExprs.isEmpty()) { return; @@ -648,7 +655,8 @@ public class BTreeAccessMethod implements IAccessMethod { } // The original select cond must be an AND. Check it just to be sure. if (funcExpr.getFunctionIdentifier() != AlgebricksBuiltinFunctions.AND) { - throw new IllegalStateException(); + throw new CompilationException(ErrorCode.COMPILATION_FUNC_EXPRESSION_CANNOT_UTILIZE_INDEX, + funcExpr.toString()); } // Clean the conjuncts. for (Mutable<ILogicalExpression> arg : funcExpr.getArguments()) { http://git-wip-us.apache.org/repos/asf/asterixdb/blob/753576f3/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1806.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1806.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1806.sqlpp new file mode 100644 index 0000000..b7ab318 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1806.sqlpp @@ -0,0 +1,69 @@ +/* + * 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. + */ + +/* + * Description : This test case is to verify the fix for issue 1806 + * https://issues.apache.org/jira/browse/ASTERIXDB-1806 + * Expected Res : Non-index utilization Plan + */ + +drop dataverse tpch if exists; +create dataverse tpch; + +use tpch; + +create type LineItemType as + closed { + l_orderkey : integer, + l_partkey : integer, + l_suppkey : integer, + l_linenumber : integer, + l_quantity : double, + l_extendedprice : double, + l_discount : double, + l_tax : double, + l_returnflag : string, + l_linestatus : string, + l_shipdate : string, + l_commitdate : string, + l_receiptdate : string, + l_shipinstruct : string, + l_shipmode : string, + l_comment : string +} + +create dataset LineItem(LineItemType) primary key l_orderkey,l_linenumber; + +SET `import-private-functions` "true"; + +SELECT l_returnflag, + l_linestatus, + sum(l_quantity) AS sum_qty, + sum(l_extendedprice) AS sum_base_price, + sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price, + sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge, + avg(l_quantity) AS ave_qty, + avg(l_extendedprice) AS ave_price, + avg(l_discount) AS ave_disc, + count(1) AS count_order +FROM LineItem l +WHERE inject_failure(l.l_shipdate <= '1998-09-02', l.l_orderkey=5988) +GROUP BY l_returnflag, l_linestatus +ORDER BY l_returnflag, l_linestatus +; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/753576f3/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806.plan ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806.plan new file mode 100644 index 0000000..0ef1ee3 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806.plan @@ -0,0 +1,25 @@ +-- DISTRIBUTE_RESULT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- SORT_MERGE_EXCHANGE [$$16(ASC), $$17(ASC) ] |PARTITIONED| + -- SORT_GROUP_BY[$$112, $$113] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- HASH_PARTITION_EXCHANGE [$$112, $$113] |PARTITIONED| + -- SORT_GROUP_BY[$$80, $$81] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| http://git-wip-us.apache.org/repos/asf/asterixdb/blob/753576f3/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java index 70e0ae9..4898e40 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java @@ -84,6 +84,7 @@ public class ErrorCode { public static final int COMPILATION_CANT_DROP_ACTIVE_DATASET = 1023; public static final int COMPILATION_AQLPLUS_IDENTIFIER_NOT_FOUND = 1024; public static final int COMPILATION_AQLPLUS_NO_SUCH_JOIN_TYPE = 1025; + public static final int COMPILATION_FUNC_EXPRESSION_CANNOT_UTILIZE_INDEX = 1026; // Feed errors public static final int DATAFLOW_ILLEGAL_STATE = 3001; http://git-wip-us.apache.org/repos/asf/asterixdb/blob/753576f3/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties index 2bdb2a3..aae7050 100644 --- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties +++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties @@ -69,6 +69,7 @@ 1023 = Can't drop dataset %1$s since it is connected to active entity: %2$s 1024 = Identifier %1$s is not found in AQL+ meta-scope 1025 = There is no such join type in AQL+ +1026 = The given function expression %1$s cannot utilize index # Feed Errors 3001 = Illegal state.