ASTERIXDB-1226: implement SQL++ core group-by semantics and syntatic sugars.
-Implmented SQL++ core group-by semantics;
-Implemented SQL++ group-by syntatic sugars for standard SQL;
-Added test cases;
-Fixed column alias rewriter;
-Fixed the variable scoping for joins.
Change-Id: I6e5477d5bf80114cfff49c8ecb163849ee55eba6
Reviewed-on: https://asterix-gerrit.ics.uci.edu/752
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
diff --git a/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 38b4429..3c81cff 100644
--- a/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -141,6 +141,7 @@
import org.apache.asterix.lang.sqlpp.optype.SetOpType;
import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
+import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
import org.apache.hyracks.algebricks.common.utils.Pair;
import org.apache.hyracks.algebricks.common.utils.Triple;
import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
@@ -757,14 +758,12 @@
{
<LEFTPAREN> (<IDENTIFIER>
{
- var = new VarIdentifier();
- var.setValue(token.image);
+ var = SqlppVariableUtil.toInternalVariableIdentifier(token.image);
paramList.add(var);
}
(<COMMA> <IDENTIFIER>
{
- var = new VarIdentifier();
- var.setValue(token.image);
+ var = SqlppVariableUtil.toInternalVariableIdentifier(token.image);
paramList.add(var);
}
)*)? <RIGHTPAREN>
@@ -1598,7 +1597,7 @@
op.addOperand(operand);
op.setCurrentop(true);
}
- op.addOperator(token.image);
+ op.addOperator(token.image.toLowerCase());
}
operand = AndExpr()
@@ -1629,7 +1628,7 @@
op.addOperand(operand);
op.setCurrentop(true);
}
- op.addOperator(token.image);
+ op.addOperator(token.image.toLowerCase());
}
operand = RelExpr()
@@ -1925,17 +1924,18 @@
{ String id = null; }
(<IDENTIFIER> { id = token.image; } | id = QuotedString())
{
+ id = SqlppVariableUtil.toInternalVariableName(id); // Prefix user-defined variables with "$"
Identifier ident = lookupSymbol(id);
if (isInForbiddenScopes(id)) {
throw new ParseException("Inside limit clauses, it is disallowed to reference a variable having the same name as any variable bound in the same scope as the limit clause.");
}
if(ident != null) { // exist such ident
- varExp.setIsNewVar(false);
varExp.setVar((VarIdentifier)ident);
} else {
varExp.setVar(var);
+ varExp.setIsNewVar(false);
+ var.setValue(id);
}
- var.setValue(id);
return varExp;
}
}
@@ -1950,6 +1950,7 @@
{ String id = null; }
(<IDENTIFIER> { id = token.image; } | id = QuotedString())
{
+ id = SqlppVariableUtil.toInternalVariableName(id); // prefix user-defined variables with "$".
Identifier ident = lookupSymbol(id);
if(ident != null) { // exist such ident
varExp.setIsNewVar(false);
@@ -2498,6 +2499,9 @@
Expression expr = null;
VariableExpr decorVar = null;
Expression decorExpr = null;
+
+ VariableExpr groupVar = null;
+ List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<Pair<Expression, Identifier>>();
}
{
{
@@ -2531,10 +2535,32 @@
}
)*
)
+ (<GROUP> <AS> groupVar = Variable()
+ ( LOOKAHEAD(1)
+ {
+ VariableExpr fieldVarExpr = null;
+ String fieldIdentifierStr = null;
+ }
+ <LEFTPAREN>
+ fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
+ {
+ groupFieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
+ }
+ (<COMMA>
+ fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
+ {
+ groupFieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
+ }
+ )*
+ <RIGHTPAREN>
+ )?
+ )?
{
gbc.setGbyPairList(vePairList);
gbc.setDecorPairList(new ArrayList<GbyVariableExpressionPair>());
gbc.setWithVarList(new ArrayList<VariableExpr>());
+ gbc.setGroupVar(groupVar);
+ gbc.setGroupFieldList(groupFieldList);
replaceCurrentScope(newScope);
return gbc;
}