Search in sources :

Example 6 with GbyVariableExpressionPair

use of org.apache.asterix.lang.common.expression.GbyVariableExpressionPair in project asterixdb by apache.

the class SqlppGroupByVisitor method visit.

@Override
public Expression visit(SelectBlock selectBlock, ILangExpression arg) throws CompilationException {
    // Traverses the select block in the order of "from", "let"s, "where",
    // "group by", "let"s, "having" and "select".
    FromClause fromClause = selectBlock.getFromClause();
    if (selectBlock.hasFromClause()) {
        fromClause.accept(this, arg);
    }
    if (selectBlock.hasLetClauses()) {
        List<LetClause> letList = selectBlock.getLetList();
        for (LetClause letClause : letList) {
            letClause.accept(this, arg);
        }
    }
    if (selectBlock.hasWhereClause()) {
        selectBlock.getWhereClause().accept(this, arg);
    }
    if (selectBlock.hasGroupbyClause()) {
        GroupbyClause groupbyClause = selectBlock.getGroupbyClause();
        groupbyClause.accept(this, fromClause);
        Collection<VariableExpr> visibleVarsInCurrentScope = SqlppVariableUtil.getBindingVariables(groupbyClause);
        VariableExpr groupVar = groupbyClause.getGroupVar();
        Set<VariableExpr> groupFieldVars = getGroupFieldVariables(groupbyClause);
        Collection<VariableExpr> freeVariablesInGbyLets = new HashSet<>();
        if (selectBlock.hasLetClausesAfterGroupby()) {
            List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
            for (LetClause letClauseAfterGby : letListAfterGby) {
                letClauseAfterGby.accept(this, arg);
                // Rewrites each let clause after the group-by.
                SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, letClauseAfterGby, context);
                Collection<VariableExpr> freeVariablesInLet = SqlppVariableUtil.getFreeVariables(letClauseAfterGby.getBindingExpr());
                freeVariablesInLet.removeAll(visibleVarsInCurrentScope);
                freeVariablesInGbyLets.addAll(freeVariablesInLet);
                visibleVarsInCurrentScope.add(letClauseAfterGby.getVarExpr());
            }
        }
        Collection<VariableExpr> freeVariables = new HashSet<>();
        if (selectBlock.hasHavingClause()) {
            // Rewrites the having clause.
            HavingClause havingClause = selectBlock.getHavingClause();
            havingClause.accept(this, arg);
            SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, havingClause, context);
            freeVariables.addAll(SqlppVariableUtil.getFreeVariables(havingClause));
        }
        SelectExpression parentSelectExpression = (SelectExpression) arg;
        // We cannot rewrite ORDER BY and LIMIT if it's a SET operation query.
        if (!parentSelectExpression.getSelectSetOperation().hasRightInputs()) {
            if (parentSelectExpression.hasOrderby()) {
                // Rewrites the ORDER BY clause.
                OrderbyClause orderbyClause = parentSelectExpression.getOrderbyClause();
                orderbyClause.accept(this, arg);
                SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, orderbyClause, context);
                freeVariables.addAll(SqlppVariableUtil.getFreeVariables(orderbyClause));
            }
            if (parentSelectExpression.hasLimit()) {
                // Rewrites the LIMIT clause.
                LimitClause limitClause = parentSelectExpression.getLimitClause();
                limitClause.accept(this, arg);
                SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, limitClause, context);
                freeVariables.addAll(SqlppVariableUtil.getFreeVariables(limitClause));
            }
        }
        // Visits the select clause.
        SelectClause selectClause = selectBlock.getSelectClause();
        selectClause.accept(this, arg);
        // Rewrites the select clause.
        SqlppRewriteUtil.rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, selectClause, context);
        freeVariables.addAll(SqlppVariableUtil.getFreeVariables(selectClause));
        freeVariables.removeAll(visibleVarsInCurrentScope);
        // Gets the final free variables.
        freeVariables.addAll(freeVariablesInGbyLets);
        // Gets outer scope variables.
        Collection<VariableExpr> decorVars = SqlppVariableUtil.getLiveVariables(scopeChecker.getCurrentScope(), true);
        decorVars.removeAll(visibleVarsInCurrentScope);
        // Need path resolution or not?
        boolean needResolution = !decorVars.containsAll(freeVariables);
        // Otherwise, we only need to retain used free variables.
        if (needResolution) {
            // Tracks used variables, including WITH variables.
            decorVars.retainAll(freeVariables);
            // Adds all non-WITH outer scope variables, for path resolution.
            Collection<VariableExpr> visibleOuterScopeNonWithVars = SqlppVariableUtil.getLiveVariables(scopeChecker.getCurrentScope(), false);
            visibleOuterScopeNonWithVars.removeAll(visibleVarsInCurrentScope);
            decorVars.addAll(visibleOuterScopeNonWithVars);
        } else {
            // Only retains used free variables.
            decorVars.retainAll(freeVariables);
        }
        if (!decorVars.isEmpty()) {
            // Adds used WITH variables.
            Collection<VariableExpr> visibleOuterScopeNonWithVars = SqlppVariableUtil.getLiveVariables(scopeChecker.getCurrentScope(), false);
            visibleOuterScopeNonWithVars.retainAll(freeVariables);
            decorVars.addAll(visibleOuterScopeNonWithVars);
            // Adds necessary decoration variables for the GROUP BY.
            // NOTE: we need to include WITH binding variables so as they can be evaluated before
            // the GROUP BY instead of being inlined as part of nested pipepline. The current optimzier
            // is not able to optimize the latter case. The following query is such an example:
            // asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-11
            List<GbyVariableExpressionPair> decorList = new ArrayList<>();
            for (VariableExpr var : decorVars) {
                decorList.add(new GbyVariableExpressionPair((VariableExpr) SqlppRewriteUtil.deepCopy(var), (Expression) SqlppRewriteUtil.deepCopy(var)));
            }
            groupbyClause.getDecorPairList().addAll(decorList);
        }
    } else {
        selectBlock.getSelectClause().accept(this, arg);
    }
    return null;
}
Also used : LimitClause(org.apache.asterix.lang.common.clause.LimitClause) SelectClause(org.apache.asterix.lang.sqlpp.clause.SelectClause) LetClause(org.apache.asterix.lang.common.clause.LetClause) ArrayList(java.util.ArrayList) SelectExpression(org.apache.asterix.lang.sqlpp.expression.SelectExpression) GroupbyClause(org.apache.asterix.lang.common.clause.GroupbyClause) FromClause(org.apache.asterix.lang.sqlpp.clause.FromClause) HavingClause(org.apache.asterix.lang.sqlpp.clause.HavingClause) ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) Expression(org.apache.asterix.lang.common.base.Expression) SelectExpression(org.apache.asterix.lang.sqlpp.expression.SelectExpression) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) OrderbyClause(org.apache.asterix.lang.common.clause.OrderbyClause) VariableExpr(org.apache.asterix.lang.common.expression.VariableExpr) HashSet(java.util.HashSet)

