@Override public ILogicalOperator visitLimitOperator(LimitOperator op, Void arg) throws AlgebricksException { return new LimitOperator(deepCopyExpressionRef(op.getMaxObjects()).getValue(), deepCopyExpressionRef(op.getOffset()).getValue(), op.isTopmostLimitOp()); }
@Override public IVariableTypeEnvironment computeOutputTypeEnvironment(ITypingContext ctx) throws AlgebricksException { return createPropagatingAllInputsTypeEnvironment(ctx); } }
@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 (!Objects.equals(op.getOffset().getValue(), limitOpArg.getOffset().getValue())) { return Boolean.FALSE; } boolean isomorphic = op.getMaxObjects().getValue().equals(limitOpArg.getMaxObjects().getValue()); return isomorphic; }
if (!limitOp.isTopmostLimitOp()) { return false; Mutable<ILogicalOperator> candidateOpRef = limitOp.getInputs().get(0); Mutable<ILogicalOperator> unsafeOpRef = safeOp.getInputs().get(0); ILogicalOperator unsafeOp = unsafeOpRef.getValue(); SourceLocation sourceLoc = limitOp.getSourceLocation(); LimitOperator limitCloneOp = null; if (limitOp.getOffset().getValue() == null) { limitCloneOp = new LimitOperator(limitOp.getMaxObjects().getValue(), false); limitCloneOp.setSourceLocation(sourceLoc); } else { 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); maxPlusOffset.setSourceLocation(sourceLoc); limitCloneOp = new LimitOperator(maxPlusOffset, false); limitCloneOp.setSourceLocation(sourceLoc); limitCloneOp.setPhysicalOperator(new StreamLimitPOperator()); limitCloneOp.getInputs().add(new MutableObject<ILogicalOperator>(unsafeOp)); limitCloneOp.setExecutionMode(unsafeOp.getExecutionMode()); OperatorPropertiesUtil.computeSchemaRecIfNull((AbstractLogicalOperator) unsafeOp); limitCloneOp.recomputeSchema(); unsafeOpRef.setValue(limitCloneOp);
@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()); runtime.setSourceLocation(limit.getSourceLocation()); 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); }
@Override public Pair<ILogicalOperator, LogicalVariable> visit(LimitClause lc, Mutable<ILogicalOperator> tupSource) throws CompilationException { SourceLocation sourceLoc = lc.getSourceLocation(); LimitOperator opLim; Pair<ILogicalExpression, Mutable<ILogicalOperator>> p1 = langExprToAlgExpression(lc.getLimitExpr(), tupSource); ILogicalExpression maxObjectsExpr = createLimitOffsetValueExpression(p1.first, lc.getLimitExpr().getSourceLocation()); Expression offset = lc.getOffset(); if (offset != null) { Pair<ILogicalExpression, Mutable<ILogicalOperator>> p2 = langExprToAlgExpression(offset, p1.second); ILogicalExpression offsetExpr = createLimitOffsetValueExpression(p2.first, lc.getOffset().getSourceLocation()); opLim = new LimitOperator(maxObjectsExpr, offsetExpr); opLim.getInputs().add(p2.second); opLim.setSourceLocation(sourceLoc); } else { opLim = new LimitOperator(maxObjectsExpr); opLim.getInputs().add(p1.second); opLim.setSourceLocation(sourceLoc); } return new Pair<>(opLim, null); }
VariableUtilities.getSubplanLocalLiveVariables(op.getInputs().get(0).getValue(), inputLiveVars); createRecordConstructorAssignOp(inputLiveVars, op.getSourceLocation()); ILogicalOperator assignOp = assignOpAndRecordVar.first; LogicalVariable recordVar = assignOpAndRecordVar.second; ILogicalOperator inputOp = op.getInputs().get(0).getValue(); assignOp.getInputs().add(new MutableObject<>(inputOp)); createUnnestForAggregatedList(aggVar, op.getSourceLocation()); ILogicalOperator unnestOp = unnestOpAndUnnestVar.first; LogicalVariable unnestVar = unnestOpAndUnnestVar.second; createFieldAccessAssignOperator(unnestVar, inputLiveVars, op.getSourceLocation()); fieldAccessAssignOp.getInputs().add(new MutableObject<>(unnestOp));
if (op.getOperatorTag() == LogicalOperatorTag.LIMIT) { LimitOperator opLim = (LimitOperator) op; if (opLim.isTopmostLimitOp()) { opLim.setExecutionMode(AbstractLogicalOperator.ExecutionMode.UNPARTITIONED); forceUnpartitioned = true;
@Override public Long visitLimitOperator(LimitOperator op, Void arg) throws AlgebricksException { return adjustCardinalityForTupleReductionOperator(op.getInputs().get(0).getValue().accept(this, arg)); }
@Override public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext ctx) throws AlgebricksException { parents.remove(parents.size() - 1); AbstractLogicalOperator orderOp = (AbstractLogicalOperator) opRef.getValue(); if (orderOp.getOperatorTag() == LogicalOperatorTag.ORDER && !orderOp.getAnnotations().containsKey(OperatorAnnotations.USE_STATIC_RANGE)) { // disable when sort output is consumed by limit & running agg op (result should be unpartitioned for limit) AbstractLogicalOperator parent; for (int i = parents.size() - 1; i >= 0; i--) { parent = parents.get(i); if (parent.getOperatorTag() == LogicalOperatorTag.LIMIT && ((LimitOperator) parent).isTopmostLimitOp()) { orderOp.getAnnotations().put(OperatorAnnotations.USE_DYNAMIC_RANGE, Boolean.FALSE); return true; } if (parent.getOperatorTag() == LogicalOperatorTag.RUNNINGAGGREGATE) { orderOp.getAnnotations().put(OperatorAnnotations.USE_DYNAMIC_RANGE, Boolean.FALSE); return true; } } } return false; } }
@Override public String visitLimitOperator(LimitOperator op, Boolean showDetails) throws AlgebricksException { stringBuilder.setLength(0); stringBuilder.append("limit ").append(op.getMaxObjects().getValue().toString()); ILogicalExpression offset = op.getOffset().getValue(); if (offset != null) { stringBuilder.append(", ").append(offset.toString()); } appendSchema(op, showDetails); appendAnnotations(op, showDetails); appendPhysicalOperatorInfo(op, showDetails); return stringBuilder.toString(); }
@Override public ILogicalOperator visitLimitOperator(LimitOperator op, ILogicalOperator arg) throws AlgebricksException { LimitOperator opCopy = new LimitOperator(exprDeepCopyVisitor.deepCopy(op.getMaxObjects().getValue()), exprDeepCopyVisitor.deepCopy(op.getOffset().getValue()), op.isTopmostLimitOp()); deepCopyInputsAnnotationsAndExecutionMode(op, arg, opCopy); return opCopy; }
@Override public Void visitLimitOperator(LimitOperator op, Void arg) { op.getMaxObjects().getValue().getUsedVariables(usedVariables); ILogicalExpression offsetExpr = op.getOffset().getValue(); if (offsetExpr != null) { offsetExpr.getUsedVariables(usedVariables); } return null; }
@Override public Void visitLimitOperator(LimitOperator op, Integer indent) throws AlgebricksException { addIndent(indent).append("limit " + op.getMaxObjects().getValue().accept(exprVisitor, indent)); ILogicalExpression offset = op.getOffset().getValue(); if (offset != null) { buffer.append(", " + offset.accept(exprVisitor, indent)); } return null; }
@Override public Void visitLimitOperator(LimitOperator op, Pair<LogicalVariable, LogicalVariable> pair) throws AlgebricksException { op.getMaxObjects().getValue().substituteVar(pair.first, pair.second); ILogicalExpression offset = op.getOffset().getValue(); if (offset != null) { offset.substituteVar(pair.first, pair.second); } substVarTypes(op, pair); return null; }
@Override public Void visitLimitOperator(LimitOperator op, Integer indent) throws AlgebricksException { addIndent(indent).append("\"operator\": \"limit\",\n"); addIndent(indent).append("\"value\": \"" + op.getMaxObjects().getValue().accept(exprVisitor, indent) + "\""); ILogicalExpression offset = op.getOffset().getValue(); if (offset != null) { buffer.append(",\n"); addIndent(indent).append("\"offset\": \"" + offset.accept(exprVisitor, indent) + "\""); } return null; }
static Integer getOutputLimit(LimitOperator limitOp) { ILogicalExpression maxObjectsExpr = limitOp.getMaxObjects().getValue(); IAObject maxObjectsValue = ConstantExpressionUtil.getConstantIaObject(maxObjectsExpr, ATypeTag.INTEGER); if (maxObjectsValue == null) { ILogicalExpression offsetExpr = limitOp.getOffset().getValue(); if (offsetExpr != null) { IAObject offsetValue = ConstantExpressionUtil.getConstantIaObject(offsetExpr, ATypeTag.INTEGER);