>From Preetham Poluparthi <[email protected]>:
Preetham Poluparthi has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20946?usp=email )
Change subject: WIP: Support OR conditions in index lookups
......................................................................
WIP: Support OR conditions in index lookups
Change-Id: I5979630883e718ac0cbd3a380cb752658c47d4f5
---
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/DisjunctivePredicateToJoinRule.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
M
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/AbstractRuleController.java
4 files changed, 111 insertions(+), 20 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/46/20946/1
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/DisjunctivePredicateToJoinRule.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/DisjunctivePredicateToJoinRule.java
index 17c5e52..c3357da 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/DisjunctivePredicateToJoinRule.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/DisjunctivePredicateToJoinRule.java
@@ -59,7 +59,7 @@
public class DisjunctivePredicateToJoinRule implements IAlgebraicRewriteRule {
// Disable this rule if this option is set to 'false'
public static final String REWRITE_OR_AS_JOIN_OPTION =
"rewrite_or_as_join";
- private static final boolean REWRITE_OR_AS_JOIN_OPTION_DEFAULT = true;
+ private static final boolean REWRITE_OR_AS_JOIN_OPTION_DEFAULT = false;
private Boolean isRuleEnabled;
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 6dc0906..ab4b768 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
@@ -745,9 +745,21 @@
IVariableTypeEnvironment typeEnvironment) throws
AlgebricksException {
AbstractFunctionCallExpression funcExpr =
(AbstractFunctionCallExpression) cond;
FunctionIdentifier funcIdent = funcExpr.getFunctionIdentifier();
- // TODO: We don't consider a disjunctive condition with an index yet
since it's complex.
+ // Think about joins carefully ?
if (funcIdent == AlgebricksBuiltinFunctions.OR) {
- return false;
+ boolean found = true;
+ for (Mutable<ILogicalExpression> arg : funcExpr.getArguments()) {
+ ILogicalExpression argExpr = arg.getValue();
+ if (argExpr.getExpressionTag() !=
LogicalExpressionTag.FUNCTION_CALL) {
+ found = false;
+ break;
+ }
+ AbstractFunctionCallExpression argFuncExpr =
(AbstractFunctionCallExpression) argExpr;
+ boolean matchFound =
analyzeSelectOrJoinOpConditionAndUpdateAnalyzedAM(argFuncExpr,
assignsAndUnnests,
+ analyzedAMs, context, typeEnvironment);
+ found = found && matchFound;
+ }
+ return found;
} 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.
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 b7e2a28..26f7b01 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
@@ -19,6 +19,7 @@
package org.apache.asterix.optimizer.rules.am;
+import static
org.apache.asterix.om.types.AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE;
import static
org.apache.asterix.optimizer.rules.am.AccessMethodUtils.CAST_NULL_TYPE_CONSTRUCTORS;
import java.util.ArrayList;
@@ -30,6 +31,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.stream.Collectors;
import
org.apache.asterix.common.annotations.AbstractExpressionAnnotationWithIndexNames;
import org.apache.asterix.common.annotations.IndexedNLJoinExpressionAnnotation;
@@ -46,7 +48,9 @@
import org.apache.asterix.metadata.utils.IndexUtil;
import org.apache.asterix.metadata.utils.TypeUtil;
import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.AOrderedList;
import org.apache.asterix.om.base.IAObject;
+import org.apache.asterix.om.constants.AsterixConstantValue;
import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.asterix.om.typecomputer.base.TypeCastUtils;
import org.apache.asterix.om.typecomputer.impl.TypeComputeUtils;
@@ -69,6 +73,7 @@
import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
import
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import
org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
import
org.apache.hyracks.algebricks.core.algebra.expressions.IAlgebricksConstantValue;
import
org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import
org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
@@ -87,6 +92,7 @@
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
import
org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
import org.apache.hyracks.api.exceptions.SourceLocation;
import org.apache.hyracks.util.LogRedactionUtil;
@@ -653,24 +659,97 @@
jobGenParams.setLowKeyVarList(keyVarList, 0, numLowKeys);
jobGenParams.setHighKeyVarList(keyVarList, numLowKeys, numHighKeys);
+ boolean isOrCondition = false;
+
+ List<Mutable<ILogicalExpression>> orExprList = new ArrayList<>();
+
+ if (conditionRef.get().getExpressionTag() ==
LogicalExpressionTag.FUNCTION_CALL
+ && ((ScalarFunctionCallExpression) conditionRef.get())
+ .getFunctionIdentifier() ==
AlgebricksBuiltinFunctions.OR) {
+
+ ScalarFunctionCallExpression sfce = (ScalarFunctionCallExpression)
conditionRef.get();
+
+ isOrCondition = true;
+
+ for (Mutable<ILogicalExpression> argExpr : sfce.getArguments()) {
+
+ if (argExpr.get().getExpressionTag() !=
LogicalExpressionTag.FUNCTION_CALL) {
+ isOrCondition = false;
+ break;
+ }
+
+ ScalarFunctionCallExpression sfce2 =
(ScalarFunctionCallExpression) argExpr.get();
+ if (sfce2.getFunctionIdentifier() !=
AlgebricksBuiltinFunctions.EQ) {
+ isOrCondition = false;
+ break;
+ }
+ orExprList.add(sfce2.getArguments().get(1));
+ }
+ }
+
ILogicalOperator inputOp;
if (!assignKeyVarList.isEmpty()) {
- // Assign operator that sets the constant secondary-index
search-key fields if necessary.
- AssignOperator assignSearchKeys = new
AssignOperator(assignKeyVarList, assignKeyExprList);
- assignSearchKeys.setSourceLocation(dataSrcLoc);
- if (probeSubTree == null) {
- // We are optimizing a selection query.
- // Input to this assign is the EmptyTupleSource (which the
dataSourceScan also must have had as input).
- assignSearchKeys.getInputs().add(new MutableObject<>(
+
+ if (isOrCondition && probeSubTree == null) {
+
+ ConstantExpression constantExpression1 =
+ new ConstantExpression(new AsterixConstantValue(new
AOrderedList(FULL_OPEN_ORDEREDLIST_TYPE,
+ orExprList.stream()
+ .map(e -> (((AsterixConstantValue)
((ConstantExpression) e.get()).getValue()))
+ .getObject())
+ .collect(Collectors.toList()))));
+ ConstantExpression constantExpression2 =
+ new ConstantExpression(new AsterixConstantValue(new
AOrderedList(FULL_OPEN_ORDEREDLIST_TYPE,
+ orExprList.stream()
+ .map(e -> (((AsterixConstantValue)
((ConstantExpression) e.get()).getValue()))
+ .getObject())
+ .collect(Collectors.toList()))));
+
+ UnnestingFunctionCallExpression scanCollectionExpr1 = new
UnnestingFunctionCallExpression(
+
FunctionUtil.getFunctionInfo(BuiltinFunctions.SCAN_COLLECTION),
+ Collections.singletonList(new
MutableObject<>(constantExpression1)));
+ UnnestingFunctionCallExpression scanCollectionExpr2 = new
UnnestingFunctionCallExpression(
+
FunctionUtil.getFunctionInfo(BuiltinFunctions.SCAN_COLLECTION),
+ Collections.singletonList(new
MutableObject<>(constantExpression2)));
+
+ UnnestOperator unnestOp1 = new
UnnestOperator(assignKeyVarList.get(0),
+ new
MutableObject<ILogicalExpression>(scanCollectionExpr1));
+ UnnestOperator unnestOp2 = new
UnnestOperator(assignKeyVarList.get(1),
+ new
MutableObject<ILogicalExpression>(scanCollectionExpr2));
+
+ unnestOp1.getInputs().add(new MutableObject<>(unnestOp2));
+
+ unnestOp2.setSourceLocation(dataSrcLoc);
+ unnestOp1.setSourceLocation(dataSrcLoc);
+
+ unnestOp2.getInputs().add(new MutableObject<>(
OperatorManipulationUtil.deepCopy(dataSourceOp.getInputs().get(0).getValue())));
-
assignSearchKeys.setExecutionMode(dataSourceOp.getExecutionMode());
+
+ unnestOp1.setExecutionMode(dataSourceOp.getExecutionMode());
+ unnestOp2.setExecutionMode(dataSourceOp.getExecutionMode());
+ context.computeAndSetTypeEnvironmentForOperator(unnestOp2);
+ context.computeAndSetTypeEnvironmentForOperator(unnestOp1);
+ inputOp = unnestOp1;
+
} else {
- // We are optimizing a join, place the assign op top of the
probe subtree.
- assignSearchKeys.getInputs().add(probeSubTree.getRootRef());
-
assignSearchKeys.setExecutionMode(probeSubTree.getRootRef().getValue().getExecutionMode());
+
+ // Assign operator that sets the constant secondary-index
search-key fields if necessary.
+ AssignOperator assignSearchKeys = new
AssignOperator(assignKeyVarList, assignKeyExprList);
+ assignSearchKeys.setSourceLocation(dataSrcLoc);
+ if (probeSubTree == null) {
+ // We are optimizing a selection query.
+ // Input to this assign is the EmptyTupleSource (which the
dataSourceScan also must have had as input).
+ assignSearchKeys.getInputs().add(new MutableObject<>(
+
OperatorManipulationUtil.deepCopy(dataSourceOp.getInputs().get(0).getValue())));
+
assignSearchKeys.setExecutionMode(dataSourceOp.getExecutionMode());
+ } else {
+ // We are optimizing a join, place the assign op top of
the probe subtree.
+
assignSearchKeys.getInputs().add(probeSubTree.getRootRef());
+
assignSearchKeys.setExecutionMode(probeSubTree.getRootRef().getValue().getExecutionMode());
+ }
+
context.computeAndSetTypeEnvironmentForOperator(assignSearchKeys);
+ inputOp = assignSearchKeys;
}
- context.computeAndSetTypeEnvironmentForOperator(assignSearchKeys);
- inputOp = assignSearchKeys;
} else if (probeSubTree == null) {
//nonpure case
//Make sure that the nonpure function is unpartitioned
diff --git
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/AbstractRuleController.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/AbstractRuleController.java
index dca5d62..36b2c54 100644
---
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/AbstractRuleController.java
+++
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/AbstractRuleController.java
@@ -41,7 +41,7 @@
protected IOptimizationContext context;
public AbstractRuleController() {
- isTraceEnabled = AlgebricksConfig.ALGEBRICKS_LOGGER.isTraceEnabled();
+ isTraceEnabled = true;
}
public void setContext(IOptimizationContext context) {
@@ -186,9 +186,9 @@
private void printRuleApplication(IAlgebraicRewriteRule rule, String
status, String beforePlan, String afterPlan) {
if (isTraceEnabled) {
- AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">> Rule " +
rule.getClass().getName() + " " + status + "\n");
- AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">> Before plan\n" +
LogRedactionUtil.userData(beforePlan) + "\n");
- AlgebricksConfig.ALGEBRICKS_LOGGER.trace(">> After plan\n" +
LogRedactionUtil.userData(afterPlan) + "\n");
+ AlgebricksConfig.ALGEBRICKS_LOGGER.info(">> Rule " +
rule.getClass().getName() + " " + status + "\n");
+ AlgebricksConfig.ALGEBRICKS_LOGGER.info(">> Before plan\n" +
LogRedactionUtil.userData(beforePlan) + "\n");
+ AlgebricksConfig.ALGEBRICKS_LOGGER.info(">> After plan\n" +
LogRedactionUtil.userData(afterPlan) + "\n");
}
}
}
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20946?usp=email
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I5979630883e718ac0cbd3a380cb752658c47d4f5
Gerrit-Change-Number: 20946
Gerrit-PatchSet: 1
Gerrit-Owner: Preetham Poluparthi <[email protected]>