Example 7 with GbyVariableExpressionPair

use of org.apache.asterix.lang.common.expression.GbyVariableExpressionPair in project asterixdb by apache.

the class SubstituteGroupbyExpressionVisitor method visit.

@Override
public Expression visit(SelectBlock selectBlock, ILangExpression arg) throws CompilationException {
    if (selectBlock.hasGroupbyClause()) {
        Map<Expression, Expression> map = new HashMap<>();
        for (GbyVariableExpressionPair gbyKeyPair : selectBlock.getGroupbyClause().getGbyPairList()) {
            Expression gbyKeyExpr = gbyKeyPair.getExpr();
            if (gbyKeyExpr.getKind() != Kind.VARIABLE_EXPRESSION) {
                map.put(gbyKeyExpr, gbyKeyPair.getVar());
            }
        }
        // Creates a substitution visitor.
        SubstituteGroupbyExpressionVisitor visitor = new SubstituteGroupbyExpressionVisitor(context, map);
        // Rewrites LET/HAVING/SELECT clauses.
        if (selectBlock.hasLetClausesAfterGroupby()) {
            for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
                letClause.accept(this, arg);
            }
        }
        if (selectBlock.hasHavingClause()) {
            selectBlock.getHavingClause().accept(visitor, arg);
        }
        selectBlock.getSelectClause().accept(visitor, arg);
        SelectExpression selectExpression = (SelectExpression) arg;
        // For SET operation queries, the GROUP BY key variables will not substitute ORDER BY nor LIMIT expressions.
        if (!selectExpression.getSelectSetOperation().hasRightInputs()) {
            if (selectExpression.hasOrderby()) {
                selectExpression.getOrderbyClause().accept(visitor, arg);
            }
            if (selectExpression.hasLimit()) {
                selectExpression.getLimitClause().accept(visitor, arg);
            }
        }
    }
    return super.visit(selectBlock, arg);
}
Also used : LetClause(org.apache.asterix.lang.common.clause.LetClause) HashMap(java.util.HashMap) Expression(org.apache.asterix.lang.common.base.Expression) ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) SelectExpression(org.apache.asterix.lang.sqlpp.expression.SelectExpression) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) SelectExpression(org.apache.asterix.lang.sqlpp.expression.SelectExpression)

