Search in sources :

Example 1 with CaseExpression

use of org.apache.asterix.lang.sqlpp.expression.CaseExpression in project asterixdb by apache.

the class SqlppExpressionToPlanTranslator method visit.

@Override
public Pair<ILogicalOperator, LogicalVariable> visit(CaseExpression caseExpression, Mutable<ILogicalOperator> tupSource) throws CompilationException {
    //Creates a series of subplan operators, one for each branch.
    Mutable<ILogicalOperator> currentOpRef = tupSource;
    ILogicalOperator currentOperator = null;
    List<Expression> whenExprList = caseExpression.getWhenExprs();
    List<Expression> thenExprList = caseExpression.getThenExprs();
    List<ILogicalExpression> branchCondVarReferences = new ArrayList<>();
    List<ILogicalExpression> allVarReferences = new ArrayList<>();
    for (int index = 0; index < whenExprList.size(); ++index) {
        Pair<ILogicalOperator, LogicalVariable> whenExprResult = whenExprList.get(index).accept(this, currentOpRef);
        currentOperator = whenExprResult.first;
        // Variable whenConditionVar is corresponds to the current "WHEN" condition.
        LogicalVariable whenConditionVar = whenExprResult.second;
        Mutable<ILogicalExpression> branchEntraceConditionExprRef = new MutableObject<>(new VariableReferenceExpression(whenConditionVar));
        // even though multiple "WHEN" conditions can be satisfied.
        if (!branchCondVarReferences.isEmpty()) {
            // The additional filter generated here makes sure the the tuple has not
            // entered other matched "WHEN...THEN" case.
            List<Mutable<ILogicalExpression>> andArgs = new ArrayList<>();
            andArgs.add(generateNoMatchedPrecedingWhenBranchesFilter(branchCondVarReferences));
            andArgs.add(branchEntraceConditionExprRef);
            // A "THEN" branch can be entered only when the tuple has not enter any other preceding
            // branches and the current "WHEN" condition is TRUE.
            branchEntraceConditionExprRef = new MutableObject<>(new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.AND), andArgs));
        }
        // Translates the corresponding "THEN" expression.
        Pair<ILogicalOperator, LogicalVariable> opAndVarForThen = constructSubplanOperatorForBranch(currentOperator, branchEntraceConditionExprRef, thenExprList.get(index));
        branchCondVarReferences.add(new VariableReferenceExpression(whenConditionVar));
        allVarReferences.add(new VariableReferenceExpression(whenConditionVar));
        allVarReferences.add(new VariableReferenceExpression(opAndVarForThen.second));
        currentOperator = opAndVarForThen.first;
        currentOpRef = new MutableObject<>(currentOperator);
    }
    // Creates a subplan for the "ELSE" branch.
    Mutable<ILogicalExpression> elseCondExprRef = generateNoMatchedPrecedingWhenBranchesFilter(branchCondVarReferences);
    Pair<ILogicalOperator, LogicalVariable> opAndVarForElse = constructSubplanOperatorForBranch(currentOperator, elseCondExprRef, caseExpression.getElseExpr());
    // Uses switch-case function to select the results of two branches.
    LogicalVariable selectVar = context.newVar();
    List<Mutable<ILogicalExpression>> arguments = new ArrayList<>();
    arguments.add(new MutableObject<>(new ConstantExpression(new AsterixConstantValue(ABoolean.TRUE))));
    for (ILogicalExpression argVar : allVarReferences) {
        arguments.add(new MutableObject<>(argVar));
    }
    arguments.add(new MutableObject<>(new VariableReferenceExpression(opAndVarForElse.second)));
    AbstractFunctionCallExpression swithCaseExpr = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.SWITCH_CASE), arguments);
    AssignOperator assignOp = new AssignOperator(selectVar, new MutableObject<>(swithCaseExpr));
    assignOp.getInputs().add(new MutableObject<>(opAndVarForElse.first));
    // Unnests the selected (a "THEN" or "ELSE" branch) result.
    LogicalVariable unnestVar = context.newVar();
    UnnestOperator unnestOp = new UnnestOperator(unnestVar, new MutableObject<>(new UnnestingFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.SCAN_COLLECTION), Collections.singletonList(new MutableObject<>(new VariableReferenceExpression(selectVar))))));
    unnestOp.getInputs().add(new MutableObject<>(assignOp));
    // Produces the final assign operator.
    LogicalVariable resultVar = context.newVar();
    AssignOperator finalAssignOp = new AssignOperator(resultVar, new MutableObject<>(new VariableReferenceExpression(unnestVar)));
    finalAssignOp.getInputs().add(new MutableObject<>(unnestOp));
    return new Pair<>(finalAssignOp, resultVar);
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) UnnestingFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ConstantExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) Mutable(org.apache.commons.lang3.mutable.Mutable) LeftOuterUnnestOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestOperator) UnnestOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AsterixConstantValue(org.apache.asterix.om.constants.AsterixConstantValue) 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) SelectExpression(org.apache.asterix.lang.sqlpp.expression.SelectExpression) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression) UnnestingFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression) ConstantExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) MutableObject(org.apache.commons.lang3.mutable.MutableObject) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) Pair(org.apache.hyracks.algebricks.common.utils.Pair)

