[NO ISSUE][COMP] Avoid variable reference sharing
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
- IntroduceSecondaryIndexInsertDeleteRule should
not share variable reference expressions
Change-Id: I1d8d25cf2ea78016b7f090398656f6dac718e573
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/10724
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
Reviewed-by: Glenn Galvizo <ggalvizo@uci.edu>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
index bf87fc0..c3859be 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
@@ -686,9 +686,7 @@
int sourceIndicatorForBaseRecord = workingElement.getSourceIndicator();
LogicalVariable sourceVarForBaseRecord = hasMetaPart
? ((sourceIndicatorForBaseRecord == Index.RECORD_INDICATOR) ? recordVar : metaVar) : recordVar;
- VariableReferenceExpression baseRecordVarRef = new VariableReferenceExpression(sourceVarForBaseRecord);
- baseRecordVarRef.setSourceLocation(sourceLoc);
- UnnestBranchCreator branchCreator = new UnnestBranchCreator(baseRecordVarRef, unnestSourceOp);
+ UnnestBranchCreator branchCreator = new UnnestBranchCreator(sourceVarForBaseRecord, unnestSourceOp);
int initialKeyPositionQueueSize = keyPositionQueue.size();
Set<LogicalVariable> secondaryKeyVars = new HashSet<>();
@@ -739,7 +737,7 @@
for (int j = 1; j < workingElement.getProjectList().size(); j++) {
LogicalVariable newVar = context.newVar();
AbstractFunctionCallExpression newVarRef =
- getFieldAccessFunction(new MutableObject<>(branchCreator.lastRecordVarRef), -1,
+ getFieldAccessFunction(new MutableObject<>(branchCreator.createLastRecordVarRef()), -1,
workingElement.getProjectList().get(j));
AssignOperator newAssignOp = new AssignOperator(newVar, new MutableObject<>(newVarRef));
@@ -988,12 +986,12 @@
*/
private class UnnestBranchCreator implements ArrayIndexUtil.TypeTrackerCommandExecutor {
private final List<LogicalVariable> lastFieldVars;
- private VariableReferenceExpression lastRecordVarRef;
+ private LogicalVariable lastRecordVar;
private ILogicalOperator currentTop, currentBottom;
private boolean isFirstWalk = true;
- public UnnestBranchCreator(VariableReferenceExpression recordVarRef, ILogicalOperator sourceOperator) {
- this.lastRecordVarRef = recordVarRef;
+ public UnnestBranchCreator(LogicalVariable recordVar, ILogicalOperator sourceOperator) {
+ this.lastRecordVar = recordVar;
this.currentTop = sourceOperator;
this.lastFieldVars = new ArrayList<>();
}
@@ -1006,6 +1004,12 @@
isFirstWalk = false;
}
+ public VariableReferenceExpression createLastRecordVarRef() {
+ VariableReferenceExpression varRef = new VariableReferenceExpression(lastRecordVar);
+ varRef.setSourceLocation(sourceLoc);
+ return varRef;
+ }
+
@SafeVarargs
public final void applyProjectDistinct(List<Mutable<ILogicalExpression>>... auxiliaryExpressions)
throws AlgebricksException {
@@ -1061,9 +1065,9 @@
if (isFirstUnnestInStep) {
// This is the first UNNEST step. Get the field we want to UNNEST from our record.
accessToUnnestVar = (startingStepRecordType != null)
- ? getFieldAccessFunction(new MutableObject<>(lastRecordVarRef),
+ ? getFieldAccessFunction(new MutableObject<>(createLastRecordVarRef()),
startingStepRecordType.getFieldIndex(fieldName.get(0)), fieldName)
- : getFieldAccessFunction(new MutableObject<>(lastRecordVarRef), -1, fieldName);
+ : getFieldAccessFunction(new MutableObject<>(createLastRecordVarRef()), -1, fieldName);
} else {
// This is the second+ UNNEST step. Refer back to the previously unnested variable.
accessToUnnestVar = new VariableReferenceExpression(this.lastFieldVars.get(0));
@@ -1086,8 +1090,7 @@
if (isLastUnnestInIntermediateStep) {
// This is the last UNNEST before the next array step. Update our record variable.
- this.lastRecordVarRef = new VariableReferenceExpression(unnestVar);
- this.lastRecordVarRef.setSourceLocation(sourceLoc);
+ this.lastRecordVar = unnestVar;
this.lastFieldVars.clear();
}
}
@@ -1102,9 +1105,9 @@
// Create the function to access our final field.
AbstractFunctionCallExpression accessToFinalVar = (startingStepRecordType != null)
- ? getFieldAccessFunction(new MutableObject<>(lastRecordVarRef),
+ ? getFieldAccessFunction(new MutableObject<>(createLastRecordVarRef()),
startingStepRecordType.getFieldIndex(fieldName.get(0)), fieldName)
- : getFieldAccessFunction(new MutableObject<>(lastRecordVarRef), -1, fieldName);
+ : getFieldAccessFunction(new MutableObject<>(createLastRecordVarRef()), -1, fieldName);
LogicalVariable finalVar = context.newVar();
this.lastFieldVars.add(finalVar);