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;
}
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;
}
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;
}
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);
}
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);
}
Aggregations