public ResultSetProcessorDesc( ResultSetProcessorFactoryForge resultSetProcessorFactoryForge, ResultSetProcessorType resultSetProcessorType, SelectExprProcessorForge[] selectExprProcessorForges, bool join, bool hasOutputLimit, ResultSetProcessorOutputConditionType? outputConditionType, bool hasOutputLimitSnapshot, EventType resultEventType, bool rollup, AggregationServiceForgeDesc aggregationServiceForgeDesc, OrderByProcessorFactoryForge orderByProcessorFactoryForge, SelectSubscriberDescriptor selectSubscriberDescriptor, IList<StmtClassForgeableFactory> additionalForgeables) { ResultSetProcessorFactoryForge = resultSetProcessorFactoryForge; ResultSetProcessorType = resultSetProcessorType; SelectExprProcessorForges = selectExprProcessorForges; IsJoin = join; HasOutputLimit = hasOutputLimit; OutputConditionType = outputConditionType; HasOutputLimitSnapshot = hasOutputLimitSnapshot; ResultEventType = resultEventType; IsRollup = rollup; AggregationServiceForgeDesc = aggregationServiceForgeDesc; OrderByProcessorFactoryForge = orderByProcessorFactoryForge; SelectSubscriberDescriptor = selectSubscriberDescriptor; AdditionalForgeables = additionalForgeables; }
public static bool IsGrouped(this ResultSetProcessorType value) { switch (value) { case ResultSetProcessorType.HANDTHROUGH: case ResultSetProcessorType.UNAGGREGATED_UNGROUPED: case ResultSetProcessorType.FULLYAGGREGATED_UNGROUPED: case ResultSetProcessorType.AGGREGATED_UNGROUPED: return false; case ResultSetProcessorType.FULLYAGGREGATED_GROUPED: case ResultSetProcessorType.FULLYAGGREGATED_GROUPED_ROLLUP: case ResultSetProcessorType.AGGREGATED_GROUPED: return true; default: throw new ArgumentException("invalid argument", nameof(value)); } }
public static OutputProcessViewFactory Make(StatementSpecCompiled statementSpec, InternalEventRouter internalEventRouter, StatementContext statementContext, EventType resultEventType, OutputProcessViewCallback optionalOutputProcessViewCallback, TableService tableService, ResultSetProcessorType resultSetProcessorType) { // determine direct-callback if (optionalOutputProcessViewCallback != null) { return(new OutputProcessViewFactoryCallback(optionalOutputProcessViewCallback)); } // determine routing var isRouted = false; var routeToFront = false; if (statementSpec.InsertIntoDesc != null) { isRouted = true; routeToFront = statementContext.NamedWindowService.IsNamedWindow(statementSpec.InsertIntoDesc.EventTypeName); } OutputStrategyPostProcessFactory outputStrategyPostProcessFactory = null; if ((statementSpec.InsertIntoDesc != null) || (statementSpec.SelectStreamSelectorEnum == SelectClauseStreamSelectorEnum.RSTREAM_ONLY)) { SelectClauseStreamSelectorEnum?insertIntoStreamSelector = null; string tableName = null; if (statementSpec.InsertIntoDesc != null) { insertIntoStreamSelector = statementSpec.InsertIntoDesc.StreamSelector; var tableMetadata = tableService.GetTableMetadata(statementSpec.InsertIntoDesc.EventTypeName); if (tableMetadata != null) { tableName = tableMetadata.TableName; EPLValidationUtil.ValidateContextName(true, tableName, tableMetadata.ContextName, statementSpec.OptionalContextName, true); } } outputStrategyPostProcessFactory = new OutputStrategyPostProcessFactory(isRouted, insertIntoStreamSelector, statementSpec.SelectStreamSelectorEnum, internalEventRouter, statementContext.EpStatementHandle, routeToFront, tableService, tableName); } // Do we need to enforce an output policy? var streamCount = statementSpec.StreamSpecs.Length; var outputLimitSpec = statementSpec.OutputLimitSpec; var isDistinct = statementSpec.SelectClauseSpec.IsDistinct; var isGrouped = statementSpec.GroupByExpressions != null && statementSpec.GroupByExpressions.GroupByNodes.Length > 0; if (outputLimitSpec != null) { var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); var validationContext = new ExprValidationContext( new StreamTypeServiceImpl(statementContext.EngineURI, false), statementContext.MethodResolutionService, null, statementContext.TimeProvider, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, false, false, null, false); if (outputLimitSpec.AfterTimePeriodExpr != null) { var timePeriodExpr = (ExprTimePeriod)ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, outputLimitSpec.AfterTimePeriodExpr, validationContext); outputLimitSpec.AfterTimePeriodExpr = timePeriodExpr; } if (outputLimitSpec.TimePeriodExpr != null) { var timePeriodExpr = (ExprTimePeriod)ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, outputLimitSpec.TimePeriodExpr, validationContext); outputLimitSpec.TimePeriodExpr = timePeriodExpr; if (timePeriodExpr.IsConstantResult && timePeriodExpr.EvaluateAsSeconds(null, true, new ExprEvaluatorContextStatement(statementContext, false)) <= 0) { throw new ExprValidationException("Invalid time period expression returns a zero or negative time interval"); } } } OutputProcessViewFactory outputProcessViewFactory; if (outputLimitSpec == null) { if (!isDistinct) { outputProcessViewFactory = new OutputProcessViewDirectFactory(statementContext, outputStrategyPostProcessFactory); } else { outputProcessViewFactory = new OutputProcessViewDirectDistinctOrAfterFactory(statementContext, outputStrategyPostProcessFactory, isDistinct, null, null, resultEventType); } } else if (outputLimitSpec.RateType == OutputLimitRateType.AFTER) { outputProcessViewFactory = new OutputProcessViewDirectDistinctOrAfterFactory(statementContext, outputStrategyPostProcessFactory, isDistinct, outputLimitSpec.AfterTimePeriodExpr, outputLimitSpec.AfterNumberOfEvents, resultEventType); } else { try { var isWithHavingClause = statementSpec.HavingExprRootNode != null; var isStartConditionOnCreation = HasOnlyTables(statementSpec.StreamSpecs); var outputConditionFactory = OutputConditionFactoryFactory.CreateCondition(outputLimitSpec, statementContext, isGrouped, isWithHavingClause, isStartConditionOnCreation); var hasOrderBy = statementSpec.OrderByList != null && statementSpec.OrderByList.Length > 0; OutputProcessViewConditionFactory.ConditionType conditionType; var hasAfter = outputLimitSpec.AfterNumberOfEvents != null || outputLimitSpec.AfterTimePeriodExpr != null; var isUnaggregatedUngrouped = resultSetProcessorType == ResultSetProcessorType.HANDTHROUGH || resultSetProcessorType == ResultSetProcessorType.UNAGGREGATED_UNGROUPED; // hint checking with order-by var hasOptHint = HintEnum.ENABLE_OUTPUTLIMIT_OPT.GetHint(statementSpec.Annotations) != null; if (hasOptHint && hasOrderBy) { throw new ExprValidationException("The " + HintEnum.ENABLE_OUTPUTLIMIT_OPT + " hint is not supported with order-by"); } if (outputLimitSpec.DisplayLimit == OutputLimitLimitType.SNAPSHOT) { conditionType = OutputProcessViewConditionFactory.ConditionType.SNAPSHOT; } // For FIRST without groups we are using a special logic that integrates the first-flag, in order to still conveniently use all sorts of output conditions. // FIRST with group-by is handled by setting the output condition to null (OutputConditionNull) and letting the ResultSetProcessor handle first-per-group. // Without having-clause there is no required order of processing, thus also use regular policy. else if (outputLimitSpec.DisplayLimit == OutputLimitLimitType.FIRST && statementSpec.GroupByExpressions == null) { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_FIRST; } else if (isUnaggregatedUngrouped && outputLimitSpec.DisplayLimit == OutputLimitLimitType.LAST) { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_LASTALL_UNORDERED; } else if (hasOptHint && outputLimitSpec.DisplayLimit == OutputLimitLimitType.ALL && !hasOrderBy) { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_LASTALL_UNORDERED; } else if (hasOptHint && outputLimitSpec.DisplayLimit == OutputLimitLimitType.LAST && !hasOrderBy) { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_LASTALL_UNORDERED; } else { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_NONFIRST; } var selectClauseStreamSelectorEnum = statementSpec.SelectStreamSelectorEnum; var terminable = outputLimitSpec.RateType == OutputLimitRateType.TERM || outputLimitSpec.IsAndAfterTerminate; outputProcessViewFactory = new OutputProcessViewConditionFactory(statementContext, outputStrategyPostProcessFactory, isDistinct, outputLimitSpec.AfterTimePeriodExpr, outputLimitSpec.AfterNumberOfEvents, resultEventType, outputConditionFactory, streamCount, conditionType, outputLimitSpec.DisplayLimit, terminable, hasAfter, isUnaggregatedUngrouped, selectClauseStreamSelectorEnum); } catch (Exception ex) { throw new ExprValidationException("Error in the output rate limiting clause: " + ex.Message, ex); } } return(outputProcessViewFactory); }
public static OutputProcessViewFactoryForgeDesc Make( EventType[] typesPerStream, EventType resultEventType, ResultSetProcessorType resultSetProcessorType, StatementSpecCompiled statementSpec, StatementRawInfo statementRawInfo, StatementCompileTimeServices services) { InsertIntoDesc insertIntoDesc = statementSpec.Raw.InsertIntoDesc; SelectClauseStreamSelectorEnum selectStreamSelector = statementSpec.Raw.SelectStreamSelectorEnum; OutputLimitSpec outputLimitSpec = statementSpec.Raw.OutputLimitSpec; int streamCount = statementSpec.StreamSpecs.Length; bool isDistinct = statementSpec.Raw.SelectClauseSpec.IsDistinct; bool isGrouped = statementSpec.GroupByExpressions != null && statementSpec.GroupByExpressions.GroupByNodes.Length > 0; List<StmtClassForgeableFactory> additionalForgeables = new List<StmtClassForgeableFactory>(); // determine routing bool isRouted = false; bool routeToFront = false; if (insertIntoDesc != null) { isRouted = true; routeToFront = services.NamedWindowCompileTimeResolver.Resolve(insertIntoDesc.EventTypeName) != null; } OutputStrategyPostProcessForge outputStrategyPostProcessForge = null; if ((insertIntoDesc != null) || (selectStreamSelector == SelectClauseStreamSelectorEnum.RSTREAM_ONLY)) { SelectClauseStreamSelectorEnum? insertIntoStreamSelector = null; TableMetaData table = null; if (insertIntoDesc != null) { insertIntoStreamSelector = insertIntoDesc.StreamSelector; table = services.TableCompileTimeResolver.Resolve(statementSpec.Raw.InsertIntoDesc.EventTypeName); if (table != null) { EPLValidationUtil.ValidateContextName( true, table.TableName, table.OptionalContextName, statementSpec.Raw.OptionalContextName, true); } } bool audit = AuditEnum.INSERT.GetAudit(statementSpec.Annotations) != null; outputStrategyPostProcessForge = new OutputStrategyPostProcessForge( isRouted, insertIntoStreamSelector, selectStreamSelector, routeToFront, table, audit); } MultiKeyPlan multiKeyPlan = MultiKeyPlanner.PlanMultiKeyDistinct( isDistinct, resultEventType, statementRawInfo, SerdeCompileTimeResolverNonHA.INSTANCE); MultiKeyClassRef distinctMultiKey = multiKeyPlan.ClassRef; additionalForgeables.AddRange(multiKeyPlan.MultiKeyForgeables); OutputProcessViewFactoryForge outputProcessViewFactoryForge; if (outputLimitSpec == null) { if (!isDistinct) { if (outputStrategyPostProcessForge == null || !outputStrategyPostProcessForge.HasTable) { // without table we have a shortcut implementation outputProcessViewFactoryForge = new OutputProcessViewDirectSimpleForge(outputStrategyPostProcessForge); } else { outputProcessViewFactoryForge = new OutputProcessViewDirectForge(outputStrategyPostProcessForge); } } else { outputProcessViewFactoryForge = new OutputProcessViewDirectDistinctOrAfterFactoryForge( outputStrategyPostProcessForge, isDistinct, distinctMultiKey, null, null, resultEventType); } } else if (outputLimitSpec.RateType == OutputLimitRateType.AFTER) { outputProcessViewFactoryForge = new OutputProcessViewDirectDistinctOrAfterFactoryForge( outputStrategyPostProcessForge, isDistinct, distinctMultiKey, outputLimitSpec.AfterTimePeriodExpr, outputLimitSpec.AfterNumberOfEvents, resultEventType); } else { try { bool isWithHavingClause = statementSpec.Raw.HavingClause != null; bool isStartConditionOnCreation = HasOnlyTables(statementSpec.StreamSpecs); OutputConditionFactoryForge outputConditionFactoryForge = OutputConditionFactoryFactory.CreateCondition( outputLimitSpec, isGrouped, isWithHavingClause, isStartConditionOnCreation, statementRawInfo, services); bool hasOrderBy = statementSpec.Raw.OrderByList != null && statementSpec.Raw.OrderByList.Count > 0; bool hasAfter = outputLimitSpec.AfterNumberOfEvents != null || outputLimitSpec.AfterTimePeriodExpr != null; // hint checking with order-by bool hasOptHint = ResultSetProcessorOutputConditionTypeExtensions .GetOutputLimitOpt(statementSpec.Annotations, services.Configuration, hasOrderBy); ResultSetProcessorOutputConditionType conditionType = ResultSetProcessorOutputConditionTypeExtensions .GetConditionType( outputLimitSpec.DisplayLimit, resultSetProcessorType.IsAggregated(), hasOrderBy, hasOptHint, resultSetProcessorType.IsGrouped()); // plan serdes foreach (EventType eventType in typesPerStream) { IList<StmtClassForgeableFactory> serdeForgeables = SerdeEventTypeUtility.Plan( eventType, statementRawInfo, services.SerdeEventTypeRegistry, services.SerdeResolver); additionalForgeables.AddRange(serdeForgeables); } bool terminable = outputLimitSpec.RateType == OutputLimitRateType.TERM || outputLimitSpec.IsAndAfterTerminate; outputProcessViewFactoryForge = new OutputProcessViewConditionForge( outputStrategyPostProcessForge, isDistinct, distinctMultiKey, outputLimitSpec.AfterTimePeriodExpr, outputLimitSpec.AfterNumberOfEvents, outputConditionFactoryForge, streamCount, conditionType, terminable, hasAfter, resultSetProcessorType.IsUnaggregatedUngrouped(), selectStreamSelector, typesPerStream, resultEventType); } catch (Exception ex) { throw new ExprValidationException("Failed to validate the output rate limiting clause: " + ex.Message, ex); } } return new OutputProcessViewFactoryForgeDesc(outputProcessViewFactoryForge, additionalForgeables); }
public static bool IsUnaggregatedUngrouped(this ResultSetProcessorType value) { return !IsAggregated(value) && !IsGrouped(value); }