Example 2 with CaseExpression

use of org.apache.asterix.lang.sqlpp.expression.CaseExpression in project asterixdb by apache.

the class DeepCopyVisitor method visit.

@Override
public ILangExpression visit(CaseExpression caseExpr, Void arg) throws CompilationException {
    Expression conditionExpr = (Expression) caseExpr.getConditionExpr().accept(this, arg);
    List<Expression> whenExprList = copyExprList(caseExpr.getWhenExprs(), arg);
    List<Expression> thenExprList = copyExprList(caseExpr.getThenExprs(), arg);
    Expression elseExpr = (Expression) caseExpr.getElseExpr().accept(this, arg);
    return new CaseExpression(conditionExpr, whenExprList, thenExprList, elseExpr);
}
Also used : ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) Expression(org.apache.asterix.lang.common.base.Expression) SelectExpression(org.apache.asterix.lang.sqlpp.expression.SelectExpression) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression) QuantifiedExpression(org.apache.asterix.lang.common.expression.QuantifiedExpression) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression)

Example 3 with CaseExpression

use of org.apache.asterix.lang.sqlpp.expression.CaseExpression in project asterixdb by apache.

the class SqlppBuiltinFunctionRewriteVisitor method normalizeCaseExpr.

// Normalizes WHEN expressions so that it can have correct NULL/MISSING semantics as well
// as type promotion semantics.
private CaseExpression normalizeCaseExpr(CaseExpression caseExpr) throws CompilationException {
    LiteralExpr trueLiteral = new LiteralExpr(TrueLiteral.INSTANCE);
    Expression conditionExpr = caseExpr.getConditionExpr();
    if (trueLiteral.equals(conditionExpr)) {
        return caseExpr;
    }
    List<Expression> normalizedWhenExprs = new ArrayList<>();
    for (Expression expr : caseExpr.getWhenExprs()) {
        OperatorExpr operatorExpr = new OperatorExpr();
        operatorExpr.addOperand((Expression) SqlppRewriteUtil.deepCopy(expr));
        operatorExpr.addOperand(caseExpr.getConditionExpr());
        operatorExpr.addOperator("=");
        normalizedWhenExprs.add(operatorExpr);
    }
    return new CaseExpression(trueLiteral, normalizedWhenExprs, caseExpr.getThenExprs(), caseExpr.getElseExpr());
}
Also used : OperatorExpr(org.apache.asterix.lang.common.expression.OperatorExpr) Expression(org.apache.asterix.lang.common.base.Expression) ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression) ArrayList(java.util.ArrayList) LiteralExpr(org.apache.asterix.lang.common.expression.LiteralExpr) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression)

Example 4 with CaseExpression

use of org.apache.asterix.lang.sqlpp.expression.CaseExpression in project asterixdb by apache.

the class SqlppBuiltinFunctionRewriteVisitor method visit.