Example 8 with GbyVariableExpressionPair

use of org.apache.asterix.lang.common.expression.GbyVariableExpressionPair in project asterixdb by apache.

the class SqlppVariableUtil method getBindingVariables.

public static Collection<VariableExpr> getBindingVariables(GroupbyClause gbyClause) {
    List<VariableExpr> bindingVars = new ArrayList<>();
    if (gbyClause == null) {
        return bindingVars;
    }
    for (GbyVariableExpressionPair gbyKey : gbyClause.getGbyPairList()) {
        VariableExpr var = gbyKey.getVar();
        if (var != null) {
            bindingVars.add(var);
        }
    }
    for (GbyVariableExpressionPair gbyKey : gbyClause.getDecorPairList()) {
        VariableExpr var = gbyKey.getVar();
        if (var != null) {
            bindingVars.add(var);
        }
    }
    if (gbyClause.hasWithMap()) {
        bindingVars.addAll(gbyClause.getWithVarMap().values());
    }
    bindingVars.add(gbyClause.getGroupVar());
    return bindingVars;
}
Also used : GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) ArrayList(java.util.ArrayList) VariableExpr(org.apache.asterix.lang.common.expression.VariableExpr)

Example 9 with GbyVariableExpressionPair

use of org.apache.asterix.lang.common.expression.GbyVariableExpressionPair in project asterixdb by apache.

the class QueryPrintVisitor method visit.

@Override
public Void visit(GroupbyClause gc, Integer step) throws CompilationException {
    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);
    }
    if (gc.hasDecorList()) {
        out.println(skip(step + 1) + "Decor");
        for (GbyVariableExpressionPair pair : gc.getDecorPairList()) {
            if (pair.getVar() != null) {
                pair.getVar().accept(this, step + 1);
                out.println(skip(step + 1) + ":=");
            }
            pair.getExpr().accept(this, step + 1);
        }
    }
    if (gc.hasWithMap()) {
        out.println(skip(step + 1) + "With");
        for (Entry<Expression, VariableExpr> entry : gc.getWithVarMap().entrySet()) {
            Expression key = entry.getKey();
            VariableExpr value = entry.getValue();
            key.accept(this, step + 1);
            if (!key.equals(value)) {
                out.println(skip(step + 1) + "AS");
                value.accept(this, step + 1);
            }
        }
    }
    out.println();
    return null;
}
Also used : TypeReferenceExpression(org.apache.asterix.lang.common.expression.TypeReferenceExpression) TypeExpression(org.apache.asterix.lang.common.expression.TypeExpression) QuantifiedExpression(org.apache.asterix.lang.common.expression.QuantifiedExpression) Expression(org.apache.asterix.lang.common.base.Expression) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) VariableExpr(org.apache.asterix.lang.common.expression.VariableExpr)

Example 10 with GbyVariableExpressionPair

use of org.apache.asterix.lang.common.expression.GbyVariableExpressionPair in project asterixdb by apache.

the class LangExpressionToPlanTranslator method visit.

