Search in sources :

Example 1 with LimitOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator in project asterixdb by apache.

the class CopyLimitDownRule method rewritePre.

@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.LIMIT) {
        return false;
    }
    LimitOperator limitOp = (LimitOperator) op;
    if (!limitOp.isTopmostLimitOp()) {
        return false;
    }
    List<LogicalVariable> limitUsedVars = new ArrayList<>();
    VariableUtilities.getUsedVariables(limitOp, limitUsedVars);
    Mutable<ILogicalOperator> safeOpRef = null;
    Mutable<ILogicalOperator> candidateOpRef = limitOp.getInputs().get(0);
    List<LogicalVariable> candidateProducedVars = new ArrayList<>();
    while (true) {
        candidateProducedVars.clear();
        ILogicalOperator candidateOp = candidateOpRef.getValue();
        LogicalOperatorTag candidateOpTag = candidateOp.getOperatorTag();
        if (candidateOp.getInputs().size() > 1 || !candidateOp.isMap() || candidateOpTag == LogicalOperatorTag.SELECT || candidateOpTag == LogicalOperatorTag.LIMIT || candidateOpTag == LogicalOperatorTag.UNNEST_MAP || !OperatorPropertiesUtil.disjoint(limitUsedVars, candidateProducedVars)) {
            break;
        }
        safeOpRef = candidateOpRef;
        candidateOpRef = safeOpRef.getValue().getInputs().get(0);
    }
    if (safeOpRef != null) {
        ILogicalOperator safeOp = safeOpRef.getValue();
        Mutable<ILogicalOperator> unsafeOpRef = safeOp.getInputs().get(0);
        ILogicalOperator unsafeOp = unsafeOpRef.getValue();
        LimitOperator limitCloneOp = null;
        if (limitOp.getOffset().getValue() == null) {
            limitCloneOp = new LimitOperator(limitOp.getMaxObjects().getValue(), false);
        } else {
            // Need to add an offset to the given limit value
            // since the original topmost limit will use the offset value.
            // We can't apply the offset multiple times.
            IFunctionInfo finfoAdd = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.NUMERIC_ADD);
            List<Mutable<ILogicalExpression>> addArgs = new ArrayList<>();
            addArgs.add(new MutableObject<ILogicalExpression>(limitOp.getMaxObjects().getValue().cloneExpression()));
            addArgs.add(new MutableObject<ILogicalExpression>(limitOp.getOffset().getValue().cloneExpression()));
            ScalarFunctionCallExpression maxPlusOffset = new ScalarFunctionCallExpression(finfoAdd, addArgs);
            limitCloneOp = new LimitOperator(maxPlusOffset, false);
        }
        limitCloneOp.setPhysicalOperator(new StreamLimitPOperator());
        limitCloneOp.getInputs().add(new MutableObject<ILogicalOperator>(unsafeOp));
        limitCloneOp.setExecutionMode(unsafeOp.getExecutionMode());
        OperatorPropertiesUtil.computeSchemaRecIfNull((AbstractLogicalOperator) unsafeOp);
        limitCloneOp.recomputeSchema();
        unsafeOpRef.setValue(limitCloneOp);
        context.computeAndSetTypeEnvironmentForOperator(limitCloneOp);
        context.addToDontApplySet(this, limitOp);
    }
    return safeOpRef != null;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) IFunctionInfo(org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) LimitOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator) LogicalOperatorTag(org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag) StreamLimitPOperator(org.apache.hyracks.algebricks.core.algebra.operators.physical.StreamLimitPOperator) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)

Example 2 with LimitOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator in project asterixdb by apache.

the class PushLimitIntoOrderByRule method pushLimitIntoOrder.

/**
     * Generate new ORDER operator that uses TopKSort module and replaces the old ORDER operator.
     */
private boolean pushLimitIntoOrder(Mutable<ILogicalOperator> opRef, Mutable<ILogicalOperator> opRef2, IOptimizationContext context) throws AlgebricksException {
    PhysicalOptimizationConfig physicalOptimizationConfig = context.getPhysicalOptimizationConfig();
    LimitOperator limitOp = (LimitOperator) opRef.getValue();
    OrderOperator orderOp = (OrderOperator) opRef2.getValue();
    long topK = -1;
    // We don't push-down LIMIT into in-memory sort.
    if (orderOp.getPhysicalOperator().getOperatorTag() != PhysicalOperatorTag.STABLE_SORT) {
        return false;
    }
    // Get the LIMIT constant
    if (limitOp.getMaxObjects().getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT) {
        // Currently, we support LIMIT with a constant value.
        topK = AccessMethodUtils.getInt64Constant(limitOp.getMaxObjects());
        // since the original external sort's performance might be better.
        if (topK > Integer.MAX_VALUE) {
            return false;
        }
        if (topK < 0) {
            topK = 0;
        }
    } else {
        return false;
    }
    // Final topK will be applied through LIMIT.
    if (limitOp.getOffset().getValue() != null) {
        if (limitOp.getOffset().getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT) {
            long offset = AccessMethodUtils.getInt64Constant(limitOp.getOffset());
            if (offset < 0) {
                offset = 0;
            }
            // Check the overflow case.
            if (offset >= Integer.MAX_VALUE - topK) {
                return false;
            }
            topK += offset;
        } else {
            return false;
        }
    }
    // Create the new ORDER operator, set the topK value, and replace the current one.
    OrderOperator newOrderOp = new OrderOperator(orderOp.getOrderExpressions(), (int) topK);
    newOrderOp.setPhysicalOperator(new StableSortPOperator(physicalOptimizationConfig.getMaxFramesExternalSort(), newOrderOp.getTopK()));
    newOrderOp.getInputs().addAll(orderOp.getInputs());
    newOrderOp.setExecutionMode(orderOp.getExecutionMode());
    newOrderOp.recomputeSchema();
    newOrderOp.computeDeliveredPhysicalProperties(context);
    opRef2.setValue(newOrderOp);
    context.computeAndSetTypeEnvironmentForOperator(newOrderOp);
    context.addToDontApplySet(this, limitOp);
    return true;
}
Also used : LimitOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator) OrderOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator) PhysicalOptimizationConfig(org.apache.hyracks.algebricks.core.rewriter.base.PhysicalOptimizationConfig) StableSortPOperator(org.apache.hyracks.algebricks.core.algebra.operators.physical.StableSortPOperator)

