Taewoo Kim has uploaded a new change for review.
https://asterix-gerrit.ics.uci.edu/637
Change subject: Added LeftOuterUnnestMap operator.
......................................................................
Added LeftOuterUnnestMap operator.
- Added LeftOuterUnnestMap operator to represent the left-outer-join semantics
properly.
Change-Id: I6760319c2d3ff90c8b7d8ddeea3d9dd8f743366b
---
M
asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/BTreeSearchPOperator.java
M
asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/InvertedIndexPOperator.java
M
asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/RTreeSearchPOperator.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SetAsterixPhysicalOperatorsRule.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SweepIllegalNonfunctionalFunctions.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeAccessMethod.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineLeftNtsInSubplanJoinFlatteningVisitor.java
M
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanSpecialFlatteningCheckVisitor.java
13 files changed, 312 insertions(+), 60 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/37/637/1
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/BTreeSearchPOperator.java
b/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/BTreeSearchPOperator.java
index da7d9c6..bd515d9 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/BTreeSearchPOperator.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/BTreeSearchPOperator.java
@@ -34,6 +34,7 @@
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+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.base.PhysicalOperatorTag;
import
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
@@ -41,6 +42,7 @@
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.core.algebra.metadata.IDataSourceIndex;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
@@ -94,8 +96,30 @@
public void contributeRuntimeOperator(IHyracksJobBuilder builder,
JobGenContext context, ILogicalOperator op,
IOperatorSchema opSchema, IOperatorSchema[] inputSchemas,
IOperatorSchema outerPlanSchema)
throws AlgebricksException {
- UnnestMapOperator unnestMap = (UnnestMapOperator) op;
- ILogicalExpression unnestExpr =
unnestMap.getExpressionRef().getValue();
+ // We have two types of unnest-map operator - UNNEST_MAP and
+ // LEFT_OUTER_UNNEST_MAP
+ UnnestMapOperator unnestMapOp = null;
+ LeftOuterUnnestMapOperator leftOuterUnnestMapOp = null;
+ ILogicalOperator unnestMap = null;
+ ILogicalExpression unnestExpr = null;
+ List<LogicalVariable> minFilterVarList = null;
+ List<LogicalVariable> maxFilterVarList = null;
+ List<LogicalVariable> outputVars = null;
+ if (op.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
+ unnestMapOp = (UnnestMapOperator) op;
+ unnestExpr = unnestMapOp.getExpressionRef().getValue();
+ minFilterVarList = unnestMapOp.getMinFilterVars();
+ maxFilterVarList = unnestMapOp.getMaxFilterVars();
+ outputVars = unnestMapOp.getVariables();
+ unnestMap = unnestMapOp;
+ } else if (op.getOperatorTag() ==
LogicalOperatorTag.LEFT_OUTER_UNNEST_MAP) {
+ leftOuterUnnestMapOp = (LeftOuterUnnestMapOperator) op;
+ unnestExpr =
leftOuterUnnestMapOp.getExpressionRef().getValue();
+ minFilterVarList =
leftOuterUnnestMapOp.getMinFilterVars();
+ maxFilterVarList =
leftOuterUnnestMapOp.getMaxFilterVars();
+ outputVars = leftOuterUnnestMapOp.getVariables();
+ unnestMap = leftOuterUnnestMapOp;
+ }
if (unnestExpr.getExpressionTag() !=
LogicalExpressionTag.FUNCTION_CALL) {
throw new IllegalStateException();
}
@@ -109,13 +133,14 @@
int[] lowKeyIndexes = getKeyIndexes(jobGenParams.getLowKeyVarList(),
inputSchemas);
int[] highKeyIndexes = getKeyIndexes(jobGenParams.getHighKeyVarList(),
inputSchemas);
- int[] minFilterFieldIndexes =
getKeyIndexes(unnestMap.getMinFilterVars(), inputSchemas);
- int[] maxFilterFieldIndexes =
getKeyIndexes(unnestMap.getMaxFilterVars(), inputSchemas);
+ int[] minFilterFieldIndexes = getKeyIndexes(minFilterVarList,
+ inputSchemas);
+ int[] maxFilterFieldIndexes = getKeyIndexes(maxFilterVarList,
+ inputSchemas);
AqlMetadataProvider metadataProvider = (AqlMetadataProvider)
context.getMetadataProvider();
Dataset dataset =
metadataProvider.findDataset(jobGenParams.getDataverseName(),
jobGenParams.getDatasetName());
IVariableTypeEnvironment typeEnv = context.getTypeEnvironment(op);
- List<LogicalVariable> outputVars = unnestMap.getVariables();
if (jobGenParams.getRetainInput()) {
outputVars = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(unnestMap, outputVars);
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/InvertedIndexPOperator.java
b/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/InvertedIndexPOperator.java
index 0e5850b..7373caf 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/InvertedIndexPOperator.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/InvertedIndexPOperator.java
@@ -53,6 +53,7 @@
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+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.base.PhysicalOperatorTag;
import
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
@@ -60,6 +61,7 @@
import
org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import org.apache.hyracks.algebricks.core.algebra.metadata.IDataSourceIndex;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import org.apache.hyracks.algebricks.core.jobgen.impl.JobGenContext;
@@ -107,8 +109,30 @@
public void contributeRuntimeOperator(IHyracksJobBuilder builder,
JobGenContext context, ILogicalOperator op,
IOperatorSchema opSchema, IOperatorSchema[] inputSchemas,
IOperatorSchema outerPlanSchema)
throws AlgebricksException {
- UnnestMapOperator unnestMapOp = (UnnestMapOperator) op;
- ILogicalExpression unnestExpr =
unnestMapOp.getExpressionRef().getValue();
+ // We have two types of unnest-map operator - UNNEST_MAP and
+ // LEFT_OUTER_UNNEST_MAP
+ UnnestMapOperator unnestMapOp = null;
+ LeftOuterUnnestMapOperator leftOuterUnnestMapOp = null;
+ ILogicalOperator unnestMap = null;
+ ILogicalExpression unnestExpr = null;
+ List<LogicalVariable> minFilterVarList = null;
+ List<LogicalVariable> maxFilterVarList = null;
+ List<LogicalVariable> outputVars = null;
+ if (op.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
+ unnestMapOp = (UnnestMapOperator) op;
+ unnestExpr = unnestMapOp.getExpressionRef().getValue();
+ minFilterVarList = unnestMapOp.getMinFilterVars();
+ maxFilterVarList = unnestMapOp.getMaxFilterVars();
+ outputVars = unnestMapOp.getVariables();
+ unnestMap = unnestMapOp;
+ } else if (op.getOperatorTag() ==
LogicalOperatorTag.LEFT_OUTER_UNNEST_MAP) {
+ leftOuterUnnestMapOp = (LeftOuterUnnestMapOperator) op;
+ unnestExpr =
leftOuterUnnestMapOp.getExpressionRef().getValue();
+ minFilterVarList =
leftOuterUnnestMapOp.getMinFilterVars();
+ maxFilterVarList =
leftOuterUnnestMapOp.getMaxFilterVars();
+ outputVars = leftOuterUnnestMapOp.getVariables();
+ unnestMap = leftOuterUnnestMapOp;
+ }
if (unnestExpr.getExpressionTag() !=
LogicalExpressionTag.FUNCTION_CALL) {
throw new IllegalStateException();
}
@@ -129,25 +153,29 @@
}
int[] keyIndexes = getKeyIndexes(jobGenParams.getKeyVarList(),
inputSchemas);
- int[] minFilterFieldIndexes =
getKeyIndexes(unnestMapOp.getMinFilterVars(), inputSchemas);
- int[] maxFilterFieldIndexes =
getKeyIndexes(unnestMapOp.getMaxFilterVars(), inputSchemas);
+ int[] minFilterFieldIndexes = getKeyIndexes(minFilterVarList,
+ inputSchemas);
+ int[] maxFilterFieldIndexes = getKeyIndexes(maxFilterVarList,
+ inputSchemas);
// Build runtime.
Pair<IOperatorDescriptor, AlgebricksPartitionConstraint>
invIndexSearch = buildInvertedIndexRuntime(
- metadataProvider, context, builder.getJobSpec(), unnestMapOp,
opSchema, jobGenParams.getRetainInput(),
+ metadataProvider, context,
builder.getJobSpec(), unnestMap,
+ opSchema, jobGenParams.getRetainInput(),
jobGenParams.getRetainNull(), jobGenParams.getDatasetName(),
dataset, jobGenParams.getIndexName(),
jobGenParams.getSearchKeyType(), keyIndexes,
jobGenParams.getSearchModifierType(),
jobGenParams.getSimilarityThreshold(), minFilterFieldIndexes,
maxFilterFieldIndexes);
// Contribute operator in hyracks job.
- builder.contributeHyracksOperator(unnestMapOp, invIndexSearch.first);
+ builder.contributeHyracksOperator(unnestMap,
invIndexSearch.first);
builder.contributeAlgebricksPartitionConstraint(invIndexSearch.first,
invIndexSearch.second);
- ILogicalOperator srcExchange =
unnestMapOp.getInputs().get(0).getValue();
- builder.contributeGraphEdge(srcExchange, 0, unnestMapOp, 0);
+ ILogicalOperator srcExchange =
unnestMap.getInputs().get(0).getValue();
+ builder.contributeGraphEdge(srcExchange, 0, unnestMap, 0);
}
public Pair<IOperatorDescriptor, AlgebricksPartitionConstraint>
buildInvertedIndexRuntime(
AqlMetadataProvider metadataProvider, JobGenContext context,
JobSpecification jobSpec,
- UnnestMapOperator unnestMap, IOperatorSchema opSchema, boolean
retainInput, boolean retainNull,
+ ILogicalOperator unnestMap,
+ IOperatorSchema opSchema, boolean retainInput, boolean
retainNull,
String datasetName, Dataset dataset, String indexName, ATypeTag
searchKeyType, int[] keyFields,
SearchModifierType searchModifierType, IAlgebricksConstantValue
similarityThreshold,
int[] minFilterFieldIndexes, int[] maxFilterFieldIndexes) throws
AlgebricksException {
@@ -201,7 +229,15 @@
}
IVariableTypeEnvironment typeEnv =
context.getTypeEnvironment(unnestMap);
- List<LogicalVariable> outputVars = unnestMap.getVariables();
+ List<LogicalVariable> outputVars = null;
+
+ if (unnestMap.getOperatorTag() ==
LogicalOperatorTag.LEFT_OUTER_UNNEST_MAP) {
+ outputVars = ((LeftOuterUnnestMapOperator)
unnestMap)
+ .getVariables();
+ } else if (unnestMap.getOperatorTag() ==
LogicalOperatorTag.UNNEST_MAP) {
+ outputVars = ((UnnestMapOperator)
unnestMap).getVariables();
+ }
+
if (retainInput) {
outputVars = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(unnestMap, outputVars);
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/RTreeSearchPOperator.java
b/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/RTreeSearchPOperator.java
index d54d7f4..042c49b 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/RTreeSearchPOperator.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/RTreeSearchPOperator.java
@@ -33,6 +33,7 @@
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+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.base.PhysicalOperatorTag;
import
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
@@ -40,6 +41,7 @@
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.core.algebra.metadata.IDataSourceIndex;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import org.apache.hyracks.algebricks.core.jobgen.impl.JobGenContext;
@@ -64,8 +66,30 @@
public void contributeRuntimeOperator(IHyracksJobBuilder builder,
JobGenContext context, ILogicalOperator op,
IOperatorSchema opSchema, IOperatorSchema[] inputSchemas,
IOperatorSchema outerPlanSchema)
throws AlgebricksException {
- UnnestMapOperator unnestMap = (UnnestMapOperator) op;
- ILogicalExpression unnestExpr =
unnestMap.getExpressionRef().getValue();
+ // We have two types of unnest-map operator - UNNEST_MAP and
+ // LEFT_OUTER_UNNEST_MAP
+ UnnestMapOperator unnestMapOp = null;
+ LeftOuterUnnestMapOperator leftOuterUnnestMapOp = null;
+ ILogicalOperator unnestMap = null;
+ ILogicalExpression unnestExpr = null;
+ List<LogicalVariable> minFilterVarList = null;
+ List<LogicalVariable> maxFilterVarList = null;
+ List<LogicalVariable> outputVars = null;
+ if (op.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
+ unnestMapOp = (UnnestMapOperator) op;
+ unnestExpr = unnestMapOp.getExpressionRef().getValue();
+ minFilterVarList = unnestMapOp.getMinFilterVars();
+ maxFilterVarList = unnestMapOp.getMaxFilterVars();
+ outputVars = unnestMapOp.getVariables();
+ unnestMap = unnestMapOp;
+ } else if (op.getOperatorTag() ==
LogicalOperatorTag.LEFT_OUTER_UNNEST_MAP) {
+ leftOuterUnnestMapOp = (LeftOuterUnnestMapOperator) op;
+ unnestExpr =
leftOuterUnnestMapOp.getExpressionRef().getValue();
+ minFilterVarList =
leftOuterUnnestMapOp.getMinFilterVars();
+ maxFilterVarList =
leftOuterUnnestMapOp.getMaxFilterVars();
+ outputVars = leftOuterUnnestMapOp.getVariables();
+ unnestMap = leftOuterUnnestMapOp;
+ }
if (unnestExpr.getExpressionTag() !=
LogicalExpressionTag.FUNCTION_CALL) {
throw new IllegalStateException();
}
@@ -78,13 +102,14 @@
jobGenParams.readFromFuncArgs(unnestFuncExpr.getArguments());
int[] keyIndexes = getKeyIndexes(jobGenParams.getKeyVarList(),
inputSchemas);
- int[] minFilterFieldIndexes =
getKeyIndexes(unnestMap.getMinFilterVars(), inputSchemas);
- int[] maxFilterFieldIndexes =
getKeyIndexes(unnestMap.getMaxFilterVars(), inputSchemas);
+ int[] minFilterFieldIndexes = getKeyIndexes(minFilterVarList,
+ inputSchemas);
+ int[] maxFilterFieldIndexes = getKeyIndexes(maxFilterVarList,
+ inputSchemas);
AqlMetadataProvider mp = (AqlMetadataProvider)
context.getMetadataProvider();
Dataset dataset = mp.findDataset(jobGenParams.getDataverseName(),
jobGenParams.getDatasetName());
IVariableTypeEnvironment typeEnv =
context.getTypeEnvironment(unnestMap);
- List<LogicalVariable> outputVars = unnestMap.getVariables();
if (jobGenParams.getRetainInput()) {
outputVars = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(unnestMap, outputVars);
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SetAsterixPhysicalOperatorsRule.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SetAsterixPhysicalOperatorsRule.java
index 353c9be..b4cb57e 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SetAsterixPhysicalOperatorsRule.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SetAsterixPhysicalOperatorsRule.java
@@ -21,9 +21,6 @@
import java.util.ArrayList;
import java.util.List;
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.commons.lang3.mutable.MutableObject;
-
import org.apache.asterix.algebra.operators.physical.BTreeSearchPOperator;
import org.apache.asterix.algebra.operators.physical.InvertedIndexPOperator;
import org.apache.asterix.algebra.operators.physical.RTreeSearchPOperator;
@@ -33,6 +30,8 @@
import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
import org.apache.asterix.optimizer.rules.am.AccessMethodJobGenParams;
import org.apache.asterix.optimizer.rules.am.BTreeJobGenParams;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
import org.apache.hyracks.algebricks.common.utils.Pair;
@@ -56,6 +55,7 @@
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.physical.ExternalGroupByPOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.physical.PreclusteredGroupByPOperator;
@@ -198,9 +198,16 @@
JoinUtils.setJoinAlgorithmAndExchangeAlgo((LeftOuterJoinOperator) op, context);
break;
}
- case UNNEST_MAP: {
- UnnestMapOperator unnestMap = (UnnestMapOperator) op;
- ILogicalExpression unnestExpr =
unnestMap.getExpressionRef().getValue();
+ case UNNEST_MAP:
+ case LEFT_OUTER_UNNEST_MAP: {
+ ILogicalExpression unnestExpr = null;
+ if (op.getOperatorTag() ==
LogicalOperatorTag.UNNEST_MAP) {
+ unnestExpr = ((UnnestMapOperator)
op).getExpressionRef()
+ .getValue();
+ } else if (op.getOperatorTag() ==
LogicalOperatorTag.LEFT_OUTER_UNNEST_MAP) {
+ unnestExpr =
((LeftOuterUnnestMapOperator) op)
+
.getExpressionRef().getValue();
+ }
if (unnestExpr.getExpressionTag() ==
LogicalExpressionTag.FUNCTION_CALL) {
AbstractFunctionCallExpression f =
(AbstractFunctionCallExpression) unnestExpr;
FunctionIdentifier fid = f.getFunctionIdentifier();
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SweepIllegalNonfunctionalFunctions.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SweepIllegalNonfunctionalFunctions.java
index 238eaa3..23c5dca 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SweepIllegalNonfunctionalFunctions.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SweepIllegalNonfunctionalFunctions.java
@@ -44,6 +44,7 @@
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.InsertDeleteUpsertOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.IntersectOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
@@ -253,6 +254,11 @@
public Void visitUnnestMapOperator(UnnestMapOperator op, Void arg)
throws AlgebricksException {
return null;
}
+
+ @Override
+ public Void visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator
op, Void arg) throws AlgebricksException {
+ return null;
+ }
@Override
public Void visitDataScanOperator(DataSourceScanOperator op, Void arg)
throws AlgebricksException {
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
index 9165506..f43f8ce 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
@@ -71,6 +71,7 @@
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.ExternalDataLookupOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
@@ -307,7 +308,17 @@
numPrimaryKeys = DatasetUtils.getPartitioningKeys(dataset).size();
}
List<LogicalVariable> primaryKeyVars = new
ArrayList<LogicalVariable>();
- List<LogicalVariable> sourceVars = ((UnnestMapOperator)
unnestMapOp).getVariables();
+ List<LogicalVariable> sourceVars = null;
+
+ // For a left outer join case, LEFT_OUTER_UNNEST_MAP operator
is placed
+ // instead of UNNEST_MAP operator.
+ if (unnestMapOp.getOperatorTag() ==
LogicalOperatorTag.UNNEST_MAP) {
+ sourceVars = ((UnnestMapOperator)
unnestMapOp).getVariables();
+ } else if (unnestMapOp.getOperatorTag() ==
LogicalOperatorTag.LEFT_OUTER_UNNEST_MAP) {
+ sourceVars = ((LeftOuterUnnestMapOperator) unnestMapOp)
+ .getVariables();
+ }
+
// Assumes the primary keys are located at the end.
int start = sourceVars.size() - numPrimaryKeys;
int stop = sourceVars.size();
@@ -321,7 +332,16 @@
ILogicalOperator unnestMapOp) {
int numPrimaryKeys = DatasetUtils.getPartitioningKeys(dataset).size();
List<LogicalVariable> primaryKeyVars = new
ArrayList<LogicalVariable>();
- List<LogicalVariable> sourceVars = ((UnnestMapOperator)
unnestMapOp).getVariables();
+ List<LogicalVariable> sourceVars = null;
+
+ // For a left outer join case, LEFT_OUTER_UNNEST_MAP operator
is placed
+ // instead of UNNEST_MAP operator.
+ if (unnestMapOp.getOperatorTag() ==
LogicalOperatorTag.UNNEST_MAP) {
+ sourceVars = ((UnnestMapOperator)
unnestMapOp).getVariables();
+ } else if (unnestMapOp.getOperatorTag() ==
LogicalOperatorTag.LEFT_OUTER_UNNEST_MAP) {
+ sourceVars = ((LeftOuterUnnestMapOperator) unnestMapOp)
+ .getVariables();
+ }
// Assumes the primary keys are located at the beginning.
for (int i = 0; i < numPrimaryKeys; i++) {
primaryKeyVars.add(sourceVars.get(i));
@@ -423,7 +443,7 @@
return indexExprs.get(0).second;
}
- public static UnnestMapOperator createSecondaryIndexUnnestMap(Dataset
dataset, ARecordType recordType, Index index,
+ public static ILogicalOperator createSecondaryIndexUnnestMap(Dataset
dataset, ARecordType recordType, Index index,
ILogicalOperator inputOp, AccessMethodJobGenParams jobGenParams,
IOptimizationContext context,
boolean outputPrimaryKeysOnly, boolean retainInput) throws
AlgebricksException {
// The job gen parameters are transferred to the actual job gen via
the UnnestMapOperator's function arguments.
@@ -443,14 +463,33 @@
secondaryIndexSearchFunc.setReturnsUniqueValues(true);
// This is the operator that jobgen will be looking for. It contains
an unnest function that has all necessary arguments to determine
// which index to use, which variables contain the index-search keys,
what is the original dataset, etc.
- UnnestMapOperator secondaryIndexUnnestOp = new
UnnestMapOperator(secondaryIndexUnnestVars,
- new
MutableObject<ILogicalExpression>(secondaryIndexSearchFunc),
secondaryIndexOutputTypes,
- retainInput);
- secondaryIndexUnnestOp.getInputs().add(new
MutableObject<ILogicalOperator>(inputOp));
-
context.computeAndSetTypeEnvironmentForOperator(secondaryIndexUnnestOp);
- secondaryIndexUnnestOp.setExecutionMode(ExecutionMode.PARTITIONED);
- return secondaryIndexUnnestOp;
- }
+
+ // Left-outer-join (retainInput and retainNull) case?
+ // Then, we use the LEFT-OUTER-UNNEST-MAP operator instead of
unnest-map operator.
+ if (jobGenParams.getRetainNull()) {
+ if (retainInput) {
+ LeftOuterUnnestMapOperator secondaryIndexLeftOuterUnnestOp =
new LeftOuterUnnestMapOperator(
+ secondaryIndexUnnestVars, new
MutableObject<ILogicalExpression>(secondaryIndexSearchFunc),
+ secondaryIndexOutputTypes);
+ secondaryIndexLeftOuterUnnestOp.getInputs().add(new
MutableObject<ILogicalOperator>(inputOp));
+
context.computeAndSetTypeEnvironmentForOperator(secondaryIndexLeftOuterUnnestOp);
+
secondaryIndexLeftOuterUnnestOp.setExecutionMode(ExecutionMode.PARTITIONED);
+ return secondaryIndexLeftOuterUnnestOp;
+ } else {
+ // Left-outer-join without retainNull and retainInput doesn't
make sense.
+ throw new AlgebricksException("Left-outer-join should
propagate all inputs from the outer branch.");
+ }
+ } else {
+ // If this is not a left-outer-join case, then we use UNNEST-MAP
operator.
+ UnnestMapOperator secondaryIndexUnnestOp = new
UnnestMapOperator(secondaryIndexUnnestVars,
+ new
MutableObject<ILogicalExpression>(secondaryIndexSearchFunc),
secondaryIndexOutputTypes,
+ retainInput);
+ secondaryIndexUnnestOp.getInputs().add(new
MutableObject<ILogicalOperator>(inputOp));
+
context.computeAndSetTypeEnvironmentForOperator(secondaryIndexUnnestOp);
+ secondaryIndexUnnestOp.setExecutionMode(ExecutionMode.PARTITIONED);
+ return secondaryIndexUnnestOp;
+ }
+ }
public static UnnestMapOperator
createPrimaryIndexUnnestMap(AbstractDataSourceOperator dataSourceOp,
Dataset dataset, ARecordType recordType, ILogicalOperator inputOp,
IOptimizationContext context,
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
index 370b90d..b1356f7 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
@@ -34,6 +34,7 @@
import org.apache.asterix.lang.common.util.FunctionUtil;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.Index;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
import org.apache.asterix.om.types.ARecordType;
import org.apache.asterix.optimizer.rules.util.EquivalenceClassUtils;
import org.apache.commons.lang3.mutable.Mutable;
@@ -49,6 +50,7 @@
import
org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import
org.apache.hyracks.algebricks.core.algebra.expressions.IndexedNLJoinExpressionAnnotation;
import
org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import
org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
import
org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
import
org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
import
org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions.ComparisonKind;
@@ -59,8 +61,8 @@
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
-import
org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.ExternalDataLookupOperator;
+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.util.OperatorManipulationUtil;
@@ -481,11 +483,15 @@
inputOp = probeSubTree.root;
}
- UnnestMapOperator secondaryIndexUnnestOp =
AccessMethodUtils.createSecondaryIndexUnnestMap(dataset, recordType,
+ ILogicalOperator secondaryIndexUnnestOp = AccessMethodUtils
+ .createSecondaryIndexUnnestMap(dataset,
recordType,
chosenIndex, inputOp, jobGenParams, context, false,
retainInput);
// Generate the rest of the upstream plan which feeds the search
results into the primary index.
UnnestMapOperator primaryIndexUnnestOp = null;
+ LeftOuterUnnestMapOperator leftOuterPrimaryIndexUnnestOp = null;
+ ILogicalOperator finalPrimaryIndexUnnestOp = null;
+
boolean isPrimaryIndex = chosenIndex.isPrimaryIndex();
if (dataset.getDatasetType() == DatasetType.EXTERNAL) {
// External dataset
@@ -494,12 +500,15 @@
retainNull);
return externalDataAccessOp;
} else if (!isPrimaryIndex) {
- primaryIndexUnnestOp =
AccessMethodUtils.createPrimaryIndexUnnestMap(dataSourceOp, dataset, recordType,
+ finalPrimaryIndexUnnestOp = AccessMethodUtils
+
.createPrimaryIndexUnnestMap(dataSourceOp, dataset,
+ recordType,
secondaryIndexUnnestOp, context, true, retainInput,
retainNull, false);
// Adds equivalence classes --- one equivalent class between a
primary key
// variable and a record field-access expression.
-
EquivalenceClassUtils.addEquivalenceClassesForPrimaryIndexAccess(primaryIndexUnnestOp,
+
EquivalenceClassUtils.addEquivalenceClassesForPrimaryIndexAccess(
+ finalPrimaryIndexUnnestOp,
dataSourceOp.getVariables(), recordType, dataset, context);
} else {
List<Object> primaryIndexOutputTypes = new ArrayList<Object>();
@@ -508,30 +517,89 @@
} catch (IOException e) {
throw new AlgebricksException(e);
}
- List<LogicalVariable> scanVariables = dataSourceOp.getVariables();
- primaryIndexUnnestOp = new UnnestMapOperator(scanVariables,
secondaryIndexUnnestOp.getExpressionRef(),
- primaryIndexOutputTypes, retainInput);
- primaryIndexUnnestOp.getInputs().add(new
MutableObject<ILogicalOperator>(inputOp));
- if (!primaryIndexPostProccessingIsNeeded) {
- List<Mutable<ILogicalExpression>> remainingFuncExprs = new
ArrayList<Mutable<ILogicalExpression>>();
- getNewConditionExprs(conditionRef, replacedFuncExprs,
remainingFuncExprs);
- // Generate new condition.
- if (!remainingFuncExprs.isEmpty()) {
- ILogicalExpression pulledCond =
createSelectCondition(remainingFuncExprs);
- conditionRef.setValue(pulledCond);
+ List<LogicalVariable> scanVariables =
dataSourceOp.getVariables();
+
+ // Checks whether the primary index search can replace
the given
+ // SELECT condition.
+ // If so, condition will be set to null and eventually
the SELECT
+ // operator will be removed.
+ // If not, we create a new condition based on remaining
ones.
+ if (!primaryIndexPostProccessingIsNeeded) {
+ List<Mutable<ILogicalExpression>>
remainingFuncExprs = new ArrayList<Mutable<ILogicalExpression>>();
+ getNewConditionExprs(conditionRef,
replacedFuncExprs,
+ remainingFuncExprs);
+ // Generate new condition.
+ if (!remainingFuncExprs.isEmpty()) {
+ ILogicalExpression pulledCond =
createSelectCondition(remainingFuncExprs);
+ conditionRef.setValue(pulledCond);
+ } else {
+ conditionRef.setValue(null);
+ }
+ }
+
+ // Checks whether LEFT_OUTER_UNNESTMAP operator is
required.
+ boolean leftOuterUnnestMapRequired = false;
+ if (retainNull && retainInput) {
+ leftOuterUnnestMapRequired = true;
+ } else {
+ leftOuterUnnestMapRequired = false;
+ }
+
+ if (conditionRef.getValue() != null) {
+ // The job gen parameters are transferred to
the actual job gen
+ // via the UnnestMapOperator's function
arguments.
+ ArrayList<Mutable<ILogicalExpression>>
primaryIndexFuncArgs = new ArrayList<Mutable<ILogicalExpression>>();
+
jobGenParams.writeToFuncArgs(primaryIndexFuncArgs);
+ // An index search is expressed as an
unnest-map over an
+ // index-search function.
+ IFunctionInfo primaryIndexSearch = FunctionUtil
+
.getFunctionInfo(AsterixBuiltinFunctions.INDEX_SEARCH);
+ UnnestingFunctionCallExpression
primaryIndexSearchFunc = new UnnestingFunctionCallExpression(
+ primaryIndexSearch,
primaryIndexFuncArgs);
+
primaryIndexSearchFunc.setReturnsUniqueValues(true);
+ if (!leftOuterUnnestMapRequired) {
+ primaryIndexUnnestOp = new
UnnestMapOperator(scanVariables,
+ new
MutableObject<ILogicalExpression>(
+
primaryIndexSearchFunc),
+
primaryIndexOutputTypes, retainInput);
+ finalPrimaryIndexUnnestOp =
primaryIndexUnnestOp;
+ } else {
+ leftOuterPrimaryIndexUnnestOp = new
LeftOuterUnnestMapOperator(
+ scanVariables,
+ new
MutableObject<ILogicalExpression>(
+
primaryIndexSearchFunc),
+
primaryIndexOutputTypes);
+ finalPrimaryIndexUnnestOp =
leftOuterPrimaryIndexUnnestOp;
+ }
+ } else {
+ if (!leftOuterUnnestMapRequired) {
+ primaryIndexUnnestOp = new
UnnestMapOperator(scanVariables,
+ ((UnnestMapOperator)
secondaryIndexUnnestOp)
+
.getExpressionRef(),
+
primaryIndexOutputTypes, retainInput);
+ finalPrimaryIndexUnnestOp =
primaryIndexUnnestOp;
} else {
- conditionRef.setValue(null);
+ leftOuterPrimaryIndexUnnestOp = new
LeftOuterUnnestMapOperator(
+ scanVariables,
+
((LeftOuterUnnestMapOperator) secondaryIndexUnnestOp)
+
.getExpressionRef(),
+
primaryIndexOutputTypes);
+ finalPrimaryIndexUnnestOp =
leftOuterPrimaryIndexUnnestOp;
}
}
+ finalPrimaryIndexUnnestOp.getInputs().add(
+ new
MutableObject<ILogicalOperator>(inputOp));
+
// Adds equivalence classes --- one equivalent class between a
primary key
// variable and a record field-access expression.
-
EquivalenceClassUtils.addEquivalenceClassesForPrimaryIndexAccess(primaryIndexUnnestOp,
scanVariables,
- recordType, dataset, context);
- }
+
EquivalenceClassUtils.addEquivalenceClassesForPrimaryIndexAccess(
+ finalPrimaryIndexUnnestOp,
scanVariables, recordType,
+ dataset, context);
+ }
- return primaryIndexUnnestOp;
+ return finalPrimaryIndexUnnestOp;
}
private int createKeyVarsAndExprs(int numKeys, LimitType[] keyLimits,
ILogicalExpression[] searchKeyExprs,
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
index d8e4c6a..735c8c5 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
@@ -66,7 +66,6 @@
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
-import
org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
@@ -406,7 +405,8 @@
inputOp = (AbstractLogicalOperator) probeSubTree.root;
}
jobGenParams.setKeyVarList(keyVarList);
- UnnestMapOperator secondaryIndexUnnestOp =
AccessMethodUtils.createSecondaryIndexUnnestMap(dataset, recordType,
+ ILogicalOperator secondaryIndexUnnestOp = AccessMethodUtils
+ .createSecondaryIndexUnnestMap(dataset,
recordType,
chosenIndex, inputOp, jobGenParams, context, true,
retainInput);
// Generate the rest of the upstream plan which feeds the search
results into the primary index.
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
index 52582ba..5cb0f1e 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
@@ -82,8 +82,32 @@
rootRef = subTreeOpRef;
root = subTreeOpRef.getValue();
// Examine the op's children to match the expected patterns.
+ // Pattern: limit? <- (assign | unnest)+ <- order? <- select <-
(assign
+ // | unnest)+ <- datasource?
AbstractLogicalOperator subTreeOp = (AbstractLogicalOperator)
subTreeOpRef.getValue();
do {
+ // Skip LIMIT if one is present.
+ if (subTreeOp.getOperatorTag() ==
LogicalOperatorTag.LIMIT) {
+ subTreeOpRef = subTreeOp.getInputs().get(0);
+ subTreeOp = (AbstractLogicalOperator)
subTreeOpRef.getValue();
+ // subTreeOp = (AbstractLogicalOperator)
+ // subTreeOp.getInputs().get(0).getValue();
+ }
+ // Match (assign | unnest)+.
+ while (subTreeOp.getOperatorTag() ==
LogicalOperatorTag.ASSIGN
+ || subTreeOp.getOperatorTag() ==
LogicalOperatorTag.UNNEST) {
+ assignsAndUnnestsRefs.add(subTreeOpRef);
+ assignsAndUnnests.add(subTreeOp);
+
+ subTreeOpRef = subTreeOp.getInputs().get(0);
+ subTreeOp = (AbstractLogicalOperator)
subTreeOpRef.getValue();
+ }
+ ;
+ // Skip ORDER operator if one is present.
+ if (subTreeOp.getOperatorTag() ==
LogicalOperatorTag.ORDER) {
+ subTreeOpRef = subTreeOp.getInputs().get(0);
+ subTreeOp = (AbstractLogicalOperator)
subTreeOpRef.getValue();
+ }
// Skip select operator.
if (subTreeOp.getOperatorTag() == LogicalOperatorTag.SELECT) {
subTreeOpRef = subTreeOp.getInputs().get(0);
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeAccessMethod.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeAccessMethod.java
index c5bd8af..2b2b8ea 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeAccessMethod.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeAccessMethod.java
@@ -239,7 +239,8 @@
assignSearchKeys.getInputs().add(probeSubTree.rootRef);
}
- UnnestMapOperator secondaryIndexUnnestOp =
AccessMethodUtils.createSecondaryIndexUnnestMap(dataset, recordType,
+ ILogicalOperator secondaryIndexUnnestOp = AccessMethodUtils
+ .createSecondaryIndexUnnestMap(dataset,
recordType,
chosenIndex, assignSearchKeys, jobGenParams, context, false,
retainInput);
// Generate the rest of the upstream plan which feeds the search
results into the primary index.
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
index 0715d46..a558a2c 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
@@ -59,6 +59,7 @@
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.IntersectOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
@@ -566,6 +567,13 @@
}
@Override
+ public ILogicalOperator
visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op, Void arg)
+ throws AlgebricksException {
+ // This operator always propagates all inputs.
+ return visitSingleInputOperator(op);
+ }
+
+ @Override
public ILogicalOperator visitDataScanOperator(DataSourceScanOperator op,
Void arg) throws AlgebricksException {
return visitSingleInputOperator(op);
}
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineLeftNtsInSubplanJoinFlatteningVisitor.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineLeftNtsInSubplanJoinFlatteningVisitor.java
index 5aaa59f..b9a8bfd 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineLeftNtsInSubplanJoinFlatteningVisitor.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineLeftNtsInSubplanJoinFlatteningVisitor.java
@@ -47,6 +47,7 @@
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.IntersectOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
@@ -336,6 +337,12 @@
}
return op;
}
+
+ @Override
+ public ILogicalOperator
visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op, Void arg)
+ throws AlgebricksException {
+ return visitSingleInputOperator(op);
+ }
@Override
public ILogicalOperator visitDataScanOperator(DataSourceScanOperator op,
Void arg) throws AlgebricksException {
diff --git
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanSpecialFlatteningCheckVisitor.java
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanSpecialFlatteningCheckVisitor.java
index c691365..8c32ae3 100644
---
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanSpecialFlatteningCheckVisitor.java
+++
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanSpecialFlatteningCheckVisitor.java
@@ -33,6 +33,7 @@
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.IntersectOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
+import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
import
org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
@@ -203,6 +204,11 @@
public Boolean visitUnnestMapOperator(UnnestMapOperator op, Void arg)
throws AlgebricksException {
return false;
}
+
+ @Override
+ public Boolean visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator
op, Void arg) throws AlgebricksException {
+ return false;
+ }
@Override
public Boolean visitDataScanOperator(DataSourceScanOperator op, Void arg)
throws AlgebricksException {
--
To view, visit https://asterix-gerrit.ics.uci.edu/637
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6760319c2d3ff90c8b7d8ddeea3d9dd8f743366b
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Taewoo Kim <[email protected]>