@Override
public Pair<ILogicalOperator, LogicalVariable> visit(GroupbyClause gc, Mutable<ILogicalOperator> tupSource) throws CompilationException {
    Mutable<ILogicalOperator> topOp = tupSource;
    if (gc.hasGroupVar()) {
        List<Pair<Expression, Identifier>> groupFieldList = gc.getGroupFieldList();
        List<Mutable<ILogicalExpression>> groupRecordConstructorArgList = new ArrayList<>();
        for (Pair<Expression, Identifier> groupField : groupFieldList) {
            ILogicalExpression groupFieldNameExpr = langExprToAlgExpression(new LiteralExpr(new StringLiteral(groupField.second.getValue())), topOp).first;
            groupRecordConstructorArgList.add(new MutableObject<>(groupFieldNameExpr));
            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);
    }
    GroupByOperator gOp = new GroupByOperator();
    for (GbyVariableExpressionPair ve : gc.getGbyPairList()) {
        VariableExpr vexpr = ve.getVar();
        LogicalVariable v = vexpr == null ? context.newVar() : context.newVarFromExpression(vexpr);
        Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(ve.getExpr(), topOp);
        gOp.addGbyExpression(v, eo.first);
        topOp = eo.second;
    }
    for (GbyVariableExpressionPair ve : gc.getDecorPairList()) {
        VariableExpr vexpr = ve.getVar();
        LogicalVariable v = vexpr == null ? context.newVar() : context.newVarFromExpression(vexpr);
        Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(ve.getExpr(), topOp);
        gOp.addDecorExpression(v, eo.first);
        topOp = eo.second;
    }
    gOp.getInputs().add(topOp);
    for (Entry<Expression, VariableExpr> entry : gc.getWithVarMap().entrySet()) {
        Pair<ILogicalExpression, Mutable<ILogicalOperator>> listifyInput = langExprToAlgExpression(entry.getKey(), 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.setGroupAll(gc.isGroupAll());
    gOp.getAnnotations().put(OperatorAnnotations.USE_HASH_GROUP_BY, gc.hasHashGroupByHint());
    return new Pair<>(gOp, null);
}
Also used : NestedTupleSourceOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator) ArrayList(java.util.ArrayList) Identifier(org.apache.asterix.lang.common.struct.Identifier) FunctionIdentifier(org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier) ALogicalPlanImpl(org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator) LiteralExpr(org.apache.asterix.lang.common.expression.LiteralExpr) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) Pair(org.apache.hyracks.algebricks.common.utils.Pair) QuantifiedPair(org.apache.asterix.lang.common.struct.QuantifiedPair) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression) MutableObject(org.apache.commons.lang3.mutable.MutableObject) LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AggregateFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression) GroupByOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) StringLiteral(org.apache.asterix.lang.common.literal.StringLiteral) ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) AggregateFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression) Expression(org.apache.asterix.lang.common.base.Expression) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) QuantifiedExpression(org.apache.asterix.lang.common.expression.QuantifiedExpression) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression) ConstantExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) UnnestingFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) ILogicalPlan(org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan) VariableExpr(org.apache.asterix.lang.common.expression.VariableExpr)

Aggregations

GbyVariableExpressionPair (org.apache.asterix.lang.common.expression.GbyVariableExpressionPair)16 Expression (org.apache.asterix.lang.common.base.Expression)9 VariableExpr (org.apache.asterix.lang.common.expression.VariableExpr)9 ILangExpression (org.apache.asterix.lang.common.base.ILangExpression)8 ArrayList (java.util.ArrayList)7 QuantifiedExpression (org.apache.asterix.lang.common.expression.QuantifiedExpression)6 Identifier (org.apache.asterix.lang.common.struct.Identifier)5 SelectExpression (org.apache.asterix.lang.sqlpp.expression.SelectExpression)5 HashMap (java.util.HashMap)4 GroupbyClause (org.apache.asterix.lang.common.clause.GroupbyClause)4 QuantifiedPair (org.apache.asterix.lang.common.struct.QuantifiedPair)3 VarIdentifier (org.apache.asterix.lang.common.struct.VarIdentifier)3 Pair (org.apache.hyracks.algebricks.common.utils.Pair)3 LetClause (org.apache.asterix.lang.common.clause.LetClause)2 VariableSubstitutionEnvironment (org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment)2 SelectClause (org.apache.asterix.lang.sqlpp.clause.SelectClause)2 CaseExpression (org.apache.asterix.lang.sqlpp.expression.CaseExpression)2 FunctionIdentifier (org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier)2 HashSet (java.util.HashSet)1 LinkedList (java.util.LinkedList)1