Dmitry Lychagin has uploaded a new change for review.
https://asterix-gerrit.ics.uci.edu/2169
Change subject: [ASTERIXDB-2170][SQL] Fix resolution order of implicit field
access
......................................................................
[ASTERIXDB-2170][SQL] Fix resolution order of implicit field access
- user model changes: yes
- storage format changes: no
- interface changes: no
Details:
- Resolve field access to the nearest variable in scope
instead of raising compile-time error
- Cleanup group variable handling in GroupBy clause,
no longer use ‘with’ map for it
- Fix ByNameToByIndexFieldAccessRule to use type environment
of its input operator when analyzing its expression
- Fix ExternalGroupByPOperator to use input schema of its
aggregate function when generating runtime for that function
Change-Id: I69b1c5422017ceaa74a0cd83085c910292b00418
---
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ResolveVariableRule.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
M
asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581.plan
M
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/custord/join_q_09/join_q_09.2.query.sqlpp
M
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/conflict-fields-dataset/conflict-fields-dataset.3.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.1.ddl.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.2.update.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.3.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/results/custord/join_q_09/join_q_09.1.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/resolution/conflict-fields-dataset/conflict-fields-dataset.1.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/resolution/order_1/order_1.3.adm
M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
M asterixdb/asterix-lang-common/pom.xml
M
asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
M
asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
M
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
M asterixdb/pom.xml
M
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/ExternalGroupByPOperator.java
26 files changed, 271 insertions(+), 185 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/69/2169/1
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
index b3b0ad7..1ace6fa 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
@@ -87,7 +87,7 @@
return changed;
}
changed |= extractFirstArg(fce, op, context);
- IVariableTypeEnvironment env = context.getOutputTypeEnvironment(op);
+ IVariableTypeEnvironment env =
context.getOutputTypeEnvironment(op.getInputs().get(0).getValue());
IAType t = (IAType) env.getType(fce.getArguments().get(0).getValue());
changed |= rewriteFieldAccess(exprRef, fce, getActualType(t));
return changed;
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java
index 2b98762..d69dd3b 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java
@@ -421,47 +421,47 @@
AggregateOperator nspAgg = (AggregateOperator)
nspAggRef.getValue();
Mutable<ILogicalOperator> nspAggChildRef =
nspAgg.getInputs().get(0);
LogicalVariable listifyVar = findListifiedVariable(nspAgg,
varFromNestedAgg);
- if (listifyVar == null) {
- continue;
- }
- OperatorManipulationUtil.substituteVarRec(aggInSubplanOp,
unnestVar, listifyVar, true, context);
- nspAgg.getVariables().addAll(aggInSubplanOp.getVariables());
- nspAgg.getExpressions().addAll(aggInSubplanOp.getExpressions());
- for (LogicalVariable v : aggInSubplanOp.getVariables()) {
- nspWithAgg.put(v, nspOp);
- nspAggVars.put(v, 0);
- nspAggVarToPlanIndex.put(v, i);
- }
+ if (listifyVar != null) {
+ OperatorManipulationUtil.substituteVarRec(aggInSubplanOp,
unnestVar, listifyVar, true, context);
+ nspAgg.getVariables().addAll(aggInSubplanOp.getVariables());
+
nspAgg.getExpressions().addAll(aggInSubplanOp.getExpressions());
+ for (LogicalVariable v : aggInSubplanOp.getVariables()) {
+ nspWithAgg.put(v, nspOp);
+ nspAggVars.put(v, 0);
+ nspAggVarToPlanIndex.put(v, i);
+ }
- Mutable<ILogicalOperator> opRef1InSubplan =
aggInSubplanOp.getInputs().get(0);
- if (!opRef1InSubplan.getValue().getInputs().isEmpty()) {
- Mutable<ILogicalOperator> opRef2InSubplan =
opRef1InSubplan.getValue().getInputs().get(0);
- AbstractLogicalOperator op2InSubplan =
(AbstractLogicalOperator) opRef2InSubplan.getValue();
- if (op2InSubplan.getOperatorTag() !=
LogicalOperatorTag.NESTEDTUPLESOURCE) {
- List<Mutable<ILogicalOperator>> nspInpList =
nspAgg.getInputs();
- nspInpList.clear();
- nspInpList.add(opRef1InSubplan);
- while (true) {
- opRef2InSubplan =
opRef1InSubplan.getValue().getInputs().get(0);
- op2InSubplan = (AbstractLogicalOperator)
opRef2InSubplan.getValue();
- if (op2InSubplan.getOperatorTag() ==
LogicalOperatorTag.UNNEST) {
- List<Mutable<ILogicalOperator>> opInpList =
opRef1InSubplan.getValue().getInputs();
- opInpList.clear();
- opInpList.add(nspAggChildRef);
- break;
- }
- opRef1InSubplan = opRef2InSubplan;
- if (opRef1InSubplan.getValue().getInputs().isEmpty()) {
- throw new IllegalStateException(
+ Mutable<ILogicalOperator> opRef1InSubplan =
aggInSubplanOp.getInputs().get(0);
+ if (!opRef1InSubplan.getValue().getInputs().isEmpty()) {
+ Mutable<ILogicalOperator> opRef2InSubplan =
opRef1InSubplan.getValue().getInputs().get(0);
+ AbstractLogicalOperator op2InSubplan =
(AbstractLogicalOperator) opRef2InSubplan.getValue();
+ if (op2InSubplan.getOperatorTag() !=
LogicalOperatorTag.NESTEDTUPLESOURCE) {
+ List<Mutable<ILogicalOperator>> nspInpList =
nspAgg.getInputs();
+ nspInpList.clear();
+ nspInpList.add(opRef1InSubplan);
+ while (true) {
+ opRef2InSubplan =
opRef1InSubplan.getValue().getInputs().get(0);
+ op2InSubplan = (AbstractLogicalOperator)
opRef2InSubplan.getValue();
+ if (op2InSubplan.getOperatorTag() ==
LogicalOperatorTag.UNNEST) {
+ List<Mutable<ILogicalOperator>> opInpList =
opRef1InSubplan.getValue().getInputs();
+ opInpList.clear();
+ opInpList.add(nspAggChildRef);
+ break;
+ }
+ opRef1InSubplan = opRef2InSubplan;
+ if
(opRef1InSubplan.getValue().getInputs().isEmpty()) {
+ throw new IllegalStateException(
"PushAggregateIntoNestedSubplanRule:
could not find UNNEST.");
+ }
}
}
}
+ subplanOpRef.setValue(subplan.getInputs().get(0).getValue());
+ OperatorPropertiesUtil.typeOpRec(nspAggRef, context);
+ return true;
}
- subplanOpRef.setValue(subplan.getInputs().get(0).getValue());
- OperatorPropertiesUtil.typeOpRec(nspAggRef, context);
}
- return true;
+ return false;
}
private LogicalVariable findListifiedVariable(AggregateOperator nspAgg,
LogicalVariable varFromNestedAgg) {
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ResolveVariableRule.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ResolveVariableRule.java
index 2d7695f..f851e91 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ResolveVariableRule.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ResolveVariableRule.java
@@ -21,7 +21,7 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -154,13 +154,7 @@
// The resolution order: 1. field-access 2. datasets (standalone-name
or fully-qualified)
if (numVarCandidates > 0) {
- if (numVarCandidates == 1) {
- resolveAsFieldAccess(funcRef,
varAccessCandidates.iterator().next());
- } else {
- // More than one possibilities.
- throw new AlgebricksException(
- "Cannot resolve ambiguous alias reference for
undefined identifier " + unresolvedVarName);
- }
+ resolveAsFieldAccess(funcRef,
varAccessCandidates.iterator().next());
} else if (hasMatchedDataset) {
// Rewrites the "resolve" function to a "dataset" function and
only keep the dataset name argument.
func.setFunctionInfo(FunctionUtil.getFunctionInfo(BuiltinFunctions.DATASET));
@@ -205,22 +199,22 @@
}
// Finds all candidate fully qualified expression/field-access paths.
- private Set<Pair<ILogicalExpression, List<String>>>
findCandidatePaths(ILogicalOperator op,
- Collection<ILogicalExpression> referenceExprs, String
unresolvedVarName, IOptimizationContext context)
+ private LinkedHashSet<Pair<ILogicalExpression, List<String>>>
findCandidatePaths(ILogicalOperator op,
+ List<ILogicalExpression> referenceExprs, String unresolvedVarName,
IOptimizationContext context)
throws AlgebricksException {
- Set<Pair<ILogicalExpression, List<String>>> candidates = new
HashSet<>();
+ LinkedHashSet<Pair<ILogicalExpression, List<String>>> candidates = new
LinkedHashSet<>();
IVariableTypeEnvironment env =
context.getOutputTypeEnvironment(op.getInputs().get(0).getValue());
for (ILogicalExpression referenceExpr : referenceExprs) {
IAType type = (IAType) env.getType(referenceExpr);
- candidates.addAll(findCandidatePathsForExpr(unresolvedVarName,
type, referenceExpr, new ArrayList<>()));
+ findCandidatePathsForExpr(unresolvedVarName, type, referenceExpr,
new ArrayList<>(), candidates);
}
return candidates;
}
// Recursively finds candidate paths under an expression.
- private Set<Pair<ILogicalExpression, List<String>>>
findCandidatePathsForExpr(String unresolvedVarName,
- IAType pathType, ILogicalExpression expr, List<String> parentPath)
throws AlgebricksException {
- Set<Pair<ILogicalExpression, List<String>>> varAccessCandidates = new
HashSet<>();
+ private void findCandidatePathsForExpr(String unresolvedVarName, IAType
pathType, ILogicalExpression expr,
+ List<String> parentPath, Set<Pair<ILogicalExpression,
List<String>>> outCandidates)
+ throws AlgebricksException {
IAType type = pathType;
if (type.getTypeTag() == ATypeTag.UNION) {
type = ((AUnionType) type).getActualType();
@@ -229,7 +223,7 @@
if (tag == ATypeTag.ANY) {
List<String> path = new ArrayList<>(parentPath);
path.add(unresolvedVarName);
- varAccessCandidates.add(new Pair<>(expr, path));
+ outCandidates.add(new Pair<>(expr, path));
}
if (tag == ATypeTag.OBJECT) {
ARecordType recordType = (ARecordType) type;
@@ -237,7 +231,7 @@
// If the field name is possible.
List<String> path = new ArrayList<>(parentPath);
path.add(unresolvedVarName);
- varAccessCandidates.add(new Pair<>(expr, path));
+ outCandidates.add(new Pair<>(expr, path));
} else {
// Recursively identified possible paths.
String[] fieldNames = recordType.getFieldNames();
@@ -245,12 +239,10 @@
for (int index = 0; index < fieldNames.length; ++index) {
List<String> path = new ArrayList<>(parentPath);
path.add(fieldNames[index]);
-
varAccessCandidates.addAll(findCandidatePathsForExpr(unresolvedVarName,
fieldTypes[index], expr,
- path));
+ findCandidatePathsForExpr(unresolvedVarName,
fieldTypes[index], expr, path, outCandidates);
}
}
}
- return varAccessCandidates;
}
// Try to resolve the expression like resolve("x").foo as x.foo.
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
index 719824b..57d729d 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
@@ -794,6 +794,8 @@
public Pair<ILogicalOperator, LogicalVariable> visit(GroupbyClause gc,
Mutable<ILogicalOperator> tupSource)
throws CompilationException {
Mutable<ILogicalOperator> topOp = tupSource;
+
+ LogicalVariable groupRecordVar = null;
if (gc.hasGroupVar()) {
List<Pair<Expression, Identifier>> groupFieldList =
gc.getGroupFieldList();
List<Mutable<ILogicalExpression>> groupRecordConstructorArgList =
new ArrayList<>();
@@ -805,13 +807,14 @@
ILogicalExpression groupFieldExpr =
langExprToAlgExpression(groupField.first, topOp).first;
groupRecordConstructorArgList.add(new
MutableObject<>(groupFieldExpr));
}
- LogicalVariable groupVar =
context.newVarFromExpression(gc.getGroupVar());
- AssignOperator groupVarAssignOp = new AssignOperator(groupVar,
- new MutableObject<>(new ScalarFunctionCallExpression(
-
FunctionUtil.getFunctionInfo(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR),
- groupRecordConstructorArgList)));
- groupVarAssignOp.getInputs().add(topOp);
- topOp = new MutableObject<>(groupVarAssignOp);
+ MutableObject<ILogicalExpression> groupRecordConstr = new
MutableObject<>(new ScalarFunctionCallExpression(
+
FunctionUtil.getFunctionInfo(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR),
+ groupRecordConstructorArgList));
+
+ groupRecordVar = context.newVar();
+ AssignOperator groupRecordVarAssignOp = new
AssignOperator(groupRecordVar, groupRecordConstr);
+ groupRecordVarAssignOp.getInputs().add(topOp);
+ topOp = new MutableObject<>(groupRecordVarAssignOp);
}
GroupByOperator gOp = new GroupByOperator();
@@ -831,30 +834,46 @@
}
gOp.getInputs().add(topOp);
- for (Entry<Expression, VariableExpr> entry :
gc.getWithVarMap().entrySet()) {
- Pair<ILogicalExpression, Mutable<ILogicalOperator>> listifyInput =
langExprToAlgExpression(entry.getKey(),
+
+ if (gc.hasGroupVar()) {
+ VariableExpr groupVar = gc.getGroupVar();
+ LogicalVariable groupLogicalVar = context.newVar();
+ ILogicalPlan nestedPlan =
createNestedPlanWithAggregate(groupLogicalVar,
+ BuiltinFunctions.LISTIFY, new
VariableReferenceExpression(groupRecordVar),
new MutableObject<>(new NestedTupleSourceOperator(new
MutableObject<>(gOp))));
- List<Mutable<ILogicalExpression>> flArgs = new ArrayList<>(1);
- flArgs.add(new MutableObject<>(listifyInput.first));
- AggregateFunctionCallExpression fListify =
-
BuiltinFunctions.makeAggregateFunctionExpression(BuiltinFunctions.LISTIFY,
flArgs);
- LogicalVariable aggVar = context.newVar();
- AggregateOperator agg = new
AggregateOperator(mkSingletonArrayList(aggVar),
- mkSingletonArrayList(new MutableObject<>(fListify)));
-
- agg.getInputs().add(listifyInput.second);
-
- ILogicalPlan plan = new ALogicalPlanImpl(new MutableObject<>(agg));
- gOp.getNestedPlans().add(plan);
- // Hide the variable that was part of the "with", replacing it with
- // the one bound by the aggregation op.
- context.setVar(entry.getValue(), aggVar);
+ gOp.getNestedPlans().add(nestedPlan);
+ context.setVar(groupVar, groupLogicalVar);
}
+
+ if (gc.hasWithMap()) {
+ for (Entry<Expression, VariableExpr> entry :
gc.getWithVarMap().entrySet()) {
+ VariableExpr withVar = entry.getValue();
+ Expression withExpr = entry.getKey();
+ Pair<ILogicalExpression, Mutable<ILogicalOperator>>
listifyInput = langExprToAlgExpression(withExpr,
+ new MutableObject<>(new NestedTupleSourceOperator(new
MutableObject<>(gOp))));
+ LogicalVariable withLogicalVar = context.newVar();
+ ILogicalPlan nestedPlan =
createNestedPlanWithAggregate(withLogicalVar,
+ BuiltinFunctions.LISTIFY, listifyInput.first,
listifyInput.second);
+ gOp.getNestedPlans().add(nestedPlan);
+ context.setVar(withVar, withLogicalVar);
+ }
+ }
+
gOp.setGroupAll(gc.isGroupAll());
gOp.getAnnotations().put(OperatorAnnotations.USE_HASH_GROUP_BY,
gc.hasHashGroupByHint());
return new Pair<>(gOp, null);
}
+ private ILogicalPlan createNestedPlanWithAggregate(LogicalVariable
aggOutputVar, FunctionIdentifier aggFunc,
+ ILogicalExpression aggFnInput, Mutable<ILogicalOperator>
aggOpInput) {
+ AggregateFunctionCallExpression aggFnCall =
BuiltinFunctions.makeAggregateFunctionExpression(aggFunc,
+ mkSingletonArrayList(new MutableObject<>(aggFnInput)));
+ AggregateOperator aggOp = new
AggregateOperator(mkSingletonArrayList(aggOutputVar),
+ mkSingletonArrayList(new MutableObject<>(aggFnCall)));
+ aggOp.getInputs().add(aggOpInput);
+ return new ALogicalPlanImpl(new MutableObject<>(aggOp));
+ }
+
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(IfExpr ifexpr,
Mutable<ILogicalOperator> tupSource)
throws CompilationException {
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
index c17b55b..57f2253 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
@@ -662,9 +662,12 @@
for (GbyVariableExpressionPair pair : groupbyClause.getGbyPairList()) {
fieldBindings.add(getFieldBinding(pair.getVar()));
}
- if (groupbyClause.hasWithMap() && groupbyClause.hasGroupVar()) {
- // Makes sure that we add the re-mapped group variable which
refers to a collection.
-
fieldBindings.add(getFieldBinding(groupbyClause.getWithVarMap().get(groupbyClause.getGroupVar())));
+ if (groupbyClause.hasGroupVar()) {
+ fieldBindings.add(getFieldBinding(groupbyClause.getGroupVar()));
+ }
+ if (groupbyClause.hasWithMap()) {
+ // no WITH in SQL++
+ throw new
IllegalStateException(groupbyClause.getWithVarMap().values().toString());
}
return fieldBindings;
}
diff --git
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581.plan
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581.plan
index 14b31eb..753ae20 100644
---
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581.plan
+++
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581.plan
@@ -32,7 +32,7 @@
-- ONE_TO_ONE_EXCHANGE |PARTITIONED|
-- HYBRID_HASH_JOIN [$$92][$$93]
|PARTITIONED|
-- HASH_PARTITION_EXCHANGE [$$92]
|PARTITIONED|
- -- PRE_CLUSTERED_GROUP_BY[$$32]
|PARTITIONED|
+ -- PRE_CLUSTERED_GROUP_BY[$$30]
|PARTITIONED|
{
-- AGGREGATE |LOCAL|
-- AGGREGATE |LOCAL|
@@ -42,11 +42,11 @@
--
NESTED_TUPLE_SOURCE |LOCAL|
}
-- ONE_TO_ONE_EXCHANGE |PARTITIONED|
- -- STABLE_SORT [$$32(ASC)]
|PARTITIONED|
+ -- STABLE_SORT [$$30(ASC)]
|PARTITIONED|
-- ONE_TO_ONE_EXCHANGE
|PARTITIONED|
-- STREAM_PROJECT |PARTITIONED|
-- ONE_TO_ONE_EXCHANGE
|PARTITIONED|
- -- HYBRID_HASH_JOIN
[$$32][$$85] |PARTITIONED|
+ -- HYBRID_HASH_JOIN
[$$30][$$85] |PARTITIONED|
-- ONE_TO_ONE_EXCHANGE
|PARTITIONED|
-- STREAM_PROJECT
|PARTITIONED|
-- ASSIGN
|PARTITIONED|
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/custord/join_q_09/join_q_09.2.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/custord/join_q_09/join_q_09.2.query.sqlpp
index 49aa67f..32071ee 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/custord/join_q_09/join_q_09.2.query.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/custord/join_q_09/join_q_09.2.query.sqlpp
@@ -17,10 +17,10 @@
* under the License.
*/
-/** This query is a negative test for ambiguous alias reference. */
+/** This query is a test for ambiguous alias reference. */
SELECT c.name AS cust_name,
- age AS cust_age,
+ age AS age,
o.total AS order_total,
[o.oid,o.cid] AS orderList
FROM test.Customers c, test.Orders o
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/conflict-fields-dataset/conflict-fields-dataset.3.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/conflict-fields-dataset/conflict-fields-dataset.3.query.sqlpp
index 2645ddc..6560931 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/conflict-fields-dataset/conflict-fields-dataset.3.query.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/conflict-fields-dataset/conflict-fields-dataset.3.query.sqlpp
@@ -21,4 +21,5 @@
select *
from samptable s1, samptable s2
-where samptable > 0;
+where samptable > 0
+order by s1.id
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.1.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.1.ddl.sqlpp
new file mode 100644
index 0000000..d6231cf
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.1.ddl.sqlpp
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type partType as closed {
+ pid: bigint
+};
+
+create type orderType as closed {
+ oid: bigint,
+ pid: bigint
+};
+
+create dataset parts(partType) primary key pid;
+
+create dataset orders(orderType) primary key oid;
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.2.update.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.2.update.sqlpp
new file mode 100644
index 0000000..3e5e1d1
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.2.update.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+use test;
+
+insert into parts ({'pid': 0});
+insert into parts ({'pid': 1});
+
+insert into orders ({'oid' : 100, 'pid': 0});
+insert into orders ({'oid' : 101, 'pid': 1});
+insert into orders ({'oid' : 102, 'pid': 99});
+insert into orders ({'oid' : 103, 'pid': 1});
+insert into orders ({'oid' : 104, 'pid': 0});
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.3.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.3.query.sqlpp
new file mode 100644
index 0000000..01ed3a5
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/resolution/order_1/order_1.3.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+use test;
+
+select value oid from orders
+where pid in (select value pid from parts)
+order by oid
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/join_q_09/join_q_09.1.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/join_q_09/join_q_09.1.adm
new file mode 100644
index 0000000..9c8f2ee
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/join_q_09/join_q_09.1.adm
@@ -0,0 +1,3 @@
+{ "cust_name": "Jodi Alex", "order_total": 7.206, "orderList": [ 1, 5 ] }
+{ "cust_name": "Jodi Rotruck", "order_total": 14.2326, "orderList": [ 10, 775
] }
+{ "cust_name": "Jodi Rotruck", "order_total": 97.20656, "orderList": [ 1000,
775 ] }
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/resolution/conflict-fields-dataset/conflict-fields-dataset.1.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/resolution/conflict-fields-dataset/conflict-fields-dataset.1.adm
new file mode 100644
index 0000000..86f600b
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/resolution/conflict-fields-dataset/conflict-fields-dataset.1.adm
@@ -0,0 +1,2 @@
+{ "s1": { "id": 0 }, "s2": { "id": 1, "samptable": 1 } }
+{ "s1": { "id": 1, "samptable": 1 }, "s2": { "id": 1, "samptable": 1 } }
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/resolution/order_1/order_1.3.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/resolution/order_1/order_1.3.adm
new file mode 100644
index 0000000..c9e3657
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/resolution/order_1/order_1.3.adm
@@ -0,0 +1,4 @@
+100
+101
+103
+104
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 484e395..db69cf7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -1493,8 +1493,7 @@
</test-case>
<test-case FilePath="custord">
<compilation-unit name="join_q_09">
- <output-dir compare="Text">join_q_01</output-dir>
- <expected-error>Cannot resolve ambiguous alias reference for undefined
identifier age</expected-error>
+ <output-dir compare="Text">join_q_09</output-dir>
</compilation-unit>
</test-case>
<test-case FilePath="custord">
@@ -5389,8 +5388,7 @@
</test-case>
<test-case FilePath="resolution">
<compilation-unit name="conflict-fields-dataset">
- <output-dir compare="Text">conflict-field-dataset</output-dir>
- <expected-error>Cannot resolve ambiguous alias reference for undefined
identifier samptable</expected-error>
+ <output-dir compare="Text">conflict-fields-dataset</output-dir>
</compilation-unit>
</test-case>
<test-case FilePath="resolution">
@@ -5401,6 +5399,11 @@
<test-case FilePath="resolution">
<compilation-unit name="fullyqualified2">
<output-dir compare="Text">fullyqualified2</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="resolution">
+ <compilation-unit name="order_1">
+ <output-dir compare="Text">order_1</output-dir>
</compilation-unit>
</test-case>
</test-group>
@@ -6437,7 +6440,6 @@
<test-case FilePath="subquery">
<compilation-unit name="query-ASTERIXDB-1574-3">
<output-dir compare="Text">query-ASTERIXDB-1574</output-dir>
- <expected-error>Cannot resolve ambiguous alias reference for undefined
identifier</expected-error>
</compilation-unit>
</test-case>
<test-case FilePath="subquery">
diff --git a/asterixdb/asterix-lang-common/pom.xml
b/asterixdb/asterix-lang-common/pom.xml
index b6c6e7a..6572cc0 100644
--- a/asterixdb/asterix-lang-common/pom.xml
+++ b/asterixdb/asterix-lang-common/pom.xml
@@ -91,6 +91,10 @@
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-collections4</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.hyracks</groupId>
<artifactId>algebricks-core</artifactId>
</dependency>
diff --git
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
index ad277d3..92a101d 100644
---
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
+++
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
@@ -18,40 +18,39 @@
*/
package org.apache.asterix.lang.common.context;
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.ArrayList;
import java.util.Iterator;
-import java.util.Map;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Set;
import org.apache.asterix.common.functions.FunctionSignature;
-import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.parser.ScopeChecker;
-import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.struct.VarIdentifier;
+import org.apache.commons.collections4.iterators.ReverseListIterator;
public final class Scope {
- private Scope parent;
- private Map<String, Identifier> symbols = new HashMap<String,
Identifier>();
- private Map<String, Expression> varExprMap = new HashMap<String,
Expression>();
- private FunctionSignatures functionSignatures = null;
private final ScopeChecker scopeChecker;
- private boolean maskParentScope = false;
-
- public Scope(ScopeChecker scopeChecker, Scope parent) {
- this.scopeChecker = scopeChecker;
- this.parent = parent;
- }
+ private final Scope parent;
+ private final LinkedHashMap<String, Identifier> symbols;
+ private final boolean maskParentScope;
+ private FunctionSignatures functionSignatures;
public Scope(ScopeChecker scopeChecker) {
this(scopeChecker, null);
}
+ public Scope(ScopeChecker scopeChecker, Scope parent) {
+ this(scopeChecker, parent, false);
+ }
+
public Scope(ScopeChecker scopeChecker, Scope parent, boolean
maskParentScope) {
- this(scopeChecker, parent);
+ this.scopeChecker = scopeChecker;
+ this.parent = parent;
this.maskParentScope = maskParentScope;
+ this.symbols = new LinkedHashMap<>();
}
/**
@@ -81,36 +80,6 @@
symbols.put(ident.getValue(), ident);
}
- /**
- * Add a symbol and its definition expression into the scope
- *
- * @param ident
- */
- public void addSymbolExpressionMappingToScope(VariableExpr ident,
Expression expr) {
- varExprMap.put(ident.getVar().getValue(), expr);
- }
-
- /**
- * Remove a symbol and its definition expression into the scope
- *
- * @param ident
- */
- public Expression removeSymbolExpressionMapping(VariableExpr ident) {
- if (ident == null) {
- return null;
- }
- return varExprMap.remove(ident.getVar().getValue());
- }
-
- /**
- * @return the variable substituion environment for inlining variable
references by its original
- */
- public VariableSubstitutionEnvironment getVarSubstitutionEnvironment() {
- VariableSubstitutionEnvironment env = new
VariableSubstitutionEnvironment();
- env.addMappings(varExprMap);
- return env;
- }
-
public void addNewVarSymbolToScope(VarIdentifier ident) {
scopeChecker.incVarCounter();
ident.setId(scopeChecker.getVarCounter());
@@ -120,8 +89,8 @@
/**
* Add a FunctionDescriptor into functionSignatures
*
- * @param fd
- * FunctionDescriptor
+ * @param signature
+ * FunctionSignature
* @param varargs
* whether this function has varargs
*/
@@ -163,7 +132,6 @@
if (functionSignatures != null && scope.functionSignatures != null) {
functionSignatures.addAll(scope.functionSignatures);
}
- varExprMap.putAll(scope.varExprMap);
}
/**
@@ -172,7 +140,7 @@
* @return an iterator of visible symbols.
*/
public Iterator<Identifier> liveSymbols() {
- final Iterator<Identifier> identifierIterator =
symbols.values().iterator();
+ final Iterator<Identifier> identifierIterator = new
ReverseListIterator<>(new ArrayList<>(symbols.values()));
final Iterator<Identifier> parentIterator = parent == null ? null :
parent.liveSymbols();
return new Iterator<Identifier>() {
private Identifier currentSymbol = null;
@@ -180,7 +148,7 @@
@Override
public boolean hasNext() {
currentSymbol = null;
- if (identifierIterator != null &&
identifierIterator.hasNext()) {
+ if (identifierIterator.hasNext()) {
currentSymbol = identifierIterator.next();
} else if (!maskParentScope && parentIterator != null &&
parentIterator.hasNext()) {
do {
@@ -213,8 +181,8 @@
};
}
- public Set<VariableExpr> getLiveVariables() {
- Set<VariableExpr> vars = new HashSet<VariableExpr>();
+ public LinkedHashSet<VariableExpr> getLiveVariables() {
+ LinkedHashSet<VariableExpr> vars = new LinkedHashSet<>();
Iterator<Identifier> identifierIterator = liveSymbols();
while (identifierIterator.hasNext()) {
Identifier identifier = identifierIterator.next();
diff --git
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
index b35aa91..ed23d25 100644
---
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
+++
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
@@ -98,7 +98,7 @@
addOperator(op);
}
- public void addOperator(OperatorType op) throws CompilationException {
+ public void addOperator(OperatorType op) {
if (op == null) {
throw new NullPointerException();
}
diff --git
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
index dfe371e..dea0e3a 100644
---
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
+++
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
@@ -247,13 +247,6 @@
gc.setGroupVar(groupVar);
}
- // Adds the group variable into the "with" (i.e., re-binding) variable
list.
- VariableExpr gbyVarRef = new VariableExpr(gc.getGroupVar().getVar());
- gbyVarRef.setIsNewVar(false);
- Map<Expression, VariableExpr> withVarMap = new HashMap<>();
- withVarMap.put(gbyVarRef, (VariableExpr)
SqlppRewriteUtil.deepCopy(gbyVarRef));
- gc.setWithVarMap(withVarMap);
-
// Call super.visit(...) to scope variables.
return super.visit(gc, arg);
}
diff --git
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
index 6e6ffeb..a96bf50 100644
---
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
+++
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
@@ -135,6 +135,17 @@
+ datasetName + "!");
}
+ // Rewrites for an undefined variable reference, which potentially could
be a syntatic sugar.
+ private Expression wrapWithResolveFunction(VariableExpr expr,
Set<VariableExpr> liveVars)
+ throws CompilationException {
+ List<Expression> argList = new ArrayList<>();
+ //Ignore the parser-generated prefix "$" for a dataset.
+ String varName =
SqlppVariableUtil.toUserDefinedVariableName(expr.getVar().getValue()).getValue();
+ argList.add(new LiteralExpr(new StringLiteral(varName)));
+ argList.addAll(liveVars);
+ return new CallExpr(new FunctionSignature(BuiltinFunctions.RESOLVE),
argList);
+ }
+
// Checks whether we need to error the variable reference, e.g., the
variable is referred
// in a LIMIT clause.
private void checkError(String varName) throws CompilationException {
diff --git
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
index 2d6ac53..b2c473c 100644
---
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
+++
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
@@ -22,9 +22,8 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
-import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Set;
import org.apache.asterix.common.exceptions.CompilationException;
import org.apache.asterix.lang.common.base.ILangExpression;
@@ -77,12 +76,9 @@
return varName;
}
- public static Set<VariableExpr> getLiveVariables(Scope scope, boolean
includeWithVariables) {
- Set<VariableExpr> results = new HashSet<>();
- Set<VariableExpr> liveVars = scope.getLiveVariables();
- Iterator<VariableExpr> liveVarIter = liveVars.iterator();
- while (liveVarIter.hasNext()) {
- VariableExpr liveVar = liveVarIter.next();
+ public static LinkedHashSet<VariableExpr> getLiveVariables(Scope scope,
boolean includeWithVariables) {
+ LinkedHashSet<VariableExpr> results = new LinkedHashSet<>();
+ for (VariableExpr liveVar : scope.getLiveVariables()) {
// Variables defined in WITH clauses are named value access.
// TODO(buyingi): remove this if block once we can accurately type
// ordered lists with UNION item type. Currently it is typed as
[ANY].
diff --git
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
index 38d09f9..d77cd63 100644
---
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
+++
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
@@ -264,15 +264,16 @@
public Void visit(GroupbyClause gc, Integer step) throws
CompilationException {
if (gc.isGroupAll()) {
out.println(skip(step) + "Group All");
- return null;
}
- out.println(skip(step) + "Groupby");
- for (GbyVariableExpressionPair pair : gc.getGbyPairList()) {
- if (pair.getVar() != null) {
- pair.getVar().accept(this, step + 1);
- out.println(skip(step + 1) + ":=");
+ else {
+ out.println(skip(step) + "Groupby");
+ for (GbyVariableExpressionPair pair : gc.getGbyPairList()) {
+ if (pair.getVar() != null) {
+ pair.getVar().accept(this, step + 1);
+ out.println(skip(step + 1) + ":=");
+ }
+ pair.getExpr().accept(this, step + 1);
}
- pair.getExpr().accept(this, step + 1);
}
if (gc.hasGroupVar()) {
out.print(skip(step + 1) + "GROUP AS ");
diff --git
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
index 2f9cb32..52435e6 100644
---
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
+++
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
@@ -57,7 +57,6 @@
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
-import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.hyracks.algebricks.common.utils.Pair;
import org.apache.hyracks.algebricks.core.algebra.base.Counter;
@@ -243,7 +242,7 @@
}
}
if (gc.hasGroupVar()) {
- addNewVarSymbolToScope(scopeChecker.getCurrentScope(),
gc.getGroupVar().getVar());
+ addNewVarSymbolToScope(newScope, gc.getGroupVar().getVar());
}
if (gc.hasWithMap()) {
Map<Expression, VariableExpr> newWithMap = new HashMap<>();
@@ -363,17 +362,6 @@
insertStatement.setReturnExpression(visit(returningExpr,
insertStatement));
}
return null;
- }
-
- // Rewrites for an undefined variable reference, which potentially could
be a syntatic sugar.
- protected Expression wrapWithResolveFunction(VariableExpr expr,
Set<VariableExpr> liveVars)
- throws CompilationException {
- List<Expression> argList = new ArrayList<>();
- //Ignore the parser-generated prefix "$" for a dataset.
- String varName =
SqlppVariableUtil.toUserDefinedVariableName(expr.getVar().getValue()).getValue();
- argList.add(new LiteralExpr(new StringLiteral(varName)));
- argList.addAll(liveVars);
- return new CallExpr(new FunctionSignature(BuiltinFunctions.RESOLVE),
argList);
}
// Adds a new encountered alias identifier into a scope
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index a58ce0f..a6d7d12 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -143,6 +143,7 @@
import org.apache.asterix.lang.common.statement.UpsertStatement;
import org.apache.asterix.lang.common.statement.WriteStatement;
import org.apache.asterix.lang.common.struct.Identifier;
+import org.apache.asterix.lang.common.struct.OperatorType;
import org.apache.asterix.lang.common.struct.QuantifiedPair;
import org.apache.asterix.lang.common.struct.VarIdentifier;
import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
@@ -1970,6 +1971,7 @@
<AND>
operand = IsExpr()
{
+ op.addOperator(OperatorType.AND);
op.addOperand(operand);
}
)?
diff --git a/asterixdb/pom.xml b/asterixdb/pom.xml
index 11d9218..c2bd159 100644
--- a/asterixdb/pom.xml
+++ b/asterixdb/pom.xml
@@ -1040,6 +1040,11 @@
<version>3.5</version>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-collections4</artifactId>
+ <version>4.1</version>
+ </dependency>
+ <dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
diff --git
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/ExternalGroupByPOperator.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/ExternalGroupByPOperator.java
index 9e7daf0..eecd066 100644
---
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/ExternalGroupByPOperator.java
+++
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/ExternalGroupByPOperator.java
@@ -179,18 +179,23 @@
Mutable<ILogicalOperator> r0 = p0.getRoots().get(0);
AggregateOperator aggOp = (AggregateOperator) r0.getValue();
+ compileSubplans(inputSchemas[0], gby, opSchema, context);
+
IPartialAggregationTypeComputer partialAggregationTypeComputer =
context.getPartialAggregationTypeComputer();
List<Object> intermediateTypes = new ArrayList<Object>();
int n = aggOp.getExpressions().size();
ISerializedAggregateEvaluatorFactory[] aff = new
ISerializedAggregateEvaluatorFactory[n];
int i = 0;
IExpressionRuntimeProvider expressionRuntimeProvider =
context.getExpressionRuntimeProvider();
- IVariableTypeEnvironment aggOpInputEnv =
context.getTypeEnvironment(aggOp.getInputs().get(0).getValue());
+ ILogicalOperator aggOpInput = aggOp.getInputs().get(0).getValue();
+ IOperatorSchema aggOpInputSchema = context.getSchema(aggOpInput);
+ IOperatorSchema[] aggOpInputSchemas = new IOperatorSchema[] {
aggOpInputSchema };
+ IVariableTypeEnvironment aggOpInputEnv =
context.getTypeEnvironment(aggOpInput);
IVariableTypeEnvironment outputEnv = context.getTypeEnvironment(op);
for (Mutable<ILogicalExpression> exprRef : aggOp.getExpressions()) {
AggregateFunctionCallExpression aggFun =
(AggregateFunctionCallExpression) exprRef.getValue();
aff[i++] =
expressionRuntimeProvider.createSerializableAggregateFunctionFactory(aggFun,
aggOpInputEnv,
- inputSchemas, context);
+ aggOpInputSchemas, context);
intermediateTypes
.add(partialAggregationTypeComputer.getType(aggFun,
aggOpInputEnv, context.getMetadataProvider()));
}
@@ -215,7 +220,6 @@
aggOpInputEnv.setVarType(var, outputEnv.getVarType(var));
}
- compileSubplans(inputSchemas[0], gby, opSchema, context);
IOperatorDescriptorRegistry spec = builder.getJobSpec();
IBinaryComparatorFactory[] comparatorFactories =
JobGenHelper.variablesToAscBinaryComparatorFactories(gbyCols,
aggOpInputEnv, context);
--
To view, visit https://asterix-gerrit.ics.uci.edu/2169
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I69b1c5422017ceaa74a0cd83085c910292b00418
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <[email protected]>