You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by dl...@apache.org on 2019/01/03 21:03:25 UTC
[04/34] asterixdb git commit: [ASTERIXDB-2488][COMP] Support
aggregate window functions
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
index 0c70572..39e1883 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
@@ -33,6 +33,7 @@ import org.apache.asterix.lang.common.clause.WhereClause;
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
+import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.util.VariableCloneAndSubstitutionUtil;
import org.apache.asterix.lang.common.visitor.CloneAndSubstituteVariablesVisitor;
import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
@@ -90,7 +91,7 @@ public class SqlppCloneAndSubstituteVariablesVisitor extends CloneAndSubstituteV
VariableExpr newLeftVar = generateNewVariable(context, leftVar);
VariableExpr newLeftPosVar = fromTerm.hasPositionalVariable()
? generateNewVariable(context, fromTerm.getPositionalVariable()) : null;
- Expression newLeftExpr = (Expression) visitUnnesBindingExpression(fromTerm.getLeftExpression(), env).first;
+ Expression newLeftExpr = (Expression) visitUnnestBindingExpression(fromTerm.getLeftExpression(), env).first;
List<AbstractBinaryCorrelateClause> newCorrelateClauses = new ArrayList<>();
VariableSubstitutionEnvironment currentEnv = new VariableSubstitutionEnvironment(env);
@@ -131,7 +132,7 @@ public class SqlppCloneAndSubstituteVariablesVisitor extends CloneAndSubstituteV
? generateNewVariable(context, joinClause.getPositionalVariable()) : null;
// Visits the right expression.
- Expression newRightExpr = (Expression) visitUnnesBindingExpression(joinClause.getRightExpression(), env).first;
+ Expression newRightExpr = (Expression) visitUnnestBindingExpression(joinClause.getRightExpression(), env).first;
// Visits the condition.
VariableSubstitutionEnvironment currentEnv = new VariableSubstitutionEnvironment(env);
@@ -183,7 +184,7 @@ public class SqlppCloneAndSubstituteVariablesVisitor extends CloneAndSubstituteV
? generateNewVariable(context, unnestClause.getPositionalVariable()) : null;
// Visits the right expression.
- Expression rightExpr = (Expression) visitUnnesBindingExpression(unnestClause.getRightExpression(), env).first;
+ Expression rightExpr = (Expression) visitUnnestBindingExpression(unnestClause.getRightExpression(), env).first;
// Visits the condition.
VariableSubstitutionEnvironment currentEnv = new VariableSubstitutionEnvironment(env);
@@ -416,14 +417,26 @@ public class SqlppCloneAndSubstituteVariablesVisitor extends CloneAndSubstituteV
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(WindowExpression winExpr,
VariableSubstitutionEnvironment env) throws CompilationException {
- Expression newExpr = (Expression) winExpr.getExpr().accept(this, env).first;
+ List<Expression> newExprList =
+ VariableCloneAndSubstitutionUtil.visitAndCloneExprList(winExpr.getExprList(), env, this);
List<Expression> newPartitionList = winExpr.hasPartitionList()
? VariableCloneAndSubstitutionUtil.visitAndCloneExprList(winExpr.getPartitionList(), env, this) : null;
- List<Expression> newOrderbyList =
- VariableCloneAndSubstitutionUtil.visitAndCloneExprList(winExpr.getOrderbyList(), env, this);
- List<OrderbyClause.OrderModifier> newOrderbyModifierList = new ArrayList<>(winExpr.getOrderbyModifierList());
- WindowExpression newWinExpr =
- new WindowExpression(newExpr, newPartitionList, newOrderbyList, newOrderbyModifierList);
+ List<Expression> newOrderbyList = winExpr.hasOrderByList()
+ ? VariableCloneAndSubstitutionUtil.visitAndCloneExprList(winExpr.getOrderbyList(), env, this) : null;
+ List<OrderbyClause.OrderModifier> newOrderbyModifierList =
+ winExpr.hasOrderByList() ? new ArrayList<>(winExpr.getOrderbyModifierList()) : null;
+ Expression newFrameStartExpr =
+ winExpr.hasFrameStartExpr() ? (Expression) winExpr.getFrameStartExpr().accept(this, env).first : null;
+ Expression newFrameEndExpr =
+ winExpr.hasFrameEndExpr() ? (Expression) winExpr.getFrameEndExpr().accept(this, env).first : null;
+ VariableExpr newWindowVar =
+ winExpr.hasWindowVar() ? (VariableExpr) winExpr.getWindowVar().accept(this, env).first : null;
+ List<Pair<Expression, Identifier>> newWindowFieldList = winExpr.hasWindowFieldList()
+ ? VariableCloneAndSubstitutionUtil.substInFieldList(winExpr.getWindowFieldList(), env, this) : null;
+ WindowExpression newWinExpr = new WindowExpression(winExpr.getFunctionSignature(), newExprList,
+ newPartitionList, newOrderbyList, newOrderbyModifierList, winExpr.getFrameMode(),
+ winExpr.getFrameStartKind(), newFrameStartExpr, winExpr.getFrameEndKind(), newFrameEndExpr,
+ winExpr.getFrameExclusionKind(), newWindowVar, newWindowFieldList);
newWinExpr.setSourceLocation(winExpr.getSourceLocation());
newWinExpr.addHints(winExpr.getHints());
return new Pair<>(newWinExpr, env);
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
index 99368f8..1ee3004 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
@@ -335,8 +335,16 @@ public class SqlppFormatPrintVisitor extends FormatPrintVisitor implements ISqlp
@Override
public Void visit(WindowExpression windowExpr, Integer step) throws CompilationException {
out.print(skip(step) + "window ");
- windowExpr.getExpr().accept(this, step + 2);
- out.print(skip(step) + " over (");
+ out.print(generateFullName(windowExpr.getFunctionSignature().getNamespace(),
+ windowExpr.getFunctionSignature().getName()) + "(");
+ printDelimitedExpressions(windowExpr.getExprList(), COMMA, step);
+ out.print(")");
+ out.print(skip(step) + " over ");
+ if (windowExpr.hasWindowVar()) {
+ windowExpr.getWindowVar().accept(this, step + 2);
+ out.print(skip(step) + "as ");
+ }
+ out.print("(");
if (windowExpr.hasPartitionList()) {
List<Expression> partitionList = windowExpr.getPartitionList();
for (int i = 0, ln = partitionList.size(); i < ln; i++) {
@@ -347,8 +355,22 @@ public class SqlppFormatPrintVisitor extends FormatPrintVisitor implements ISqlp
partExpr.accept(this, step + 2);
}
}
- out.print(" order by ");
- printDelimitedObyExpressions(windowExpr.getOrderbyList(), windowExpr.getOrderbyModifierList(), step + 2);
+ if (windowExpr.hasOrderByList()) {
+ out.print(skip(step) + " order by ");
+ printDelimitedObyExpressions(windowExpr.getOrderbyList(), windowExpr.getOrderbyModifierList(), step + 2);
+ }
+ if (windowExpr.hasFrameDefinition()) {
+ out.println(skip(step) + windowExpr.getFrameMode());
+ if (windowExpr.hasFrameStartExpr()) {
+ windowExpr.getFrameStartExpr().accept(this, step + 2);
+ }
+ out.println(skip(step) + windowExpr.getFrameStartKind());
+ if (windowExpr.hasFrameEndExpr()) {
+ windowExpr.getFrameEndExpr().accept(this, step + 2);
+ }
+ out.println(skip(step) + windowExpr.getFrameEndKind());
+ out.println(skip(step) + "exclude " + windowExpr.getFrameExclusionKind());
+ }
out.println(skip(step) + ")");
return null;
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
----------------------------------------------------------------------
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 df165c0..8650eec 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
@@ -51,6 +51,7 @@ import org.apache.asterix.lang.sqlpp.clause.NestClause;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
+import org.apache.asterix.lang.sqlpp.expression.WindowExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
import org.apache.hyracks.algebricks.common.utils.Pair;
@@ -375,6 +376,22 @@ public class AbstractSqlppExpressionScopingVisitor extends AbstractSqlppSimpleEx
return null;
}
+ @Override
+ public Expression visit(WindowExpression winExpr, ILangExpression arg) throws CompilationException {
+ visitWindowExpressionExcludingExprList(winExpr, arg);
+ if (winExpr.hasWindowVar()) {
+ Scope preScope = scopeChecker.getCurrentScope();
+ Scope newScope = scopeChecker.extendCurrentScope();
+ VariableExpr windowVar = winExpr.getWindowVar();
+ addNewVarSymbolToScope(newScope, windowVar.getVar(), windowVar.getSourceLocation());
+ winExpr.setExprList(visit(winExpr.getExprList(), arg));
+ scopeChecker.replaceCurrentScope(preScope);
+ } else {
+ winExpr.setExprList(visit(winExpr.getExprList(), arg));
+ }
+ return winExpr;
+ }
+
// Adds a new encountered alias identifier into a scope
private void addNewVarSymbolToScope(Scope scope, VarIdentifier var, SourceLocation sourceLoc)
throws CompilationException {
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
index 9454984..d1092b3 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
@@ -46,6 +46,7 @@ import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.statement.FunctionDecl;
import org.apache.asterix.lang.common.statement.InsertStatement;
import org.apache.asterix.lang.common.statement.Query;
+import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.struct.QuantifiedPair;
import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
import org.apache.asterix.lang.sqlpp.clause.FromClause;
@@ -64,6 +65,7 @@ import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.expression.WindowExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
+import org.apache.hyracks.algebricks.common.utils.Pair;
public class AbstractSqlppSimpleExpressionVisitor
extends AbstractSqlppQueryExpressionVisitor<Expression, ILangExpression> {
@@ -217,8 +219,10 @@ public class AbstractSqlppSimpleExpressionVisitor
for (GbyVariableExpressionPair gbyVarExpr : gc.getGbyPairList()) {
gbyVarExpr.setExpr(visit(gbyVarExpr.getExpr(), gc));
}
- for (GbyVariableExpressionPair decVarExpr : gc.getDecorPairList()) {
- decVarExpr.setExpr(visit(decVarExpr.getExpr(), gc));
+ if (gc.hasDecorList()) {
+ for (GbyVariableExpressionPair decVarExpr : gc.getDecorPairList()) {
+ decVarExpr.setExpr(visit(decVarExpr.getExpr(), gc));
+ }
}
return null;
}
@@ -324,12 +328,30 @@ public class AbstractSqlppSimpleExpressionVisitor
@Override
public Expression visit(WindowExpression winExpr, ILangExpression arg) throws CompilationException {
- winExpr.setExpr(visit(winExpr.getExpr(), arg));
+ visitWindowExpressionExcludingExprList(winExpr, arg);
+ winExpr.setExprList(visit(winExpr.getExprList(), arg));
+ return winExpr;
+ }
+
+ protected void visitWindowExpressionExcludingExprList(WindowExpression winExpr, ILangExpression arg)
+ throws CompilationException {
if (winExpr.hasPartitionList()) {
winExpr.setPartitionList(visit(winExpr.getPartitionList(), winExpr));
}
- winExpr.setOrderbyList(visit(winExpr.getOrderbyList(), winExpr));
- return winExpr;
+ if (winExpr.hasOrderByList()) {
+ winExpr.setOrderbyList(visit(winExpr.getOrderbyList(), winExpr));
+ }
+ if (winExpr.hasFrameStartExpr()) {
+ winExpr.setFrameStartExpr(visit(winExpr.getFrameStartExpr(), winExpr));
+ }
+ if (winExpr.hasFrameEndExpr()) {
+ winExpr.setFrameEndExpr(visit(winExpr.getFrameEndExpr(), winExpr));
+ }
+ if (winExpr.hasWindowFieldList()) {
+ for (Pair<Expression, Identifier> field : winExpr.getWindowFieldList()) {
+ field.first = visit(field.first, arg);
+ }
+ }
}
@Override
@@ -391,8 +413,8 @@ public class AbstractSqlppSimpleExpressionVisitor
return expr;
}
- private List<Expression> visit(List<Expression> exprs, ILangExpression arg) throws CompilationException {
- List<Expression> newExprList = new ArrayList<>();
+ protected List<Expression> visit(List<Expression> exprs, ILangExpression arg) throws CompilationException {
+ List<Expression> newExprList = new ArrayList<>(exprs.size());
for (Expression expr : exprs) {
newExprList.add(visit(expr, arg));
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 19f2cee..4078389 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -186,6 +186,21 @@ import org.apache.hyracks.api.exceptions.SourceLocation;
class SQLPPParser extends ScopeChecker implements IParser {
+ // tokens parsed as identifiers
+ private static final String CURRENT = "CURRENT";
+ private static final String EXCLUDE = "EXCLUDE";
+ private static final String FOLLOWING = "FOLLOWING";
+ private static final String GROUPS = "GROUPS";
+ private static final String NO = "NO";
+ private static final String OTHERS = "OTHERS";
+ private static final String PARTITION = "PARTITION";
+ private static final String PRECEDING = "PRECEDING";
+ private static final String RANGE = "RANGE";
+ private static final String ROW = "ROW";
+ private static final String ROWS = "ROWS";
+ private static final String TIES = "TIES";
+ private static final String UNBOUNDED = "UNBOUNDED";
+
// optimizer hints
private static final String AUTO_HINT = "auto";
private static final String BROADCAST_JOIN_HINT = "bcast";
@@ -372,6 +387,33 @@ class SQLPPParser extends ScopeChecker implements IParser {
expr.setSourceLocation(getSourceLocation(token));
return expr;
}
+
+ private boolean isToken(String image) {
+ return token.image.equalsIgnoreCase(image);
+ }
+
+ private void expectToken(String image) throws SqlppParseException {
+ if (!isToken(image)) {
+ throw createUnexpectedTokenError();
+ }
+ }
+
+ private SqlppParseException createUnexpectedTokenError() {
+ return new SqlppParseException(getSourceLocation(token), "Unexpected token: " + token.image);
+ }
+
+ private boolean laToken(int idx, int kind, String image) {
+ Token t = getToken(idx);
+ return t.kind == kind && t.image.equalsIgnoreCase(image);
+ }
+
+ private boolean laIdentifier(int idx, String image) {
+ return laToken(idx, IDENTIFIER, image);
+ }
+
+ private boolean laIdentifier(String image) {
+ return laIdentifier(1, image);
+ }
}
PARSER_END(SQLPPParser)
@@ -2489,6 +2531,36 @@ VariableExpr Variable() throws ParseException:
}
}
+Pair<VariableExpr, List<Pair<Expression, Identifier>>> VariableWithFieldMap() throws ParseException:
+{
+ VariableExpr var = null;
+ List<Pair<Expression, Identifier>> fieldList = new ArrayList<Pair<Expression, Identifier>>();
+}
+{
+ var = Variable()
+ ( LOOKAHEAD(1)
+ {
+ VariableExpr fieldVarExpr = null;
+ String fieldIdentifierStr = null;
+ }
+ <LEFTPAREN>
+ fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
+ {
+ fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
+ }
+ (<COMMA>
+ fieldVarExpr = VariableRef() <AS> fieldIdentifierStr = Identifier()
+ {
+ fieldList.add(new Pair<Expression, Identifier>(fieldVarExpr, new Identifier(fieldIdentifierStr)));
+ }
+ )*
+ <RIGHTPAREN>
+ )?
+ {
+ return new Pair<VariableExpr, List<Pair<Expression, Identifier>>>(var, fieldList);
+ }
+}
+
VariableExpr ExternalVariableRef() throws ParseException:
{
String name = null;
@@ -2615,6 +2687,7 @@ FieldBinding FieldBinding() throws ParseException:
Expression FunctionCallExpr() throws ParseException:
{
Expression resultExpr;
+ CallExpr callExpr;
List<Expression> argList = new ArrayList<Expression>();
Expression tmp = null;
int arity = 0;
@@ -2622,10 +2695,6 @@ Expression FunctionCallExpr() throws ParseException:
String hint = null;
boolean star = false;
boolean distinct = false;
- Token overToken = null;
- Expression partitionExpr = null;
- List<Expression> partitionExprs = new ArrayList<Expression>();
- OrderbyClause orderByClause = null;
}
{
funcName = FunctionName()
@@ -2664,7 +2733,7 @@ Expression FunctionCallExpr() throws ParseException:
if (signature == null) {
signature = new FunctionSignature(funcName.dataverse, fqFunctionName, arity);
}
- CallExpr callExpr = FunctionMapUtil.normalizedListInputFunctions(new CallExpr(signature,argList));
+ callExpr = FunctionMapUtil.normalizedListInputFunctions(new CallExpr(signature,argList));
if (hint != null) {
if (hint.startsWith(INDEXED_NESTED_LOOP_JOIN_HINT)) {
callExpr.addHint(IndexedNLJoinExpressionAnnotation.INSTANCE);
@@ -2676,28 +2745,171 @@ Expression FunctionCallExpr() throws ParseException:
resultExpr = callExpr;
}
+ ( <OVER> resultExpr = WindowExpr(callExpr.getFunctionSignature(), callExpr.getExprList(), token) )?
+
+ {
+ return resultExpr;
+ }
+}
+
+WindowExpression WindowExpr(FunctionSignature signature, List<Expression> argList, Token startToken) throws ParseException:
+{
+ Expression partitionExpr = null;
+ List<Expression> partitionExprs = new ArrayList<Expression>();
+ OrderbyClause orderByClause = null;
+ List<Expression> orderbyList = null;
+ List<OrderbyClause.OrderModifier> orderbyModifierList = null;
+ WindowExpression.FrameMode frameMode = null;
+ Pair<WindowExpression.FrameBoundaryKind, Expression> frameStart = null, frameEnd = null;
+ WindowExpression.FrameBoundaryKind frameStartKind = null, frameEndKind = null;
+ Expression frameStartExpr = null, frameEndExpr = null;
+ WindowExpression.FrameExclusionKind frameExclusionKind = null;
+ Pair<VariableExpr, List<Pair<Expression, Identifier>>> windowVarWithFieldList = null;
+ VariableExpr windowVar = null;
+ List<Pair<Expression, Identifier>> windowFieldList = null;
+}
+{
+ (
+ windowVarWithFieldList = VariableWithFieldMap() <AS>
+ {
+ windowVar = windowVarWithFieldList.first;
+ windowFieldList = windowVarWithFieldList.second;
+ }
+ )?
+ <LEFTPAREN>
+ (
+ <IDENTIFIER> { expectToken(PARTITION); } <BY>
+ partitionExpr = Expression() { partitionExprs.add(partitionExpr); }
+ ( <COMMA> partitionExpr = Expression() { partitionExprs.add(partitionExpr); } )*
+ )?
(
- <OVER> { overToken = token; }
- <LEFTPAREN>
- (
- <PARTITION> <BY>
- partitionExpr = Expression() { partitionExprs.add(partitionExpr); }
- ( <COMMA> partitionExpr = Expression() { partitionExprs.add(partitionExpr); } )*
- )?
orderByClause = OrderbyClause()
- <RIGHTPAREN>
{
- WindowExpression winExp = new WindowExpression(callExpr, partitionExprs, orderByClause.getOrderbyList(),
- orderByClause.getModifierList());
- resultExpr = addSourceLocation(winExp, overToken);
+ orderbyList = orderByClause.getOrderbyList();
+ orderbyModifierList = orderByClause.getModifierList();
}
+ (
+ frameMode = WindowFrameMode()
+ (
+ frameStart = WindowFrameBoundary() |
+ ( <BETWEEN> frameStart = WindowFrameBoundary() <AND> frameEnd = WindowFrameBoundary() )
+ )
+ ( frameExclusionKind = WindowFrameExclusion() )?
+ {
+ frameStartKind = frameStart.first;
+ frameStartExpr = frameStart.second;
+ if (frameEnd == null) {
+ frameEndKind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
+ } else {
+ frameEndKind = frameEnd.first;
+ frameEndExpr = frameEnd.second;
+ }
+ if (frameExclusionKind == null) {
+ frameExclusionKind = WindowExpression.FrameExclusionKind.NO_OTHERS;
+ }
+ }
+ )?
)?
+ <RIGHTPAREN>
+ {
+ WindowExpression winExp = new WindowExpression(signature, argList, partitionExprs, orderbyList, orderbyModifierList,
+ frameMode, frameStartKind, frameStartExpr, frameEndKind, frameEndExpr, frameExclusionKind, windowVar,
+ windowFieldList);
+ return addSourceLocation(winExp, startToken);
+ }
+}
+WindowExpression.FrameMode WindowFrameMode() throws ParseException:
+{
+}
+{
+ <IDENTIFIER>
{
- return resultExpr;
+ if (isToken(RANGE)) {
+ return WindowExpression.FrameMode.RANGE;
+ } else if (isToken(ROWS)) {
+ return WindowExpression.FrameMode.ROWS;
+ } else if (isToken(GROUPS)) {
+ return WindowExpression.FrameMode.GROUPS;
+ } else {
+ throw createUnexpectedTokenError();
+ }
+ }
+}
+
+Pair<WindowExpression.FrameBoundaryKind, Expression> WindowFrameBoundary() throws ParseException:
+{
+ boolean current = false;
+ Expression expr = null;
+}
+{
+ (
+ LOOKAHEAD({ laIdentifier(CURRENT) }) <IDENTIFIER> { current = true; }
+ | LOOKAHEAD({ laIdentifier(UNBOUNDED) }) <IDENTIFIER>
+ | expr = Expression()
+ )
+ <IDENTIFIER>
+ {
+ WindowExpression.FrameBoundaryKind kind;
+ if (current && isToken(ROW)) {
+ kind = WindowExpression.FrameBoundaryKind.CURRENT_ROW;
+ } else if (!current && isToken(PRECEDING)) {
+ kind = expr == null
+ ? WindowExpression.FrameBoundaryKind.UNBOUNDED_PRECEDING
+ : WindowExpression.FrameBoundaryKind.BOUNDED_PRECEDING;
+ } else if (!current && isToken(FOLLOWING)) {
+ kind = expr == null
+ ? WindowExpression.FrameBoundaryKind.UNBOUNDED_FOLLOWING
+ : WindowExpression.FrameBoundaryKind.BOUNDED_FOLLOWING;
+ } else {
+ throw createUnexpectedTokenError();
+ }
+ return new Pair<WindowExpression.FrameBoundaryKind, Expression>(kind, expr);
}
}
+WindowExpression.FrameExclusionKind WindowFrameExclusion() throws ParseException:
+{
+ boolean current = false, no = false;
+}
+{
+ <IDENTIFIER>
+ {
+ expectToken(EXCLUDE);
+ }
+ (
+ <GROUP>
+ {
+ return WindowExpression.FrameExclusionKind.GROUP;
+ }
+ |
+ (
+ <IDENTIFIER>
+ {
+ if (isToken(TIES)) {
+ return WindowExpression.FrameExclusionKind.TIES;
+ } else if (isToken(CURRENT)) {
+ current = true;
+ } else if (isToken(NO)) {
+ no = true;
+ } else {
+ throw createUnexpectedTokenError();
+ }
+ }
+ <IDENTIFIER>
+ {
+ if (current && isToken(ROW)) {
+ return WindowExpression.FrameExclusionKind.CURRENT_ROW;
+ } else if (no && isToken(OTHERS)) {
+ return WindowExpression.FrameExclusionKind.NO_OTHERS;
+ } else {
+ throw createUnexpectedTokenError();
+ }
+ }
+ )
+ )
+}
+
Expression ParenthesizedExpression() throws ParseException:
{
Expression expr;
@@ -3166,9 +3378,9 @@ GroupbyClause GroupbyClause()throws ParseException :
Expression expr = null;
VariableExpr decorVar = null;
Expression decorExpr = null;
-
+ Pair<VariableExpr, List<Pair<Expression, Identifier>>> groupVarWithFieldList = null;
VariableExpr groupVar = null;
- List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<Pair<Expression, Identifier>>();
+ List<Pair<Expression, Identifier>> groupFieldList = null;
}
{
{
@@ -3212,25 +3424,11 @@ GroupbyClause GroupbyClause()throws ParseException :
}
)*
)
- (<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>
- )?
+ (<GROUP> <AS> groupVarWithFieldList = VariableWithFieldMap()
+ {
+ groupVar = groupVarWithFieldList.first;
+ groupFieldList = groupVarWithFieldList.second;
+ }
)?
{
gbc.setGbyPairList(vePairList);
@@ -3446,7 +3644,6 @@ TOKEN [IGNORE_CASE]:
| <OUTPUT : "output">
| <OVER: "over">
| <PATH : "path">
- | <PARTITION : "partition">
| <POLICY : "policy">
| <PRESORTED : "pre-sorted">
| <PRIMARY : "primary">
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/ADayTimeDuration.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/ADayTimeDuration.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/ADayTimeDuration.java
index 6017d4b..7e30e2a 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/ADayTimeDuration.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/ADayTimeDuration.java
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.asterix.om.base.temporal.GregorianCalendarSystem;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
@@ -37,6 +38,16 @@ public class ADayTimeDuration implements IAObject {
return chrononInMillisecond;
}
+ @Override
+ public String toString() {
+ StringBuilder sbder = new StringBuilder();
+ sbder.append("day_time_duration: {");
+ GregorianCalendarSystem.getInstance().getDurationExtendStringRepWithTimezoneUntilField(chrononInMillisecond, 0,
+ sbder);
+ sbder.append(" }");
+ return sbder.toString();
+ }
+
/* (non-Javadoc)
* @see org.apache.hyracks.api.dataflow.value.JSONSerializable#toJSON()
*/
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/AYearMonthDuration.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/AYearMonthDuration.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/AYearMonthDuration.java
index fd35adf..138d79c 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/AYearMonthDuration.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/AYearMonthDuration.java
@@ -49,7 +49,8 @@ public class AYearMonthDuration implements IAObject {
public String toString() {
StringBuilder sbder = new StringBuilder();
sbder.append("year_month_duration: {");
- GregorianCalendarSystem.getInstance().getDurationMonth(chrononInMonth);
+ GregorianCalendarSystem.getInstance().getDurationExtendStringRepWithTimezoneUntilField(0, chrononInMonth,
+ sbder);
sbder.append(" }");
return sbder.toString();
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
index 1bb5aa9..08f5139 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
@@ -165,9 +165,12 @@ public class BuiltinFunctions {
private static final Map<IFunctionInfo, IFunctionInfo> scalarToAggregateFunctionMap = new HashMap<>();
private static final Map<IFunctionInfo, IFunctionInfo> distinctToRegularScalarAggregateFunctionMap =
new HashMap<>();
- private static final Map<IFunctionInfo, IFunctionInfo> builtinWindowFunctions = new HashMap<>();
- private static final Set<IFunctionInfo> builtinWindowFunctionsWithOrderArgs = new HashSet<>();
- private static final Set<IFunctionInfo> builtinWindowFunctionsWithMaterialization = new HashSet<>();
+ private static final Map<IFunctionInfo, IFunctionInfo> sqlToWindowFunctions = new HashMap<>();
+ private static final Set<IFunctionInfo> windowFunctions = new HashSet<>();
+ private static final Set<IFunctionInfo> windowFunctionsWithListArg = new HashSet<>();
+ private static final Set<IFunctionInfo> windowFunctionsWithFrameClause = new HashSet<>();
+ private static final Set<IFunctionInfo> windowFunctionsWithOrderArgs = new HashSet<>();
+ private static final Set<IFunctionInfo> windowFunctionsWithMaterialization = new HashSet<>();
private static final Map<IFunctionInfo, SpatialFilterKind> spatialFilterFunctions = new HashMap<>();
@@ -490,6 +493,8 @@ public class BuiltinFunctions {
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-first-element", 1);
public static final FunctionIdentifier LOCAL_FIRST_ELEMENT =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-local-first-element", 1);
+ public static final FunctionIdentifier LAST_ELEMENT =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-last-element", 1);
public static final FunctionIdentifier STDDEV =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-stddev", 1);
public static final FunctionIdentifier GLOBAL_STDDEV =
@@ -538,6 +543,10 @@ public class BuiltinFunctions {
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "local-avg", 1);
public static final FunctionIdentifier SCALAR_FIRST_ELEMENT =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "first-element", 1);
+ public static final FunctionIdentifier SCALAR_LOCAL_FIRST_ELEMENT =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "local-first-element", 1);
+ public static final FunctionIdentifier SCALAR_LAST_ELEMENT =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "last-element", 1);
public static final FunctionIdentifier SCALAR_STDDEV =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "stddev", 1);
public static final FunctionIdentifier SCALAR_GLOBAL_STDDEV =
@@ -843,23 +852,43 @@ public class BuiltinFunctions {
// window functions
public static final FunctionIdentifier ROW_NUMBER =
- new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "row-number", 0);
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "row_number", 0);
public static final FunctionIdentifier ROW_NUMBER_IMPL =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "row-number-impl", 0);
public static final FunctionIdentifier RANK = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "rank", 0);
public static final FunctionIdentifier RANK_IMPL =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "rank-impl", FunctionIdentifier.VARARGS);
public static final FunctionIdentifier DENSE_RANK =
- new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "dense-rank", 0);
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "dense_rank", 0);
public static final FunctionIdentifier DENSE_RANK_IMPL =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "dense-rank-impl", FunctionIdentifier.VARARGS);
public static final FunctionIdentifier PERCENT_RANK =
- new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "percent-rank", 0);
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "percent_rank", 0);
public static final FunctionIdentifier PERCENT_RANK_IMPL =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "percent-rank-impl", FunctionIdentifier.VARARGS);
public static final FunctionIdentifier NTILE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "ntile", 1);
public static final FunctionIdentifier NTILE_IMPL =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "ntile-impl", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier LEAD =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "lead", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier LEAD_IMPL =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "lead-impl", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier LAG =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "lag", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier LAG_IMPL =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "lag-impl", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier FIRST_VALUE =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "first_value", 1);
+ public static final FunctionIdentifier FIRST_VALUE_IMPL =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "first-value-impl", 1);
+ public static final FunctionIdentifier LAST_VALUE =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "last_value", 1);
+ public static final FunctionIdentifier LAST_VALUE_IMPL =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "last-value-impl", 1);
+ public static final FunctionIdentifier NTH_VALUE =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "nth_value", 2);
+ public static final FunctionIdentifier NTH_VALUE_IMPL =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "nth-value-impl", 2);
// unnesting functions
public static final FunctionIdentifier SCAN_COLLECTION =
@@ -1335,6 +1364,8 @@ public class BuiltinFunctions {
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "if-null", FunctionIdentifier.VARARGS);
public static final FunctionIdentifier IF_MISSING_OR_NULL =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "if-missing-or-null", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier IF_SYSTEM_NULL =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "if-system-null", FunctionIdentifier.VARARGS);
public static final FunctionIdentifier IF_INF =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "if-inf", FunctionIdentifier.VARARGS);
public static final FunctionIdentifier IF_NAN =
@@ -1420,7 +1451,7 @@ public class BuiltinFunctions {
// and then, Asterix builtin functions
addPrivateFunction(CHECK_UNKNOWN, NotUnknownTypeComputer.INSTANCE, true);
- addPrivateFunction(ANY_COLLECTION_MEMBER, CollectionMemberResultType.INSTANCE, true);
+ addPrivateFunction(ANY_COLLECTION_MEMBER, CollectionMemberResultType.INSTANCE_MISSABLE, true);
addFunction(BOOLEAN_CONSTRUCTOR, ABooleanTypeComputer.INSTANCE, true);
addFunction(CIRCLE_CONSTRUCTOR, ACircleTypeComputer.INSTANCE, true);
addPrivateFunction(CONCAT_NON_NULL, ConcatNonNullTypeComputer.INSTANCE, true);
@@ -1578,6 +1609,7 @@ public class BuiltinFunctions {
addFunction(IF_NULL, IfNullTypeComputer.INSTANCE, true);
addFunction(IF_NAN, IfNanOrInfTypeComputer.INSTANCE_SKIP_MISSING, true);
addFunction(IF_NAN_OR_INF, IfNanOrInfTypeComputer.INSTANCE_SKIP_MISSING, true);
+ addPrivateFunction(IF_SYSTEM_NULL, IfNullTypeComputer.INSTANCE, true);
addFunction(MISSING_IF, MissingIfTypeComputer.INSTANCE, true);
addFunction(NULL_IF, NullIfTypeComputer.INSTANCE, true);
@@ -1595,9 +1627,12 @@ public class BuiltinFunctions {
addPrivateFunction(LOCAL_AVG, LocalAvgTypeComputer.INSTANCE, true);
addFunction(AVG, NullableDoubleTypeComputer.INSTANCE, true);
addPrivateFunction(GLOBAL_AVG, NullableDoubleTypeComputer.INSTANCE, true);
- addPrivateFunction(SCALAR_FIRST_ELEMENT, CollectionMemberResultType.INSTANCE, true);
- addPrivateFunction(FIRST_ELEMENT, PropagateTypeComputer.INSTANCE, true);
- addPrivateFunction(LOCAL_FIRST_ELEMENT, PropagateTypeComputer.INSTANCE, true);
+ addPrivateFunction(SCALAR_FIRST_ELEMENT, CollectionMemberResultType.INSTANCE_NULLABLE, true);
+ addPrivateFunction(SCALAR_LOCAL_FIRST_ELEMENT, CollectionMemberResultType.INSTANCE_NULLABLE, true);
+ addPrivateFunction(SCALAR_LAST_ELEMENT, CollectionMemberResultType.INSTANCE_NULLABLE, true);
+ addPrivateFunction(FIRST_ELEMENT, PropagateTypeComputer.INSTANCE_NULLABLE, true);
+ addPrivateFunction(LOCAL_FIRST_ELEMENT, PropagateTypeComputer.INSTANCE_NULLABLE, true);
+ addPrivateFunction(LAST_ELEMENT, PropagateTypeComputer.INSTANCE_NULLABLE, true);
addPrivateFunction(LOCAL_STDDEV, LocalSingleVarStatisticsTypeComputer.INSTANCE, true);
addFunction(STDDEV, NullableDoubleTypeComputer.INSTANCE, true);
addPrivateFunction(GLOBAL_STDDEV, NullableDoubleTypeComputer.INSTANCE, true);
@@ -1796,16 +1831,26 @@ public class BuiltinFunctions {
// Window functions
- addFunction(ROW_NUMBER, AInt64TypeComputer.INSTANCE, true);
- addPrivateFunction(ROW_NUMBER_IMPL, AInt64TypeComputer.INSTANCE, true);
- addFunction(RANK, AInt64TypeComputer.INSTANCE, true);
- addPrivateFunction(RANK_IMPL, AInt64TypeComputer.INSTANCE, true);
- addFunction(DENSE_RANK, AInt64TypeComputer.INSTANCE, true);
- addPrivateFunction(DENSE_RANK_IMPL, AInt64TypeComputer.INSTANCE, true);
- addFunction(PERCENT_RANK, ADoubleTypeComputer.INSTANCE, true);
- addPrivateFunction(PERCENT_RANK_IMPL, ADoubleTypeComputer.INSTANCE, true);
- addFunction(NTILE, AInt64TypeComputer.INSTANCE, true);
- addPrivateFunction(NTILE_IMPL, AInt64TypeComputer.INSTANCE, true);
+ addFunction(ROW_NUMBER, AInt64TypeComputer.INSTANCE, false);
+ addFunction(ROW_NUMBER_IMPL, AInt64TypeComputer.INSTANCE, false);
+ addFunction(RANK, AInt64TypeComputer.INSTANCE, false);
+ addFunction(RANK_IMPL, AInt64TypeComputer.INSTANCE, false);
+ addFunction(DENSE_RANK, AInt64TypeComputer.INSTANCE, false);
+ addFunction(DENSE_RANK_IMPL, AInt64TypeComputer.INSTANCE, false);
+ addFunction(PERCENT_RANK, ADoubleTypeComputer.INSTANCE, false);
+ addFunction(PERCENT_RANK_IMPL, ADoubleTypeComputer.INSTANCE, false);
+ addFunction(NTILE, AInt64TypeComputer.INSTANCE_NULLABLE, false);
+ addFunction(NTILE_IMPL, AInt64TypeComputer.INSTANCE_NULLABLE, false);
+ addFunction(LEAD, AnyTypeComputer.INSTANCE, false);
+ addFunction(LEAD_IMPL, AnyTypeComputer.INSTANCE, false);
+ addFunction(LAG, AnyTypeComputer.INSTANCE, false);
+ addFunction(LAG_IMPL, AnyTypeComputer.INSTANCE, false);
+ addFunction(FIRST_VALUE, CollectionMemberResultType.INSTANCE_NULLABLE, false);
+ addFunction(FIRST_VALUE_IMPL, CollectionMemberResultType.INSTANCE_NULLABLE, false);
+ addFunction(LAST_VALUE, CollectionMemberResultType.INSTANCE_NULLABLE, false);
+ addFunction(LAST_VALUE_IMPL, CollectionMemberResultType.INSTANCE_NULLABLE, false);
+ addFunction(NTH_VALUE, CollectionMemberResultType.INSTANCE_NULLABLE, false);
+ addFunction(NTH_VALUE_IMPL, CollectionMemberResultType.INSTANCE_NULLABLE, false);
// Similarity functions
addFunction(EDIT_DISTANCE_CONTAINS, OrderedListOfAnyTypeComputer.INSTANCE, true);
@@ -2261,7 +2306,7 @@ public class BuiltinFunctions {
// FIRST_ELEMENT
- addAgg(SCALAR_FIRST_ELEMENT);
+ addAgg(FIRST_ELEMENT);
addAgg(LOCAL_FIRST_ELEMENT);
addLocalAgg(FIRST_ELEMENT, LOCAL_FIRST_ELEMENT);
addIntermediateAgg(LOCAL_FIRST_ELEMENT, FIRST_ELEMENT);
@@ -2269,6 +2314,12 @@ public class BuiltinFunctions {
addGlobalAgg(FIRST_ELEMENT, FIRST_ELEMENT);
addScalarAgg(FIRST_ELEMENT, SCALAR_FIRST_ELEMENT);
+ addScalarAgg(LOCAL_FIRST_ELEMENT, SCALAR_LOCAL_FIRST_ELEMENT);
+
+ // LAST_ELEMENT
+
+ addAgg(LAST_ELEMENT);
+ addScalarAgg(LAST_ELEMENT, SCALAR_LAST_ELEMENT);
// RANGE_MAP
addAgg(RANGE_MAP);
@@ -2574,11 +2625,16 @@ public class BuiltinFunctions {
static {
// Window functions
- addWindowFunction(ROW_NUMBER, ROW_NUMBER_IMPL, false, false);
- addWindowFunction(RANK, RANK_IMPL, true, false);
- addWindowFunction(DENSE_RANK, DENSE_RANK_IMPL, true, false);
- addWindowFunction(PERCENT_RANK, PERCENT_RANK_IMPL, true, true);
- addWindowFunction(NTILE, NTILE_IMPL, false, true);
+ addWindowFunction(ROW_NUMBER, ROW_NUMBER_IMPL, false, false, false, false);
+ addWindowFunction(RANK, RANK_IMPL, false, false, true, false);
+ addWindowFunction(DENSE_RANK, DENSE_RANK_IMPL, false, false, true, false);
+ addWindowFunction(PERCENT_RANK, PERCENT_RANK_IMPL, false, false, true, true);
+ addWindowFunction(NTILE, NTILE_IMPL, false, false, false, true);
+ addWindowFunction(LEAD, LEAD_IMPL, false, true, false, false);
+ addWindowFunction(LAG, LAG_IMPL, false, true, false, false);
+ addWindowFunction(FIRST_VALUE, FIRST_VALUE_IMPL, true, true, false, false);
+ addWindowFunction(LAST_VALUE, LAST_VALUE_IMPL, true, true, false, false);
+ addWindowFunction(NTH_VALUE, NTH_VALUE_IMPL, true, true, false, false);
}
static {
@@ -2762,38 +2818,59 @@ public class BuiltinFunctions {
getAsterixFunctionInfo(regularscalarfi));
}
- public static void addWindowFunction(FunctionIdentifier fi, FunctionIdentifier implfi, boolean requiresOrderArgs,
+ public static void addWindowFunction(FunctionIdentifier sqlfi, FunctionIdentifier winfi,
+ boolean supportsFrameClause, boolean hasListArg, boolean requiresOrderArgs,
boolean requiresMaterialization) {
- IFunctionInfo implFinfo = getAsterixFunctionInfo(implfi);
- builtinWindowFunctions.put(getAsterixFunctionInfo(fi), implFinfo);
+ IFunctionInfo sqlinfo = getAsterixFunctionInfo(sqlfi);
+ IFunctionInfo wininfo = getAsterixFunctionInfo(winfi);
+ sqlToWindowFunctions.put(sqlinfo, wininfo);
+ windowFunctions.add(wininfo);
+ if (supportsFrameClause) {
+ windowFunctionsWithFrameClause.add(wininfo);
+ }
+ if (hasListArg) {
+ windowFunctionsWithListArg.add(wininfo);
+ }
if (requiresOrderArgs) {
- builtinWindowFunctionsWithOrderArgs.add(implFinfo);
+ windowFunctionsWithOrderArgs.add(wininfo);
}
if (requiresMaterialization) {
- builtinWindowFunctionsWithMaterialization.add(implFinfo);
+ windowFunctionsWithMaterialization.add(wininfo);
}
}
- public static boolean isBuiltinWindowFunction(FunctionIdentifier fi) {
- return builtinWindowFunctions.containsKey(getAsterixFunctionInfo(fi));
+ public static FunctionIdentifier getWindowFunction(FunctionIdentifier sqlfi) {
+ IFunctionInfo finfo = sqlToWindowFunctions.get(getAsterixFunctionInfo(sqlfi));
+ return finfo == null ? null : finfo.getFunctionIdentifier();
+ }
+
+ public static boolean isWindowFunction(FunctionIdentifier winfi) {
+ return windowFunctions.contains(getAsterixFunctionInfo(winfi));
+ }
+
+ public static boolean windowFunctionSupportsFrameClause(FunctionIdentifier winfi) {
+ return windowFunctionsWithFrameClause.contains(getAsterixFunctionInfo(winfi));
+ }
+
+ public static boolean windowFunctionWithListArg(FunctionIdentifier winfi) {
+ return windowFunctionsWithListArg.contains(getAsterixFunctionInfo(winfi));
}
- public static boolean windowFunctionRequiresOrderArgs(FunctionIdentifier implfi) {
- return builtinWindowFunctionsWithOrderArgs.contains(getAsterixFunctionInfo(implfi));
+ public static boolean windowFunctionRequiresOrderArgs(FunctionIdentifier winfi) {
+ return windowFunctionsWithOrderArgs.contains(getAsterixFunctionInfo(winfi));
}
- public static boolean windowFunctionRequiresMaterialization(FunctionIdentifier implfi) {
- return builtinWindowFunctionsWithMaterialization.contains(getAsterixFunctionInfo(implfi));
+ public static boolean windowFunctionRequiresMaterialization(FunctionIdentifier winfi) {
+ return windowFunctionsWithMaterialization.contains(getAsterixFunctionInfo(winfi));
}
- public static AbstractFunctionCallExpression makeWindowFunctionExpression(FunctionIdentifier scalarfi,
+ public static AbstractFunctionCallExpression makeWindowFunctionExpression(FunctionIdentifier winfi,
List<Mutable<ILogicalExpression>> args) {
- IFunctionInfo finfo = getAsterixFunctionInfo(scalarfi);
- IFunctionInfo implFinfo = builtinWindowFunctions.get(finfo);
- if (implFinfo == null) {
+ IFunctionInfo finfo = getAsterixFunctionInfo(winfi);
+ if (finfo == null) {
throw new IllegalStateException("no implementation for window function " + finfo);
}
- return new StatefulFunctionCallExpression(implFinfo, UnpartitionedPropertyComputer.INSTANCE, args);
+ return new StatefulFunctionCallExpression(finfo, UnpartitionedPropertyComputer.INSTANCE, args);
}
static {
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.java
index 1db946d..26bc116 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CollectionMemberResultType.java
@@ -21,6 +21,7 @@ package org.apache.asterix.om.typecomputer.impl;
import org.apache.asterix.om.exceptions.TypeMismatchException;
import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.AbstractCollectionType;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
@@ -29,9 +30,19 @@ import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import org.apache.hyracks.api.exceptions.SourceLocation;
public class CollectionMemberResultType extends AbstractResultTypeComputer {
- public static final CollectionMemberResultType INSTANCE = new CollectionMemberResultType();
+ public static final CollectionMemberResultType INSTANCE = new CollectionMemberResultType(false, false);
- protected CollectionMemberResultType() {
+ public static final CollectionMemberResultType INSTANCE_NULLABLE = new CollectionMemberResultType(true, false);
+
+ public static final CollectionMemberResultType INSTANCE_MISSABLE = new CollectionMemberResultType(false, true);
+
+ private final boolean nullable;
+
+ private final boolean missable;
+
+ private CollectionMemberResultType(boolean nullable, boolean missable) {
+ this.missable = missable;
+ this.nullable = nullable;
}
@Override
@@ -49,7 +60,13 @@ public class CollectionMemberResultType extends AbstractResultTypeComputer {
if (type.getTypeTag() == ATypeTag.ANY) {
return BuiltinType.ANY;
}
- return ((AbstractCollectionType) type).getItemType();
+ IAType itemType = ((AbstractCollectionType) type).getItemType();
+ if (nullable) {
+ itemType = AUnionType.createNullableType(itemType);
+ }
+ if (missable) {
+ itemType = AUnionType.createMissableType(itemType);
+ }
+ return itemType;
}
-
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/PropagateTypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/PropagateTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/PropagateTypeComputer.java
index df4524f..2aea87d 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/PropagateTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/PropagateTypeComputer.java
@@ -19,6 +19,7 @@
package org.apache.asterix.om.typecomputer.impl;
import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.IAType;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
@@ -28,10 +29,19 @@ import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
*/
public class PropagateTypeComputer extends AbstractResultTypeComputer {
- public static final PropagateTypeComputer INSTANCE = new PropagateTypeComputer();
+ public static final PropagateTypeComputer INSTANCE = new PropagateTypeComputer(false);
+
+ public static final PropagateTypeComputer INSTANCE_NULLABLE = new PropagateTypeComputer(true);
+
+ private final boolean nullable;
+
+ public PropagateTypeComputer(boolean nullable) {
+ this.nullable = nullable;
+ }
@Override
public IAType getResultType(ILogicalExpression expr, IAType... knownTypes) throws AlgebricksException {
- return knownTypes[0];
+ IAType t = knownTypes[0];
+ return nullable ? AUnionType.createNullableType(t) : t;
}
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/LastElementAggregateDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/LastElementAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/LastElementAggregateDescriptor.java
new file mode 100644
index 0000000..4d2280b
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/LastElementAggregateDescriptor.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+package org.apache.asterix.runtime.aggregates.collections;
+
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluatorFactory;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+
+// This aggregate function simply returns the last item in an input stream.
+public class LastElementAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public static final IFunctionDescriptorFactory FACTORY = () -> new LastElementAggregateDescriptor();
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.LAST_ELEMENT;
+ }
+
+ @Override
+ public IAggregateEvaluatorFactory createAggregateEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new LastElementEvalFactory(args, sourceLoc);
+ }
+}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/LastElementEvalFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/LastElementEvalFactory.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/LastElementEvalFactory.java
new file mode 100644
index 0000000..4b0bf35
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/LastElementEvalFactory.java
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+package org.apache.asterix.runtime.aggregates.collections;
+
+import org.apache.asterix.runtime.aggregates.std.AbstractAggregateFunction;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluatorFactory;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.SourceLocation;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+class LastElementEvalFactory implements IAggregateEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+ private final IScalarEvaluatorFactory[] args;
+ private final SourceLocation sourceLoc;
+
+ LastElementEvalFactory(IScalarEvaluatorFactory[] args, SourceLocation sourceLoc) {
+ this.args = args;
+ this.sourceLoc = sourceLoc;
+ }
+
+ @Override
+ public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new AbstractAggregateFunction(sourceLoc) {
+
+ // Needs to copy the bytes from inputVal to outputVal because the byte space of inputVal could be re-used
+ // by consequent tuples.
+ private ArrayBackedValueStorage outputVal = new ArrayBackedValueStorage();
+ private IPointable inputVal = new VoidPointable();
+ private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
+ private boolean empty;
+
+ @Override
+ public void init() {
+ empty = true;
+ }
+
+ @Override
+ public void step(IFrameTupleReference tuple) throws HyracksDataException {
+ eval.evaluate(tuple, inputVal);
+ outputVal.assign(inputVal);
+ empty = false;
+ }
+
+ @Override
+ public void finish(IPointable result) {
+ if (empty) {
+ PointableHelper.setNull(result);
+ } else {
+ result.set(outputVal);
+ }
+ }
+
+ @Override
+ public void finishPartial(IPointable result) {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
index 38d8e05..9b28fb6 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
@@ -94,7 +94,7 @@ public class ATimeConstructorDescriptor extends AbstractScalarFunctionDynamicDes
// the string to be parsed should be at least 6 characters: hhmmss
if (stringLength < 6) {
throw new InvalidDataFormatException(sourceLoc, getIdentifier(),
- ATypeTag.SERIALIZED_POLYGON_TYPE_TAG);
+ ATypeTag.SERIALIZED_TIME_TYPE_TAG);
}
int chrononTimeInMs =
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
index 746273f..0038d58 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
@@ -308,11 +308,13 @@ public abstract class AbstractNumericArithmeticEval extends AbstractScalarFuncti
case FLOAT:
if (evaluateDouble(operandsFloating[0], operandsFloating[1], aDouble)) {
dres = aDouble.getDoubleValue();
- if (dres > Float.MAX_VALUE) {
- throw new OverflowException(sourceLoc, getIdentifier());
- }
- if (dres < -Float.MAX_VALUE) {
- throw new UnderflowException(sourceLoc, getIdentifier());
+ if (Double.isFinite(dres)) {
+ if (dres > Float.MAX_VALUE) {
+ throw new OverflowException(sourceLoc, getIdentifier());
+ }
+ if (dres < -Float.MAX_VALUE) {
+ throw new UnderflowException(sourceLoc, getIdentifier());
+ }
}
aFloat.setValue((float) dres);
floatSerde.serialize(aFloat, out);
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfSystemNullDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfSystemNullDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfSystemNullDescriptor.java
new file mode 100644
index 0000000..90df330
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfSystemNullDescriptor.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class IfSystemNullDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+ public static final IFunctionDescriptorFactory FACTORY = IfSystemNullDescriptor::new;
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(IScalarEvaluatorFactory[] args) throws AlgebricksException {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new IfMissingOrNullDescriptor.AbstractIfMissingOrNullEval(ctx, args) {
+ @Override
+ protected boolean skip(byte argTypeTag) {
+ return argTypeTag == ATypeTag.SERIALIZED_SYSTEM_NULL_TYPE_TAG;
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.IF_SYSTEM_NULL;
+ }
+}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
index dceb5a8..0487385 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
@@ -29,6 +29,7 @@ import org.apache.asterix.om.functions.IFunctionCollection;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
import org.apache.asterix.om.functions.IFunctionRegistrant;
import org.apache.asterix.runtime.aggregates.collections.FirstElementAggregateDescriptor;
+import org.apache.asterix.runtime.aggregates.collections.LastElementAggregateDescriptor;
import org.apache.asterix.runtime.aggregates.collections.ListifyAggregateDescriptor;
import org.apache.asterix.runtime.aggregates.collections.LocalFirstElementAggregateDescriptor;
import org.apache.asterix.runtime.aggregates.scalar.ScalarAvgAggregateDescriptor;
@@ -271,6 +272,7 @@ import org.apache.asterix.runtime.evaluators.functions.IfMissingOrNullDescriptor
import org.apache.asterix.runtime.evaluators.functions.IfNanDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IfNanOrInfDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IfNullDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.IfSystemNullDescriptor;
import org.apache.asterix.runtime.evaluators.functions.InjectFailureDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IsArrayDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IsAtomicDescriptor;
@@ -532,6 +534,7 @@ public final class FunctionCollection implements IFunctionCollection {
fc.add(LocalMinAggregateDescriptor.FACTORY);
fc.add(FirstElementAggregateDescriptor.FACTORY);
fc.add(LocalFirstElementAggregateDescriptor.FACTORY);
+ fc.add(LastElementAggregateDescriptor.FACTORY);
fc.add(StddevAggregateDescriptor.FACTORY);
fc.add(LocalStddevAggregateDescriptor.FACTORY);
fc.add(IntermediateStddevAggregateDescriptor.FACTORY);
@@ -702,6 +705,7 @@ public final class FunctionCollection implements IFunctionCollection {
fc.add(IfMissingDescriptor.FACTORY);
fc.add(IfNullDescriptor.FACTORY);
fc.add(IfMissingOrNullDescriptor.FACTORY);
+ fc.add(IfSystemNullDescriptor.FACTORY);
// uuid generators (zero independent functions)
fc.add(CreateUUIDDescriptor.FACTORY);
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/AbstractRankRunningAggregateEvaluator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/AbstractRankRunningAggregateEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/AbstractRankRunningAggregateEvaluator.java
index 54bcc1a..7e6d218 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/AbstractRankRunningAggregateEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/AbstractRankRunningAggregateEvaluator.java
@@ -51,9 +51,9 @@ public abstract class AbstractRankRunningAggregateEvaluator implements IWindowAg
private IBinaryComparator[] argComparators;
- private boolean first;
+ protected boolean first;
- private long rank;
+ protected long rank;
private long groupSize;
@@ -85,28 +85,28 @@ public abstract class AbstractRankRunningAggregateEvaluator implements IWindowAg
@Override
public void step(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ resultStorage.reset();
for (int i = 0; i < args.length; i++) {
args[i].evaluate(tuple, argCurrValues[i]);
}
computeRank();
+ computeResult(resultStorage.getDataOutput());
+
+ result.set(resultStorage);
for (int i = 0; i < args.length; i++) {
argPrevValues[i].assign(argCurrValues[i]);
}
-
- resultStorage.reset();
- writeResult(rank, resultStorage.getDataOutput());
- result.set(resultStorage);
+ first = false;
}
- protected abstract void writeResult(long rank, DataOutput out) throws HyracksDataException;
+ protected abstract void computeResult(DataOutput out) throws HyracksDataException;
private void computeRank() throws HyracksDataException {
if (first) {
rank = 1;
groupSize = 1;
- first = false;
} else if (sameGroup()) {
groupSize++;
} else {
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/NtileRunningAggregateEvaluator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/NtileRunningAggregateEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/NtileRunningAggregateEvaluator.java
index 9bd306e..aebef6a 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/NtileRunningAggregateEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/NtileRunningAggregateEvaluator.java
@@ -22,8 +22,10 @@ package org.apache.asterix.runtime.runningaggregates.std;
import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
import org.apache.asterix.om.base.AInt64;
import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
import org.apache.hyracks.algebricks.runtime.base.IWindowAggregateEvaluator;
@@ -63,6 +65,8 @@ public class NtileRunningAggregateEvaluator implements IWindowAggregateEvaluator
private long count;
+ private boolean isNull;
+
NtileRunningAggregateEvaluator(IScalarEvaluator evalNumGroups, FunctionIdentifier funId) {
this.evalNumGroups = evalNumGroups;
this.funId = funId;
@@ -76,6 +80,9 @@ public class NtileRunningAggregateEvaluator implements IWindowAggregateEvaluator
public void initPartition(long partitionLength) {
this.partitionLength = partitionLength;
resultValue = 0;
+ isNull = false;
+ groupSize = 1;
+ groupRemainder = 0;
}
@Override
@@ -93,23 +100,28 @@ public class NtileRunningAggregateEvaluator implements IWindowAggregateEvaluator
count = 1;
}
- resultStorage.reset();
- aInt64.setValue(resultValue);
- serde.serialize(aInt64, resultStorage.getDataOutput());
- result.set(resultStorage);
+ if (isNull) {
+ PointableHelper.setNull(result);
+ } else {
+ resultStorage.reset();
+ aInt64.setValue(resultValue);
+ serde.serialize(aInt64, resultStorage.getDataOutput());
+ result.set(resultStorage);
+ }
}
private void evaluateGroupSize(IFrameTupleReference tuple) throws HyracksDataException {
evalNumGroups.evaluate(tuple, argNumGroups);
byte[] bytes = argNumGroups.getByteArray();
int offset = argNumGroups.getStartOffset();
- long numGroups = ATypeHierarchy.getLongValue(funId.getName(), 0, bytes, offset);
- if (numGroups > partitionLength || numGroups <= 0) {
- groupSize = partitionLength;
- groupRemainder = 0;
+ if (bytes[offset] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
+ isNull = true;
} else {
- groupSize = partitionLength / numGroups;
- groupRemainder = partitionLength % numGroups;
+ long numGroups = ATypeHierarchy.getLongValue(funId.getName(), 0, bytes, offset);
+ if (numGroups > 0 && numGroups <= partitionLength) {
+ groupSize = partitionLength / numGroups;
+ groupRemainder = partitionLength % numGroups;
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/PercentRankRunningAggregateEvaluator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/PercentRankRunningAggregateEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/PercentRankRunningAggregateEvaluator.java
index c73d9fd..edad37f 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/PercentRankRunningAggregateEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/PercentRankRunningAggregateEvaluator.java
@@ -54,8 +54,8 @@ class PercentRankRunningAggregateEvaluator extends AbstractRankRunningAggregateE
}
@Override
- protected void writeResult(long rank, DataOutput out) throws HyracksDataException {
- double percentRank = (rank - 1) / divisor;
+ protected void computeResult(DataOutput out) throws HyracksDataException {
+ double percentRank = first ? 0 : (rank - 1) / divisor;
aDouble.setValue(percentRank);
serde.serialize(aDouble, out);
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/RankRunningAggregateEvaluator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/RankRunningAggregateEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/RankRunningAggregateEvaluator.java
index 56ab299..9eba129 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/RankRunningAggregateEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/runningaggregates/std/RankRunningAggregateEvaluator.java
@@ -45,7 +45,7 @@ class RankRunningAggregateEvaluator extends AbstractRankRunningAggregateEvaluato
super(args, dense, sourceLoc);
}
- protected void writeResult(long rank, DataOutput out) throws HyracksDataException {
+ protected void computeResult(DataOutput out) throws HyracksDataException {
aInt64.setValue(rank);
serde.serialize(aInt64, out);
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/asterixdb/src/main/licenses/templates/source_only_licenses.ftl
----------------------------------------------------------------------
diff --git a/asterixdb/src/main/licenses/templates/source_only_licenses.ftl b/asterixdb/src/main/licenses/templates/source_only_licenses.ftl
index eb75200..021416a 100644
--- a/asterixdb/src/main/licenses/templates/source_only_licenses.ftl
+++ b/asterixdb/src/main/licenses/templates/source_only_licenses.ftl
@@ -214,4 +214,30 @@ Accepting Warranty or Additional Liability. While redistributing the Work or Der
END OF TERMS AND CONDITIONS
</...@license>
+<@license files=["asterix-app/src/test/resources/runtimets/queries_sqlpp/window/pg_win/*", "asterix-app/data/tenk.tbl"]
+ component="AsterixDB tests" licenseName="PostgreSQL License">
+PostgreSQL Database Management System
+(formerly known as Postgres, then as Postgres95)
+
+Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
+
+Portions Copyright (c) 1994, The Regents of the University of California
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this
+paragraph and the following two paragraphs appear in all copies.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+</...@license>
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractOperatorWithNestedPlans.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractOperatorWithNestedPlans.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractOperatorWithNestedPlans.java
index 167c022..95e60a9 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractOperatorWithNestedPlans.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractOperatorWithNestedPlans.java
@@ -28,6 +28,11 @@ import org.apache.commons.lang3.mutable.Mutable;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import org.apache.hyracks.algebricks.core.algebra.properties.TypePropagationPolicy;
+import org.apache.hyracks.algebricks.core.algebra.typing.ITypeEnvPointer;
+import org.apache.hyracks.algebricks.core.algebra.typing.ITypingContext;
+import org.apache.hyracks.algebricks.core.algebra.typing.OpRefTypeEnvPointer;
+import org.apache.hyracks.algebricks.core.algebra.typing.PropagatingTypeEnvironment;
public abstract class AbstractOperatorWithNestedPlans extends AbstractLogicalOperator {
protected final List<ILogicalPlan> nestedPlans;
@@ -87,6 +92,35 @@ public abstract class AbstractOperatorWithNestedPlans extends AbstractLogicalOpe
return false;
}
+ protected PropagatingTypeEnvironment createNestedPlansPropagatingTypeEnvironment(ITypingContext ctx,
+ boolean propagateInput) {
+ int n = 0;
+ for (ILogicalPlan p : nestedPlans) {
+ n += p.getRoots().size();
+ }
+
+ int i;
+ ITypeEnvPointer[] envPointers;
+ if (propagateInput) {
+ i = inputs.size();
+ envPointers = new ITypeEnvPointer[n + i];
+ for (int j = 0; j < i; j++) {
+ envPointers[j] = new OpRefTypeEnvPointer(inputs.get(j), ctx);
+ }
+ } else {
+ envPointers = new ITypeEnvPointer[n];
+ i = 0;
+ }
+ for (ILogicalPlan p : nestedPlans) {
+ for (Mutable<ILogicalOperator> r : p.getRoots()) {
+ envPointers[i] = new OpRefTypeEnvPointer(r, ctx);
+ i++;
+ }
+ }
+ return new PropagatingTypeEnvironment(ctx.getExpressionTypeComputer(), ctx.getMissableTypeComputer(),
+ ctx.getMetadataProvider(), TypePropagationPolicy.ALL, envPointers);
+ }
+
public abstract void getUsedVariablesExceptNestedPlans(Collection<LogicalVariable> vars);
public abstract void getProducedVariablesExceptNestedPlans(Collection<LogicalVariable> vars);
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f2c18aa9/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/GroupByOperator.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/GroupByOperator.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/GroupByOperator.java
index 365d77e..49bf062 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/GroupByOperator.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/GroupByOperator.java
@@ -34,12 +34,8 @@ import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
-import org.apache.hyracks.algebricks.core.algebra.properties.TypePropagationPolicy;
import org.apache.hyracks.algebricks.core.algebra.properties.VariablePropagationPolicy;
-import org.apache.hyracks.algebricks.core.algebra.typing.ITypeEnvPointer;
import org.apache.hyracks.algebricks.core.algebra.typing.ITypingContext;
-import org.apache.hyracks.algebricks.core.algebra.typing.OpRefTypeEnvPointer;
-import org.apache.hyracks.algebricks.core.algebra.typing.PropagatingTypeEnvironment;
import org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionReferenceTransform;
import org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalOperatorVisitor;
@@ -233,20 +229,7 @@ public class GroupByOperator extends AbstractOperatorWithNestedPlans {
@Override
public IVariableTypeEnvironment computeOutputTypeEnvironment(ITypingContext ctx) throws AlgebricksException {
- int n = 0;
- for (ILogicalPlan p : nestedPlans) {
- n += p.getRoots().size();
- }
- ITypeEnvPointer[] envPointers = new ITypeEnvPointer[n];
- int i = 0;
- for (ILogicalPlan p : nestedPlans) {
- for (Mutable<ILogicalOperator> r : p.getRoots()) {
- envPointers[i] = new OpRefTypeEnvPointer(r, ctx);
- i++;
- }
- }
- IVariableTypeEnvironment env = new PropagatingTypeEnvironment(ctx.getExpressionTypeComputer(),
- ctx.getMissableTypeComputer(), ctx.getMetadataProvider(), TypePropagationPolicy.ALL, envPointers);
+ IVariableTypeEnvironment env = createNestedPlansPropagatingTypeEnvironment(ctx, false);
ILogicalOperator child = inputs.get(0).getValue();
IVariableTypeEnvironment env2 = ctx.getOutputTypeEnvironment(child);
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : getGroupByList()) {