Example 3 with LimitOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator in project asterixdb by apache.

the class IsomorphismOperatorVisitor method visitLimitOperator.

@Override
public Boolean visitLimitOperator(LimitOperator op, ILogicalOperator arg) throws AlgebricksException {
    AbstractLogicalOperator aop = (AbstractLogicalOperator) arg;
    if (aop.getOperatorTag() != LogicalOperatorTag.LIMIT) {
        return Boolean.FALSE;
    }
    LimitOperator limitOpArg = (LimitOperator) copyAndSubstituteVar(op, arg);
    if (op.getOffset() != limitOpArg.getOffset()) {
        return Boolean.FALSE;
    }
    boolean isomorphic = op.getMaxObjects().getValue().equals(limitOpArg.getMaxObjects().getValue());
    return isomorphic;
}
Also used : AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) LimitOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator)

Example 4 with LimitOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator in project asterixdb by apache.

the class LangExpressionToPlanTranslator method visit.

@Override
public Pair<ILogicalOperator, LogicalVariable> visit(LimitClause lc, Mutable<ILogicalOperator> tupSource) throws CompilationException {
    Pair<ILogicalExpression, Mutable<ILogicalOperator>> p1 = langExprToAlgExpression(lc.getLimitExpr(), tupSource);
    LimitOperator opLim;
    Expression offset = lc.getOffset();
    if (offset != null) {
        Pair<ILogicalExpression, Mutable<ILogicalOperator>> p2 = langExprToAlgExpression(offset, p1.second);
        opLim = new LimitOperator(p1.first, p2.first);
        opLim.getInputs().add(p2.second);
    } else {
        opLim = new LimitOperator(p1.first);
        opLim.getInputs().add(p1.second);
    }
    return new Pair<>(opLim, null);
}
Also used : Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) 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) LimitOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) Pair(org.apache.hyracks.algebricks.common.utils.Pair) QuantifiedPair(org.apache.asterix.lang.common.struct.QuantifiedPair)

Example 5 with LimitOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator in project asterixdb by apache.

the class StreamLimitPOperator method contributeRuntimeOperator.

@Override
public void contributeRuntimeOperator(IHyracksJobBuilder builder, JobGenContext context, ILogicalOperator op, IOperatorSchema propagatedSchema, IOperatorSchema[] inputSchemas, IOperatorSchema outerPlanSchema) throws AlgebricksException {
    LimitOperator limit = (LimitOperator) op;
    IExpressionRuntimeProvider expressionRuntimeProvider = context.getExpressionRuntimeProvider();
    IVariableTypeEnvironment env = context.getTypeEnvironment(op);
    IScalarEvaluatorFactory maxObjectsFact = expressionRuntimeProvider.createEvaluatorFactory(limit.getMaxObjects().getValue(), env, inputSchemas, context);
    ILogicalExpression offsetExpr = limit.getOffset().getValue();
    IScalarEvaluatorFactory offsetFact = (offsetExpr == null) ? null : expressionRuntimeProvider.createEvaluatorFactory(offsetExpr, env, inputSchemas, context);
    RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(context.getTypeEnvironment(op), propagatedSchema, context);
    StreamLimitRuntimeFactory runtime = new StreamLimitRuntimeFactory(maxObjectsFact, offsetFact, null, context.getBinaryIntegerInspectorFactory());
    builder.contributeMicroOperator(limit, runtime, recDesc);
    // and contribute one edge from its child
    ILogicalOperator src = limit.getInputs().get(0).getValue();
    builder.contributeGraphEdge(src, 0, limit, 0);
}
Also used : IExpressionRuntimeProvider(org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionRuntimeProvider) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) LimitOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator) RecordDescriptor(org.apache.hyracks.api.dataflow.value.RecordDescriptor) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) IVariableTypeEnvironment(org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment) IScalarEvaluatorFactory(org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory) StreamLimitRuntimeFactory(org.apache.hyracks.algebricks.runtime.operators.std.StreamLimitRuntimeFactory)

Aggregations

LimitOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator)6 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)3 Mutable (org.apache.commons.lang3.mutable.Mutable)2 ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)2 ScalarFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)2 AbstractLogicalOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)2 ArrayList (java.util.ArrayList)1 Expression (org.apache.asterix.lang.common.base.Expression)1 ILangExpression (org.apache.asterix.lang.common.base.ILangExpression)1 GbyVariableExpressionPair (org.apache.asterix.lang.common.expression.GbyVariableExpressionPair)1 QuantifiedExpression (org.apache.asterix.lang.common.expression.QuantifiedExpression)1 QuantifiedPair (org.apache.asterix.lang.common.struct.QuantifiedPair)1 Pair (org.apache.hyracks.algebricks.common.utils.Pair)1 LogicalOperatorTag (org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag)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 ConstantExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression)1 IExpressionRuntimeProvider (org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionRuntimeProvider)1 IVariableTypeEnvironment (org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment)1