@Override
public Expression visit(CaseExpression caseExpr, ILangExpression arg) throws CompilationException {
    // Visits it as usual first.
    Expression expr = super.visit(caseExpr, arg);
    if (expr != caseExpr) {
        return expr.accept(this, arg);
    }
    CaseExpression newCaseExpr = normalizeCaseExpr(caseExpr);
    if (SqlppRewriteUtil.constainsSubquery(newCaseExpr)) {
        // If the CASE expression contains a subquery, we do not rewrite it to a switch-case function call.
        return newCaseExpr;
    }
    // If the CASE expression does not contain a subquery, we rewrite it to a switch-case function call.
    FunctionSignature functionSignature = new FunctionSignature(MetadataConstants.METADATA_DATAVERSE_NAME, "switch-case", FunctionIdentifier.VARARGS);
    List<Expression> whenExprList = newCaseExpr.getWhenExprs();
    List<Expression> thenExprList = newCaseExpr.getThenExprs();
    List<Expression> newExprList = new ArrayList<>();
    newExprList.add(newCaseExpr.getConditionExpr());
    for (int index = 0; index < whenExprList.size(); ++index) {
        newExprList.add(whenExprList.get(index));
        newExprList.add(thenExprList.get(index));
    }
    newExprList.add(newCaseExpr.getElseExpr());
    return new CallExpr(functionSignature, newExprList);
}
Also used : Expression(org.apache.asterix.lang.common.base.Expression) ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression) ArrayList(java.util.ArrayList) CallExpr(org.apache.asterix.lang.common.expression.CallExpr) FunctionSignature(org.apache.asterix.common.functions.FunctionSignature) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression)

Example 5 with CaseExpression

use of org.apache.asterix.lang.sqlpp.expression.CaseExpression in project asterixdb by apache.

the class SqlppCloneAndSubstituteVariablesVisitor method visit.

@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(CaseExpression caseExpr, VariableSubstitutionEnvironment env) throws CompilationException {
    Expression conditionExpr = (Expression) caseExpr.getConditionExpr().accept(this, env).first;
    List<Expression> whenExprList = VariableCloneAndSubstitutionUtil.visitAndCloneExprList(caseExpr.getWhenExprs(), env, this);
    List<Expression> thenExprList = VariableCloneAndSubstitutionUtil.visitAndCloneExprList(caseExpr.getThenExprs(), env, this);
    Expression elseExpr = (Expression) caseExpr.getElseExpr().accept(this, env).first;
    CaseExpression newCaseExpr = new CaseExpression(conditionExpr, whenExprList, thenExprList, elseExpr);
    return new Pair<>(newCaseExpr, env);
}
Also used : ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression) Expression(org.apache.asterix.lang.common.base.Expression) SelectExpression(org.apache.asterix.lang.sqlpp.expression.SelectExpression) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression) Pair(org.apache.hyracks.algebricks.common.utils.Pair)

Aggregations

Expression (org.apache.asterix.lang.common.base.Expression)5 ILangExpression (org.apache.asterix.lang.common.base.ILangExpression)5 CaseExpression (org.apache.asterix.lang.sqlpp.expression.CaseExpression)5 ArrayList (java.util.ArrayList)3 SelectExpression (org.apache.asterix.lang.sqlpp.expression.SelectExpression)3 Pair (org.apache.hyracks.algebricks.common.utils.Pair)2 FunctionSignature (org.apache.asterix.common.functions.FunctionSignature)1 CallExpr (org.apache.asterix.lang.common.expression.CallExpr)1 GbyVariableExpressionPair (org.apache.asterix.lang.common.expression.GbyVariableExpressionPair)1 LiteralExpr (org.apache.asterix.lang.common.expression.LiteralExpr)1 OperatorExpr (org.apache.asterix.lang.common.expression.OperatorExpr)1 QuantifiedExpression (org.apache.asterix.lang.common.expression.QuantifiedExpression)1 AsterixConstantValue (org.apache.asterix.om.constants.AsterixConstantValue)1 Mutable (org.apache.commons.lang3.mutable.Mutable)1 MutableObject (org.apache.commons.lang3.mutable.MutableObject)1 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)1 ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)1 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)1 AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)1 AggregateFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression)1