Ejemplo n.º 1
0
        public override EPStatementStartResult StartInternal(
            EPServicesContext services,
            StatementContext statementContext,
            bool isNewStatement,
            bool isRecoveringStatement,
            bool isRecoveringResilient)
        {
            CreateSchemaDesc spec = StatementSpec.CreateSchemaDesc;

            EPLValidationUtil.ValidateTableExists(services.TableService, spec.SchemaName);
            EventType eventType = HandleCreateSchema(services, statementContext, spec);

            // enter a reference
            services.StatementEventTypeRefService.AddReferences(
                statementContext.StatementName, new String[]
            {
                spec.SchemaName
            });

            EventType             allocatedEventType = eventType;
            EPStatementStopMethod stopMethod         = () =>
            {
                services.StatementEventTypeRefService.RemoveReferencesStatement(statementContext.StatementName);
                if (services.StatementEventTypeRefService.GetStatementNamesForType(spec.SchemaName).IsEmpty())
                {
                    services.EventAdapterService.RemoveType(allocatedEventType.Name);
                    services.FilterService.RemoveType(allocatedEventType);
                }
            };

            Viewable viewable = new ViewableDefaultImpl(eventType);

            return(new EPStatementStartResult(viewable, stopMethod, null));
        }
        protected override ExprEvaluator ValidateAll(
            string lhsName,
            IList<ExprNode> lhs,
            string rhsName,
            IList<ExprNode> rhs,
            ExprValidationContext validationContext)
        {
            EPLValidationUtil.ValidateParameterNumber(lhsName, LHS_VALIDATION_NAME, false, 4, lhs.Count);
            EPLValidationUtil.ValidateParametersTypePredefined(lhs, lhsName, LHS_VALIDATION_NAME,
                EPLExpressionParamType.NUMERIC);

            EPLValidationUtil.ValidateParameterNumber(rhsName, RHS_VALIDATION_NAME, true, 4, rhs.Count);
            EPLValidationUtil.ValidateParametersTypePredefined(rhs, rhsName, RHS_VALIDATION_NAME,
                EPLExpressionParamType.NUMERIC);

            var meXEval = lhs[0].ExprEvaluator;
            var meYEval = lhs[1].ExprEvaluator;
            var meWidthEval = lhs[2].ExprEvaluator;
            var meHeightEval = lhs[3].ExprEvaluator;

            var otherXEval = rhs[0].ExprEvaluator;
            var otherYEval = rhs[1].ExprEvaluator;
            var otherWidthEval = rhs[2].ExprEvaluator;
            var otherHeightEval = rhs[3].ExprEvaluator;
            return new RectangleIntersectsRectangleEvaluator(meXEval, meYEval, meWidthEval, meHeightEval, otherXEval,
                otherYEval, otherWidthEval, otherHeightEval);
        }
Ejemplo n.º 3
0
        private static void ValidateSpecificTypes(
            string methodUsedName,
            DotMethodTypeEnum type,
            DotMethodFPParam[] foundParams,
            DotMethodFPProvidedParam[] @params)
        {
            for (int i = 0; i < foundParams.Length; i++)
            {
                DotMethodFPParam         found    = foundParams[i];
                DotMethodFPProvidedParam provided = @params[i];

                // Lambda-type expressions not validated here
                if (found.LambdaParamNum > 0)
                {
                    continue;
                }

                EPLValidationUtil.ValidateParameterType(
                    methodUsedName,
                    type.GetTypeName(),
                    false,
                    found.ParamType,
                    found.SpecificType,
                    provided.ReturnType,
                    i,
                    provided.Expression);
            }
        }
Ejemplo n.º 4
0
        private OnTriggerActivatorDesc ActivatorNamedWindow(
            NamedWindowConsumerStreamSpec namedSpec,
            StatementCompileTimeServices services)
        {
            var namedWindow = namedSpec.NamedWindow;
            var triggerEventTypeName = namedSpec.NamedWindow.EventType.Name;

            var typesFilterValidation = new StreamTypeServiceImpl(
                namedWindow.EventType,
                namedSpec.OptionalStreamName,
                false);
            var filterSingle =
                ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(namedSpec.FilterExpressions);
            var filterQueryGraph = EPLValidationUtil.ValidateFilterGetQueryGraphSafe(
                filterSingle,
                typesFilterValidation,
                @base.StatementRawInfo,
                services);
            var activator = new ViewableActivatorNamedWindowForge(
                namedSpec,
                namedWindow,
                filterSingle,
                filterQueryGraph,
                false,
                namedSpec.OptPropertyEvaluator);

            var activatorResultEventType = namedWindow.EventType;
            if (namedSpec.OptPropertyEvaluator != null) {
                activatorResultEventType = namedSpec.OptPropertyEvaluator.FragmentEventType;
            }

            return new OnTriggerActivatorDesc(activator, triggerEventTypeName, activatorResultEventType);
        }
Ejemplo n.º 5
0
        protected override ExprForge ValidateAll(
            string lhsName,
            ExprNode[] lhs,
            string rhsName,
            ExprNode[] rhs,
            ExprValidationContext validationContext)
        {
            EPLValidationUtil.ValidateParameterNumber(lhsName, LHS_VALIDATION_NAME, false, 2, lhs.Length);
            EPLValidationUtil.ValidateParametersTypePredefined(
                lhs,
                lhsName,
                LHS_VALIDATION_NAME,
                EPLExpressionParamType.NUMERIC);

            EPLValidationUtil.ValidateParameterNumber(rhsName, RHS_VALIDATION_NAME, true, 4, rhs.Length);
            EPLValidationUtil.ValidateParametersTypePredefined(
                rhs,
                rhsName,
                RHS_VALIDATION_NAME,
                EPLExpressionParamType.NUMERIC);

            ExprForge pxEval = lhs[0].Forge;
            ExprForge pyEval = lhs[1].Forge;
            ExprForge xEval = rhs[0].Forge;
            ExprForge yEval = rhs[1].Forge;
            ExprForge widthEval = rhs[2].Forge;
            ExprForge heightEval = rhs[3].Forge;
            return new PointIntersectsRectangleForge(parent, pxEval, pyEval, xEval, yEval, widthEval, heightEval);
        }
Ejemplo n.º 6
0
 private void CheckTableExists(string eventTypeName)
 {
     try {
         EPLValidationUtil.ValidateTableExists(_tableService, eventTypeName);
     } catch (ExprValidationException ex) {
         throw new ConfigurationException(ex.Message, ex);
     }
 }
Ejemplo n.º 7
0
        public EventAdvancedIndexProvisionCompileTime ToCompileTime(
            EventType eventTypeIndexed,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            ExprNode[] indexedExpr;
            if (IndexExpressionsOpt != null) {
                indexedExpr = IndexExpressionsOpt;
            }
            else {
                if (IsIndexExpressionsAllProps) {
                    indexedExpr = new ExprNode[IndexProperties.Length];
                    for (var i = 0; i < IndexProperties.Length; i++) {
                        indexedExpr[i] = new ExprIdentNodeImpl(eventTypeIndexed, IndexProperties[i], 0);
                    }
                }
                else {
                    indexedExpr = new ExprNode[IndexProperties.Length];
                    for (var i = 0; i < IndexProperties.Length; i++) {
                        indexedExpr[i] = services.CompilerServices.CompileExpression(IndexExpressionTexts[i], services);
                        indexedExpr[i] = EPLValidationUtil.ValidateSimpleGetSubtree(
                            ExprNodeOrigin.CREATEINDEXCOLUMN,
                            indexedExpr[i],
                            eventTypeIndexed,
                            false,
                            statementRawInfo,
                            services);
                    }
                }
            }

            var desc = new AdvancedIndexDescWExpr(IndexTypeName, indexedExpr);

            ExprNode[] parameters;
            if (ParameterExpressionsOpt != null) {
                parameters = ParameterExpressionsOpt;
            }
            else {
                parameters = new ExprNode[ParameterExpressionTexts.Length];
                for (var i = 0; i < ParameterExpressionTexts.Length; i++) {
                    parameters[i] = services.CompilerServices.CompileExpression(ParameterExpressionTexts[i], services);
                }
            }

            return new EventAdvancedIndexProvisionCompileTime(
                desc,
                parameters,
                Factory.Forge,
                Factory.ToConfigStatement(indexedExpr));
        }
Ejemplo n.º 8
0
 public static ExprForge ToExpression(
     string hint,
     StatementRawInfo rawInfo,
     StatementCompileTimeServices services)
 {
     ExprNode expr = services.CompilerServices.CompileExpression(hint, services);
     ExprNode validated = EPLValidationUtil.ValidateSimpleGetSubtree(
         ExprNodeOrigin.HINT,
         expr,
         OAEXPRESSIONTYPE,
         false,
         rawInfo,
         services);
     return validated.Forge;
 }
Ejemplo n.º 9
0
        private DataFlowOpForgeInitializeResult InitializeTypeUndeclared(DataFlowOpForgeInitializeContext context)
        {
            // No type has been declared, we can create one
            var types = new LinkedHashMap<string, object>();
            var props = allProperties.Keys;
            props.RemoveAll(PARAMETER_PROPERTIES);

            var count = 0;
            evaluatorForges = new ExprForge[props.Count];
            foreach (var propertyName in props) {
                var exprNode = allProperties.Get(propertyName);
                var validated = EPLValidationUtil.ValidateSimpleGetSubtree(
                    ExprNodeOrigin.DATAFLOWBEACON,
                    exprNode,
                    null,
                    false,
                    context.StatementRawInfo,
                    context.Services);
                types.Put(propertyName, validated.Forge.EvaluationType);
                evaluatorForges[count] = validated.Forge;
                count++;
            }

            var eventTypeName =
                context.Services.EventTypeNameGeneratorStatement.GetDataflowOperatorTypeName(context.OperatorNumber);
            var metadata = new EventTypeMetadata(
                eventTypeName,
                context.Base.ModuleName,
                EventTypeTypeClass.DBDERIVED,
                EventTypeApplicationType.OBJECTARR,
                NameAccessModifier.TRANSIENT,
                EventTypeBusModifier.NONBUS,
                false,
                EventTypeIdPair.Unassigned());
            outputEventType = BaseNestableEventUtil.MakeOATypeCompileTime(
                metadata,
                types,
                null,
                null,
                null,
                null,
                context.Services.BeanEventTypeFactoryPrivate,
                context.Services.EventTypeCompileTimeResolver);
            context.Services.EventTypeCompileTimeRegistry.NewType(outputEventType);

            return new DataFlowOpForgeInitializeResult(new[] {new GraphTypeDesc(false, true, outputEventType)});
        }
        protected override ExprForge ValidateAll(
            string lhsName,
            ExprNode[] lhs,
            string rhsName,
            ExprNode[] rhs,
            ExprValidationContext validationContext)
        {
            EPLValidationUtil.ValidateParameterNumber(lhsName, LHS_VALIDATION_NAME, false, 4, lhs.Length);
            EPLValidationUtil.ValidateParametersTypePredefined(
                lhs,
                lhsName,
                LHS_VALIDATION_NAME,
                EPLExpressionParamType.NUMERIC);

            EPLValidationUtil.ValidateParameterNumber(rhsName, RHS_VALIDATION_NAME, true, 4, rhs.Length);
            EPLValidationUtil.ValidateParametersTypePredefined(
                rhs,
                rhsName,
                RHS_VALIDATION_NAME,
                EPLExpressionParamType.NUMERIC);

            var meXEval = lhs[0].Forge;
            var meYEval = lhs[1].Forge;
            var meWidthEval = lhs[2].Forge;
            var meHeightEval = lhs[3].Forge;

            var otherXEval = rhs[0].Forge;
            var otherYEval = rhs[1].Forge;
            var otherWidthEval = rhs[2].Forge;
            var otherHeightEval = rhs[3].Forge;
            return new RectangleIntersectsRectangleForge(
                parent,
                meXEval,
                meYEval,
                meWidthEval,
                meHeightEval,
                otherXEval,
                otherYEval,
                otherWidthEval,
                otherHeightEval);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Validate the provided expression.
        /// </summary>
        /// <param name="name">parameter name</param>
        /// <param name="eventType">event type</param>
        /// <param name="expr">expression</param>
        /// <param name="expectedReturnType">expected result type</param>
        /// <param name="context">forge initialization context</param>
        /// <returns>validated expression node</returns>
        /// <throws>ExprValidationException when validation failed</throws>
        public static ExprNode Validate(
            string name,
            ExprNode expr,
            EventType eventType,
            Type expectedReturnType,
            DataFlowOpForgeInitializeContext context)
        {
            if (expr == null) {
                return null;
            }

            ExprNode validated = EPLValidationUtil.ValidateSimpleGetSubtree(
                ExprNodeOrigin.DATAFLOWFILTER,
                expr,
                eventType,
                false,
                context.StatementRawInfo,
                context.Services);
            ValidateReturnType(name, validated, expectedReturnType);
            return validated;
        }
        protected override ExprEvaluator ValidateAll(
            string lhsName,
            IList<ExprNode> lhs,
            string rhsName,
            IList<ExprNode> rhs,
            ExprValidationContext validationContext)
        {
            EPLValidationUtil.ValidateParameterNumber(lhsName, LHS_VALIDATION_NAME, false, 2, lhs.Count);
            EPLValidationUtil.ValidateParametersTypePredefined(lhs, lhsName, LHS_VALIDATION_NAME,
                EPLExpressionParamType.NUMERIC);

            EPLValidationUtil.ValidateParameterNumber(rhsName, RHS_VALIDATION_NAME, true, 4, rhs.Count);
            EPLValidationUtil.ValidateParametersTypePredefined(rhs, rhsName, RHS_VALIDATION_NAME,
                EPLExpressionParamType.NUMERIC);

            var pxEval = lhs[0].ExprEvaluator;
            var pyEval = lhs[1].ExprEvaluator;
            var xEval = rhs[0].ExprEvaluator;
            var yEval = rhs[1].ExprEvaluator;
            var widthEval = rhs[2].ExprEvaluator;
            var heightEval = rhs[3].ExprEvaluator;
            return new PointIntersectsRectangleEvaluator(pxEval, pyEval, xEval, yEval, widthEval, heightEval);
        }
Ejemplo n.º 13
0
        public StmtForgeMethodResult Make(
            string @namespace,
            string classPostfix,
            StatementCompileTimeServices services)
        {
            var statementSpec = _base.StatementSpec;

            var createDesc = statementSpec.Raw.CreateVariableDesc;

            // Check if the variable is already declared
            EPLValidationUtil.ValidateAlreadyExistsTableOrVariable(
                createDesc.VariableName,
                services.VariableCompileTimeResolver,
                services.TableCompileTimeResolver,
                services.EventTypeCompileTimeResolver);

            // Get assignment value when compile-time-constant
            object initialValue = null;
            ExprForge initialValueExpr = null;
            if (createDesc.Assignment != null) {
                // Evaluate assignment expression
                StreamTypeService typeService = new StreamTypeServiceImpl(
                    new EventType[0],
                    new string[0],
                    new bool[0],
                    false,
                    false);
                var validationContext =
                    new ExprValidationContextBuilder(typeService, _base.StatementRawInfo, services).Build();
                var validated = ExprNodeUtilityValidate.GetValidatedSubtree(
                    ExprNodeOrigin.VARIABLEASSIGN,
                    createDesc.Assignment,
                    validationContext);
                if (validated.Forge.ForgeConstantType == ExprForgeConstantType.COMPILETIMECONST) {
                    initialValue = validated.Forge.ExprEvaluator.Evaluate(null, true, null);
                }

                createDesc.Assignment = validated;
                initialValueExpr = validated.Forge;
            }

            var contextName = statementSpec.Raw.OptionalContextName;
            NameAccessModifier? contextVisibility = null;
            string contextModuleName = null;
            if (contextName != null) {
                var contextDetail = services.ContextCompileTimeResolver.GetContextInfo(contextName);
                if (contextDetail == null) {
                    throw new ExprValidationException("Failed to find context '" + contextName + "'");
                }

                contextVisibility = contextDetail.ContextVisibility;
                contextModuleName = contextDetail.ContextModuleName;
            }

            // get visibility
            var visibility = services.ModuleVisibilityRules.GetAccessModifierVariable(_base, createDesc.VariableName);

            // Compile metadata
            var compileTimeConstant = createDesc.IsConstant &&
                                      initialValueExpr != null &&
                                      initialValueExpr.ForgeConstantType.IsCompileTimeConstant;
            var metaData = VariableUtil.CompileVariable(
                createDesc.VariableName,
                _base.ModuleName,
                visibility,
                contextName,
                contextVisibility,
                contextModuleName,
                createDesc.VariableType,
                createDesc.IsConstant,
                compileTimeConstant,
                initialValue,
                services.ImportServiceCompileTime,
                EventBeanTypedEventFactoryCompileTime.INSTANCE,
                services.EventTypeRepositoryPreconfigured,
                services.BeanEventTypeFactoryPrivate);

            // Register variable
            services.VariableCompileTimeRegistry.NewVariable(metaData);

            // Statement event type
            var eventTypePropertyTypes = Collections.SingletonDataMap(
                metaData.VariableName,
                metaData.Type);
            var eventTypeName = services.EventTypeNameGeneratorStatement.AnonymousTypeName;
            var eventTypeMetadata = new EventTypeMetadata(
                eventTypeName,
                _base.ModuleName,
                EventTypeTypeClass.STATEMENTOUT,
                EventTypeApplicationType.MAP,
                NameAccessModifier.TRANSIENT,
                EventTypeBusModifier.NONBUS,
                false,
                EventTypeIdPair.Unassigned());
            var outputEventType = BaseNestableEventUtil.MakeMapTypeCompileTime(
                eventTypeMetadata,
                eventTypePropertyTypes,
                null,
                null,
                null,
                null,
                services.BeanEventTypeFactoryPrivate,
                services.EventTypeCompileTimeResolver);
            services.EventTypeCompileTimeRegistry.NewType(outputEventType);

            // Handle output format
            var defaultSelectAllSpec = new StatementSpecCompiled();
            defaultSelectAllSpec.SelectClauseCompiled.WithSelectExprList(new SelectClauseElementWildcard());
            defaultSelectAllSpec.Raw.SelectStreamDirEnum = SelectClauseStreamSelectorEnum.RSTREAM_ISTREAM_BOTH;
            StreamTypeService streamTypeService = new StreamTypeServiceImpl(
                new EventType[] {outputEventType},
                new string[] {"trigger_stream"},
                new bool[] {true},
                false,
                false);
            var resultSetProcessor = ResultSetProcessorFactoryFactory.GetProcessorPrototype(
                new ResultSetSpec(defaultSelectAllSpec),
                streamTypeService,
                null,
                new bool[1],
                false,
                _base.ContextPropertyRegistry,
                false,
                false,
                _base.StatementRawInfo,
                services);

            // Code generation
            var statementFieldsClassName =
                CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementFields), classPostfix);
            var aiFactoryProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementAIFactoryProvider),
                classPostfix);
            var classNameRSP = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(ResultSetProcessorFactoryProvider),
                classPostfix);
            var packageScope = new CodegenNamespaceScope(
                @namespace,
                statementFieldsClassName,
                services.IsInstrumented);

            var forge =
                new StatementAgentInstanceFactoryCreateVariableForge(
                    createDesc.VariableName,
                    initialValueExpr,
                    classNameRSP);
            var aiFactoryForgable = new StmtClassForgableAIFactoryProviderCreateVariable(
                aiFactoryProviderClassName,
                packageScope,
                forge,
                createDesc.VariableName);

            var informationals = StatementInformationalsUtil.GetInformationals(
                _base,
                Collections.GetEmptyList<FilterSpecCompiled>(),
                Collections.GetEmptyList<ScheduleHandleCallbackProvider>(),
                Collections.GetEmptyList<NamedWindowConsumerStreamSpec>(),
                true,
                resultSetProcessor.SelectSubscriberDescriptor,
                packageScope,
                services);
            var statementProviderClassName =
                CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementProvider), classPostfix);
            var stmtProvider = new StmtClassForgableStmtProvider(
                aiFactoryProviderClassName,
                statementProviderClassName,
                informationals,
                packageScope);

            IList<StmtClassForgable> forgables = new List<StmtClassForgable>();
            forgables.Add(
                new StmtClassForgableRSPFactoryProvider(
                    classNameRSP,
                    resultSetProcessor,
                    packageScope,
                    _base.StatementRawInfo));
            forgables.Add(aiFactoryForgable);
            forgables.Add(stmtProvider);
            forgables.Add(new StmtClassForgableStmtFields(statementFieldsClassName, packageScope, 0));
            return new StmtForgeMethodResult(
                forgables,
                Collections.GetEmptyList<FilterSpecCompiled>(),
                Collections.GetEmptyList<ScheduleHandleCallbackProvider>(),
                Collections.GetEmptyList<NamedWindowConsumerStreamSpec>(),
                Collections.GetEmptyList<FilterSpecParamExprNodeForge>());
        }
Ejemplo n.º 14
0
        public static AggregationServiceForgeDesc GetService(
            IList<ExprAggregateNode> selectAggregateExprNodes,
            IDictionary<ExprNode, string> selectClauseNamedNodes,
            IList<ExprDeclaredNode> declaredExpressions,
            ExprNode[] groupByNodes,
            MultiKeyClassRef groupByMultiKey,
            IList<ExprAggregateNode> havingAggregateExprNodes,
            IList<ExprAggregateNode> orderByAggregateExprNodes,
            IList<ExprAggregateNodeGroupKey> groupKeyExpressions,
            bool hasGroupByClause,
            Attribute[] annotations,
            VariableCompileTimeResolver variableCompileTimeResolver,
            bool isDisallowNoReclaim,
            ExprNode whereClause,
            ExprNode havingClause,
            EventType[] typesPerStream,
            AggregationGroupByRollupDescForge groupByRollupDesc,
            string optionalContextName,
            IntoTableSpec intoTableSpec,
            TableCompileTimeResolver tableCompileTimeResolver,
            bool isUnidirectional,
            bool isFireAndForget,
            bool isOnSelect,
            ImportServiceCompileTime importService,
            StatementRawInfo raw,
            SerdeCompileTimeResolver serdeResolver)
        {
            // No aggregates used, we do not need this service
            if (selectAggregateExprNodes.IsEmpty() && havingAggregateExprNodes.IsEmpty()) {
                if (intoTableSpec != null) {
                    throw new ExprValidationException("Into-table requires at least one aggregation function");
                }

                return new AggregationServiceForgeDesc(
                    AggregationServiceNullFactory.INSTANCE,
                    EmptyList<AggregationServiceAggExpressionDesc>.Instance,
                    EmptyList<ExprAggregateNodeGroupKey>.Instance,
                    EmptyList<StmtClassForgeableFactory>.Instance);
            }

            // Validate the absence of "prev" function in where-clause:
            // Since the "previous" function does not post remove stream results, disallow when used with aggregations.
            if (whereClause != null || havingClause != null) {
                var visitor = new ExprNodePreviousVisitorWParent();
                whereClause?.Accept(visitor);

                havingClause?.Accept(visitor);

                if (visitor.Previous != null && !visitor.Previous.IsEmpty()) {
                    string funcname = visitor.Previous[0]
                        .Second.PreviousType.ToString()
                        .ToLowerInvariant();
                    throw new ExprValidationException(
                        "The '" +
                        funcname +
                        "' function may not occur in the where-clause or having-clause of a statement with aggregations as 'previous' does not provide remove stream data; Use the 'first','last','window' or 'count' aggregation functions instead");
                }
            }

            // Compile a map of aggregation nodes and equivalent-to aggregation nodes.
            // Equivalent-to functions are for example "select sum(a*b), 5*sum(a*b)".
            // Reducing the total number of aggregation functions.
            var aggregations = new List<AggregationServiceAggExpressionDesc>();
            var intoTableNonRollup = groupByRollupDesc == null && intoTableSpec != null;
            foreach (var selectAggNode in selectAggregateExprNodes) {
                AddEquivalent(selectAggNode, aggregations, intoTableNonRollup);
            }

            foreach (var havingAggNode in havingAggregateExprNodes) {
                AddEquivalent(havingAggNode, aggregations, intoTableNonRollup);
            }

            foreach (var orderByAggNode in orderByAggregateExprNodes) {
                AddEquivalent(orderByAggNode, aggregations, intoTableNonRollup);
            }

            // Construct a list of evaluation node for the aggregation functions (regular agg).
            // For example "sum(2 * 3)" would make the sum an evaluation node.
            IList<ExprForge[]> methodAggForgesList = new List<ExprForge[]>();
            foreach (var aggregation in aggregations) {
                var aggregateNode = aggregation.AggregationNode;
                if (!aggregateNode.Factory.IsAccessAggregation) {
                    var forges = aggregateNode.Factory.GetMethodAggregationForge(
                        typesPerStream.Length > 1,
                        typesPerStream);
                    methodAggForgesList.Add(forges);
                }
            }

            // determine local group-by, report when hook provided
            var localGroupDesc = AnalyzeLocalGroupBy(aggregations, groupByNodes, groupByRollupDesc, intoTableSpec);

            // determine binding
            if (intoTableSpec != null) {
                // obtain metadata
                var metadata = tableCompileTimeResolver.Resolve(intoTableSpec.Name);
                if (metadata == null) {
                    throw new ExprValidationException(
                        "Invalid into-table clause: Failed to find table by name '" + intoTableSpec.Name + "'");
                }

                EPLValidationUtil.ValidateContextName(
                    true,
                    intoTableSpec.Name,
                    metadata.OptionalContextName,
                    optionalContextName,
                    false);

                // validate group keys
                var groupByTypes = ExprNodeUtilityQuery.GetExprResultTypes(groupByNodes);
                var keyTypes = metadata.IsKeyed ? metadata.KeyTypes : new Type[0];
                ExprTableNodeUtil.ValidateExpressions(
                    intoTableSpec.Name,
                    groupByTypes,
                    "group-by",
                    groupByNodes,
                    keyTypes,
                    "group-by");

                // determine how this binds to existing aggregations, assign column numbers
                var bindingMatchResult = MatchBindingsAssignColumnNumbers(
                    intoTableSpec,
                    metadata,
                    aggregations,
                    selectClauseNamedNodes,
                    methodAggForgesList,
                    declaredExpressions,
                    importService,
                    raw.StatementName);

                // return factory
                AggregationServiceFactoryForge serviceForgeX = new AggregationServiceFactoryForgeTable(
                    metadata,
                    bindingMatchResult.MethodPairs,
                    bindingMatchResult.TargetStates,
                    bindingMatchResult.Agents,
                    groupByRollupDesc);
                return new AggregationServiceForgeDesc(serviceForgeX, aggregations, groupKeyExpressions, EmptyList<StmtClassForgeableFactory>.Instance);
            }

            // Assign a column number to each aggregation node. The regular aggregation goes first followed by access-aggregation.
            var columnNumber = 0;
            foreach (var entry in aggregations) {
                if (!entry.Factory.IsAccessAggregation) {
                    entry.SetColumnNum(columnNumber++);
                }
            }

            foreach (var entry in aggregations) {
                if (entry.Factory.IsAccessAggregation) {
                    entry.SetColumnNum(columnNumber++);
                }
            }

            // determine method aggregation factories and evaluators(non-access)
            var methodAggForges = methodAggForgesList.ToArray();
            var methodAggFactories = new AggregationForgeFactory[methodAggForges.Length];
            var count = 0;
            foreach (var aggregation in aggregations) {
                var aggregateNode = aggregation.AggregationNode;
                if (!aggregateNode.Factory.IsAccessAggregation) {
                    methodAggFactories[count] = aggregateNode.Factory;
                    count++;
                }
            }

            // handle access aggregations
            var multiFunctionAggPlan = AggregationMultiFunctionAnalysisHelper.AnalyzeAccessAggregations(
                aggregations,
                importService,
                isFireAndForget,
                raw.StatementName,
                groupByNodes);
            var accessorPairsForge = multiFunctionAggPlan.AccessorPairsForge;
            var accessFactories = multiFunctionAggPlan.StateFactoryForges;
            var hasAccessAgg = accessorPairsForge.Length > 0;
            var hasMethodAgg = methodAggFactories.Length > 0;

            AggregationServiceFactoryForge serviceForge;
            var useFlags = new AggregationUseFlags(isUnidirectional, isFireAndForget, isOnSelect);
            var additionalForgeables = new List<StmtClassForgeableFactory>();

            // analyze local group by
            AggregationLocalGroupByPlanForge localGroupByPlan = null;
            if (localGroupDesc != null) {
                AggregationLocalGroupByPlanDesc plan = AggregationGroupByLocalGroupByAnalyzer.Analyze(
                    methodAggForges,
                    methodAggFactories,
                    accessFactories,
                    localGroupDesc,
                    groupByNodes,
                    groupByMultiKey,
                    accessorPairsForge,
                    raw,
                    serdeResolver);
                localGroupByPlan = plan.Forge;
                additionalForgeables.AddAll(plan.AdditionalForgeables);

                try {
                    var hook = (AggregationLocalLevelHook) ImportUtil.GetAnnotationHook(
                        annotations,
                        HookType.INTERNAL_AGGLOCALLEVEL,
                        typeof(AggregationLocalLevelHook),
                        importService);
                    hook?.Planned(localGroupDesc, localGroupByPlan);
                }
                catch (ExprValidationException) {
                    throw new EPException("Failed to obtain hook for " + HookType.INTERNAL_AGGLOCALLEVEL);
                }
            }

            // Handle without a group-by clause: we group all into the same pot
            var rowStateDesc = new AggregationRowStateForgeDesc(
                hasMethodAgg ? methodAggFactories : null,
                hasMethodAgg ? methodAggForges : null,
                hasAccessAgg ? accessFactories : null,
                hasAccessAgg ? accessorPairsForge : null,
                useFlags);
            if (!hasGroupByClause) {
                if (localGroupByPlan != null) {
                    serviceForge = new AggSvcLocalGroupByForge(false, localGroupByPlan, useFlags);
                }
                else {
                    serviceForge = new AggregationServiceGroupAllForge(rowStateDesc);
                }
            }
            else {
                var groupDesc = new AggGroupByDesc(
                    rowStateDesc,
                    isUnidirectional,
                    isFireAndForget,
                    isOnSelect,
                    groupByNodes,
                    groupByMultiKey);
                var hasNoReclaim = HintEnum.DISABLE_RECLAIM_GROUP.GetHint(annotations) != null;
                var reclaimGroupAged = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations);
                var reclaimGroupFrequency = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations);
                if (localGroupByPlan != null) {
                    serviceForge = new AggSvcLocalGroupByForge(true, localGroupByPlan, useFlags);
                }
                else {
                    if (!isDisallowNoReclaim && hasNoReclaim) {
                        if (groupByRollupDesc != null) {
                            throw GetRollupReclaimEx();
                        }

                        serviceForge = new AggregationServiceGroupByForge(groupDesc, importService.TimeAbacus);
                    }
                    else if (!isDisallowNoReclaim && reclaimGroupAged != null) {
                        if (groupByRollupDesc != null) {
                            throw GetRollupReclaimEx();
                        }

                        CompileReclaim(
                            groupDesc,
                            reclaimGroupAged,
                            reclaimGroupFrequency,
                            variableCompileTimeResolver,
                            optionalContextName);
                        serviceForge = new AggregationServiceGroupByForge(groupDesc, importService.TimeAbacus);
                    }
                    else if (groupByRollupDesc != null) {
                        serviceForge = new AggSvcGroupByRollupForge(rowStateDesc, groupByRollupDesc, groupByNodes);
                    }
                    else {
                        groupDesc.IsRefcounted = true;
                        serviceForge = new AggregationServiceGroupByForge(groupDesc, importService.TimeAbacus);
                    }
                }
            }

            return new AggregationServiceForgeDesc(serviceForge, aggregations, groupKeyExpressions, additionalForgeables);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Returns an instance to handle the aggregation required by the aggregation expression nodes, depending on
        /// whether there are any group-by nodes.
        /// </summary>
        /// <param name="selectAggregateExprNodes">aggregation nodes extracted out of the select expression</param>
        /// <param name="selectClauseNamedNodes">The select clause named nodes.</param>
        /// <param name="declaredExpressions">The declared expressions.</param>
        /// <param name="groupByNodes">The group by nodes.</param>
        /// <param name="havingAggregateExprNodes">aggregation nodes extracted out of the select expression</param>
        /// <param name="orderByAggregateExprNodes">aggregation nodes extracted out of the select expression</param>
        /// <param name="groupKeyExpressions">The group key expressions.</param>
        /// <param name="hasGroupByClause">indicator on whethere there is group-by required, or group-all</param>
        /// <param name="annotations">statement annotations</param>
        /// <param name="variableService">variable</param>
        /// <param name="isJoin">true for joins</param>
        /// <param name="isDisallowNoReclaim">if set to <c>true</c> [is disallow no reclaim].</param>
        /// <param name="whereClause">the where-clause function if any</param>
        /// <param name="havingClause">the having-clause function if any</param>
        /// <param name="factoryService">The factory service.</param>
        /// <param name="typesPerStream">The types per stream.</param>
        /// <param name="methodResolutionService">The method resolution service.</param>
        /// <param name="groupByRollupDesc">The group by rollup desc.</param>
        /// <param name="optionalContextName">Name of the optional context.</param>
        /// <param name="intoTableSpec">The into table spec.</param>
        /// <param name="tableService">The table service.</param>
        /// <param name="isUnidirectional">if set to <c>true</c> [is unidirectional].</param>
        /// <param name="isFireAndForget">if set to <c>true</c> [is fire and forget].</param>
        /// <param name="isOnSelect">if set to <c>true</c> [is on select].</param>
        /// <returns>
        /// instance for aggregation handling
        /// </returns>
        /// <exception cref="ExprValidationException">
        /// Into-table requires at least one aggregation function
        /// or
        /// The ' + funcname + ' function may not occur in the where-clause or having-clause of a statement with aggregations as 'previous' does not provide remove stream data; Use the 'first','last','window' or 'count' aggregation functions instead
        /// or
        /// Invalid into-table clause: Failed to find table by name ' + intoTableSpec.Name + '
        /// </exception>
        /// <exception cref="EPException">Failed to obtain hook for  + HookType.INTERNAL_AGGLOCALLEVEL</exception>
        /// <throws>com.espertech.esper.epl.expression.core.ExprValidationException if validation fails</throws>
        public static AggregationServiceFactoryDesc GetService(
            IList <ExprAggregateNode> selectAggregateExprNodes,
            IDictionary <ExprNode, string> selectClauseNamedNodes,
            IList <ExprDeclaredNode> declaredExpressions,
            ExprNode[] groupByNodes,
            IList <ExprAggregateNode> havingAggregateExprNodes,
            IList <ExprAggregateNode> orderByAggregateExprNodes,
            IList <ExprAggregateNodeGroupKey> groupKeyExpressions,
            bool hasGroupByClause,
            Attribute[] annotations,
            VariableService variableService,
            bool isJoin,
            bool isDisallowNoReclaim,
            ExprNode whereClause,
            ExprNode havingClause,
            AggregationServiceFactoryService factoryService,
            EventType[] typesPerStream,
            MethodResolutionService methodResolutionService,
            AggregationGroupByRollupDesc groupByRollupDesc,
            string optionalContextName,
            IntoTableSpec intoTableSpec,
            TableService tableService,
            bool isUnidirectional,
            bool isFireAndForget,
            bool isOnSelect)
        {
            // No aggregates used, we do not need this service
            if ((selectAggregateExprNodes.IsEmpty()) && (havingAggregateExprNodes.IsEmpty()))
            {
                if (intoTableSpec != null)
                {
                    throw new ExprValidationException("Into-table requires at least one aggregation function");
                }

                return(new AggregationServiceFactoryDesc(
                           factoryService.GetNullAggregationService(),
                           Collections.GetEmptyList <AggregationServiceAggExpressionDesc>(),
                           Collections.GetEmptyList <ExprAggregateNodeGroupKey>()));
            }

            // Validate the absence of "prev" function in where-clause:
            // Since the "previous" function does not post remove stream results, disallow when used with aggregations.
            if ((whereClause != null) || (havingClause != null))
            {
                var visitor = new ExprNodePreviousVisitorWParent();
                if (whereClause != null)
                {
                    whereClause.Accept(visitor);
                }
                if (havingClause != null)
                {
                    havingClause.Accept(visitor);
                }
                if ((visitor.Previous != null) && (!visitor.Previous.IsEmpty()))
                {
                    string funcname = visitor.Previous[0].Second.PreviousType.ToString().ToLower();
                    throw new ExprValidationException("The '" + funcname + "' function may not occur in the where-clause or having-clause of a statement with aggregations as 'previous' does not provide remove stream data; Use the 'first','last','window' or 'count' aggregation functions instead");
                }
            }

            // Compile a map of aggregation nodes and equivalent-to aggregation nodes.
            // Equivalent-to functions are for example "select sum(a*b), 5*sum(a*b)".
            // Reducing the total number of aggregation functions.
            IList <AggregationServiceAggExpressionDesc> aggregations = new List <AggregationServiceAggExpressionDesc>();

            foreach (var selectAggNode in selectAggregateExprNodes)
            {
                AddEquivalent(selectAggNode, aggregations);
            }
            foreach (var havingAggNode in havingAggregateExprNodes)
            {
                AddEquivalent(havingAggNode, aggregations);
            }
            foreach (var orderByAggNode in orderByAggregateExprNodes)
            {
                AddEquivalent(orderByAggNode, aggregations);
            }

            // Construct a list of evaluation node for the aggregation functions (regular agg).
            // For example "sum(2 * 3)" would make the sum an evaluation node.
            IList <ExprEvaluator> methodAggEvaluatorsList = new List <ExprEvaluator>();

            foreach (var aggregation in aggregations)
            {
                var aggregateNode = aggregation.AggregationNode;
                if (!aggregateNode.Factory.IsAccessAggregation)
                {
                    var evaluator = aggregateNode.Factory.GetMethodAggregationEvaluator(
                        typesPerStream.Length > 1, typesPerStream);
                    methodAggEvaluatorsList.Add(evaluator);
                }
            }

            // determine local group-by, report when hook provided
            AggregationGroupByLocalGroupDesc localGroupDesc = AnalyzeLocalGroupBy(aggregations, groupByNodes, groupByRollupDesc, intoTableSpec);

            // determine binding
            if (intoTableSpec != null)
            {
                // obtain metadata
                var metadata = tableService.GetTableMetadata(intoTableSpec.Name);
                if (metadata == null)
                {
                    throw new ExprValidationException("Invalid into-table clause: Failed to find table by name '" + intoTableSpec.Name + "'");
                }

                EPLValidationUtil.ValidateContextName(true, intoTableSpec.Name, metadata.ContextName, optionalContextName, false);

                // validate group keys
                var groupByTypes = ExprNodeUtility.GetExprResultTypes(groupByNodes);
                ExprTableNodeUtil.ValidateExpressions(intoTableSpec.Name, groupByTypes, "group-by", groupByNodes,
                                                      metadata.KeyTypes, "group-by");

                // determine how this binds to existing aggregations, assign column numbers
                var bindingMatchResult = MatchBindingsAssignColumnNumbers(intoTableSpec, metadata, aggregations, selectClauseNamedNodes, methodAggEvaluatorsList, declaredExpressions);

                // return factory
                AggregationServiceFactory aggregationServiceFactory;
                if (!hasGroupByClause)
                {
                    aggregationServiceFactory = factoryService.GetNoGroupWBinding(bindingMatchResult.Accessors, isJoin, bindingMatchResult.MethodPairs, intoTableSpec.Name, bindingMatchResult.TargetStates, bindingMatchResult.AccessStateExpr, bindingMatchResult.Agents);
                }
                else
                {
                    aggregationServiceFactory = factoryService.GetGroupWBinding(metadata, bindingMatchResult.MethodPairs, bindingMatchResult.Accessors, isJoin, intoTableSpec, bindingMatchResult.TargetStates, bindingMatchResult.AccessStateExpr, bindingMatchResult.Agents, groupByRollupDesc);
                }
                return(new AggregationServiceFactoryDesc(aggregationServiceFactory, aggregations, groupKeyExpressions));
            }

            // Assign a column number to each aggregation node. The regular aggregation goes first followed by access-aggregation.
            var columnNumber = 0;

            foreach (var entry in aggregations)
            {
                if (!entry.Factory.IsAccessAggregation)
                {
                    entry.ColumnNum = columnNumber++;
                }
            }
            foreach (var entry in aggregations)
            {
                if (entry.Factory.IsAccessAggregation)
                {
                    entry.ColumnNum = columnNumber++;
                }
            }

            // determine method aggregation factories and evaluators(non-access)
            ExprEvaluator[] methodAggEvaluators = methodAggEvaluatorsList.ToArray();
            var             methodAggFactories  = new AggregationMethodFactory[methodAggEvaluators.Length];
            var             count = 0;

            foreach (var aggregation in aggregations)
            {
                var aggregateNode = aggregation.AggregationNode;
                if (!aggregateNode.Factory.IsAccessAggregation)
                {
                    methodAggFactories[count] = aggregateNode.Factory;
                    count++;
                }
            }

            // handle access aggregations
            var multiFunctionAggPlan = AggregationMultiFunctionAnalysisHelper.AnalyzeAccessAggregations(aggregations);
            var accessorPairs        = multiFunctionAggPlan.AccessorPairs;
            var accessAggregations   = multiFunctionAggPlan.StateFactories;

            AggregationServiceFactory serviceFactory;

            // analyze local group by
            AggregationLocalGroupByPlan localGroupByPlan = null;

            if (localGroupDesc != null)
            {
                localGroupByPlan = AggregationGroupByLocalGroupByAnalyzer.Analyze(methodAggEvaluators, methodAggFactories, accessAggregations, localGroupDesc, groupByNodes, accessorPairs);
                try {
                    AggregationLocalLevelHook hook = (AggregationLocalLevelHook)TypeHelper.GetAnnotationHook(annotations, HookType.INTERNAL_AGGLOCALLEVEL, typeof(AggregationLocalLevelHook), null);
                    if (hook != null)
                    {
                        hook.Planned(localGroupDesc, localGroupByPlan);
                    }
                }
                catch (ExprValidationException e) {
                    throw new EPException("Failed to obtain hook for " + HookType.INTERNAL_AGGLOCALLEVEL);
                }
            }

            // Handle without a group-by clause: we group all into the same pot
            if (!hasGroupByClause)
            {
                if (localGroupByPlan != null)
                {
                    var groupKeyBinding = methodResolutionService.GetGroupKeyBinding(localGroupByPlan);
                    serviceFactory = factoryService.GetNoGroupLocalGroupBy(isJoin, localGroupByPlan, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                }
                else if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0))
                {
                    serviceFactory = factoryService.GetNoGroupNoAccess(methodAggEvaluators, methodAggFactories, isUnidirectional, isFireAndForget, isOnSelect);
                }
                else if ((methodAggEvaluators.Length == 0) && (accessorPairs.Length > 0))
                {
                    serviceFactory = factoryService.GetNoGroupAccessOnly(accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect);
                }
                else
                {
                    serviceFactory = factoryService.GetNoGroupAccessMixed(methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect);
                }
            }
            else
            {
                var hasNoReclaim          = HintEnum.DISABLE_RECLAIM_GROUP.GetHint(annotations) != null;
                var reclaimGroupAged      = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations);
                var reclaimGroupFrequency = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations);
                if (localGroupByPlan != null)
                {
                    var groupKeyBinding = methodResolutionService.GetGroupKeyBinding(localGroupByPlan);
                    serviceFactory = factoryService.GetGroupLocalGroupBy(isJoin, localGroupByPlan, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                }
                else
                {
                    var groupKeyBinding = methodResolutionService.GetGroupKeyBinding(groupByNodes, groupByRollupDesc);
                    if (!isDisallowNoReclaim && hasNoReclaim)
                    {
                        if (groupByRollupDesc != null)
                        {
                            throw GetRollupReclaimEx();
                        }
                        if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0))
                        {
                            serviceFactory = factoryService.GetGroupedNoReclaimNoAccess(methodAggEvaluators, methodAggFactories, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                        else if ((methodAggEvaluators.Length == 0) && (accessorPairs.Length > 0))
                        {
                            serviceFactory = factoryService.GetGroupNoReclaimAccessOnly(accessorPairs, accessAggregations, groupKeyBinding, isJoin, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                        else
                        {
                            serviceFactory = factoryService.GetGroupNoReclaimMixed(methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                    }
                    else if (!isDisallowNoReclaim && reclaimGroupAged != null)
                    {
                        if (groupByRollupDesc != null)
                        {
                            throw GetRollupReclaimEx();
                        }
                        serviceFactory = factoryService.GetGroupReclaimAged(methodAggEvaluators, methodAggFactories, reclaimGroupAged, reclaimGroupFrequency, variableService, accessorPairs, accessAggregations, isJoin, groupKeyBinding, optionalContextName, isUnidirectional, isFireAndForget, isOnSelect);
                    }
                    else if (groupByRollupDesc != null)
                    {
                        serviceFactory = factoryService.GetGroupReclaimMixableRollup(methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupKeyBinding, groupByRollupDesc, isUnidirectional, isFireAndForget, isOnSelect);
                    }
                    else
                    {
                        if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0))
                        {
                            serviceFactory = factoryService.GetGroupReclaimNoAccess(methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                        else
                        {
                            serviceFactory = factoryService.GetGroupReclaimMixable(methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                    }
                }
            }

            return(new AggregationServiceFactoryDesc(serviceFactory, aggregations, groupKeyExpressions));
        }
Ejemplo n.º 16
0
        public static EPStatementStartMethodSelectDesc Prepare(
            StatementSpecCompiled statementSpec,
            EPServicesContext services,
            StatementContext statementContext,
            bool recoveringResilient,
            AgentInstanceContext defaultAgentInstanceContext,
            bool queryPlanLogging,
            ViewableActivatorFactory optionalViewableActivatorFactory,
            OutputProcessViewCallback optionalOutputProcessViewCallback,
            SelectExprProcessorDeliveryCallback selectExprProcessorDeliveryCallback)
        {
            // define stop and destroy
            var stopCallbacks    = new List <StopCallback>();
            var destroyCallbacks = new EPStatementDestroyCallbackList();

            // determine context
            var contextName             = statementSpec.OptionalContextName;
            var contextPropertyRegistry = (contextName != null) ? services.ContextManagementService.GetContextDescriptor(contextName).ContextPropertyRegistry : null;

            // Determine stream names for each stream - some streams may not have a name given
            var streamNames = EPStatementStartMethodHelperUtil.DetermineStreamNames(statementSpec.StreamSpecs);
            var numStreams  = streamNames.Length;

            if (numStreams == 0)
            {
                throw new ExprValidationException("The from-clause is required but has not been specified");
            }
            var isJoin     = statementSpec.StreamSpecs.Length > 1;
            var hasContext = statementSpec.OptionalContextName != null;

            // First we create streams for subselects, if there are any
            var subSelectStreamDesc = EPStatementStartMethodHelperSubselect.CreateSubSelectActivation(services, statementSpec, statementContext, destroyCallbacks);

            // Create streams and views
            var eventStreamParentViewableActivators = new ViewableActivator[numStreams];
            var unmaterializedViewChain             = new ViewFactoryChain[numStreams];
            var eventTypeNames           = new string[numStreams];
            var isNamedWindow            = new bool[numStreams];
            var historicalEventViewables = new HistoricalEventViewable[numStreams];

            // verify for joins that required views are present
            var joinAnalysisResult   = VerifyJoinViews(statementSpec, statementContext.NamedWindowMgmtService, defaultAgentInstanceContext);
            var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);

            for (var i = 0; i < statementSpec.StreamSpecs.Length; i++)
            {
                var streamSpec = statementSpec.StreamSpecs[i];

                var isCanIterateUnbound = streamSpec.ViewSpecs.Length == 0 &&
                                          (services.ConfigSnapshot.EngineDefaults.ViewResourcesConfig.IsIterableUnbound ||
                                           AnnotationUtil.FindAttribute(statementSpec.Annotations, typeof(IterableUnboundAttribute)) != null);

                // Create view factories and parent view based on a filter specification
                if (streamSpec is FilterStreamSpecCompiled)
                {
                    var filterStreamSpec = (FilterStreamSpecCompiled)streamSpec;
                    eventTypeNames[i] = filterStreamSpec.FilterSpec.FilterForEventTypeName;

                    // Since only for non-joins we get the existing stream's lock and try to reuse it's views
                    var filterSubselectSameStream = EPStatementStartMethodHelperUtil.DetermineSubquerySameStream(statementSpec, filterStreamSpec);

                    // create activator
                    ViewableActivator activatorDeactivator;
                    if (optionalViewableActivatorFactory != null)
                    {
                        activatorDeactivator = optionalViewableActivatorFactory.CreateActivatorSimple(filterStreamSpec);
                        if (activatorDeactivator == null)
                        {
                            throw new IllegalStateException("Viewable activate is null for " + filterStreamSpec.FilterSpec.FilterForEventType.Name);
                        }
                    }
                    else
                    {
                        if (!hasContext)
                        {
                            activatorDeactivator = services.ViewableActivatorFactory.CreateStreamReuseView(services, statementContext, statementSpec, filterStreamSpec, isJoin, evaluatorContextStmt, filterSubselectSameStream, i, isCanIterateUnbound);
                        }
                        else
                        {
                            InstrumentationAgent instrumentationAgentFilter = null;
                            if (InstrumentationHelper.ENABLED)
                            {
                                var eventTypeName = filterStreamSpec.FilterSpec.FilterForEventType.Name;
                                var streamNumber  = i;
                                instrumentationAgentFilter = new ProxyInstrumentationAgent()
                                {
                                    ProcIndicateQ = () => {
                                        InstrumentationHelper.Get().QFilterActivationStream(eventTypeName, streamNumber);
                                    },
                                    ProcIndicateA = () => {
                                        InstrumentationHelper.Get().AFilterActivationStream();
                                    },
                                };
                            }

                            activatorDeactivator = services.ViewableActivatorFactory.CreateFilterProxy(services, filterStreamSpec.FilterSpec, statementSpec.Annotations, false, instrumentationAgentFilter, isCanIterateUnbound, i);
                        }
                    }
                    eventStreamParentViewableActivators[i] = activatorDeactivator;

                    var resultEventType = filterStreamSpec.FilterSpec.ResultEventType;
                    unmaterializedViewChain[i] = services.ViewService.CreateFactories(i, resultEventType, streamSpec.ViewSpecs, streamSpec.Options, statementContext, false, -1);
                }
                // Create view factories and parent view based on a pattern expression
                else if (streamSpec is PatternStreamSpecCompiled)
                {
                    var patternStreamSpec = (PatternStreamSpecCompiled)streamSpec;
                    var usedByChildViews  = streamSpec.ViewSpecs.Length > 0 || (statementSpec.InsertIntoDesc != null);
                    var patternTypeName   = statementContext.StatementId + "_pattern_" + i;
                    var eventType         = services.EventAdapterService.CreateSemiAnonymousMapType(patternTypeName, patternStreamSpec.TaggedEventTypes, patternStreamSpec.ArrayEventTypes, usedByChildViews);
                    unmaterializedViewChain[i] = services.ViewService.CreateFactories(i, eventType, streamSpec.ViewSpecs, streamSpec.Options, statementContext, false, -1);

                    var rootFactoryNode = services.PatternNodeFactory.MakeRootNode(patternStreamSpec.EvalFactoryNode);
                    var patternContext  = statementContext.PatternContextFactory.CreateContext(statementContext, i, rootFactoryNode, patternStreamSpec.MatchedEventMapMeta, true);

                    // create activator
                    var patternActivator = services.ViewableActivatorFactory.CreatePattern(patternContext, rootFactoryNode, eventType, EPStatementStartMethodHelperUtil.IsConsumingFilters(patternStreamSpec.EvalFactoryNode), patternStreamSpec.IsSuppressSameEventMatches, patternStreamSpec.IsDiscardPartialsOnMatch, isCanIterateUnbound);
                    eventStreamParentViewableActivators[i] = patternActivator;
                }
                // Create view factories and parent view based on a database SQL statement
                else if (streamSpec is DBStatementStreamSpec)
                {
                    ValidateNoViews(streamSpec, "Historical data");
                    var sqlStreamSpec                  = (DBStatementStreamSpec)streamSpec;
                    var typeConversionHook             = (SQLColumnTypeConversion)TypeHelper.GetAnnotationHook(statementSpec.Annotations, HookType.SQLCOL, typeof(SQLColumnTypeConversion), statementContext.MethodResolutionService);
                    var outputRowConversionHook        = (SQLOutputRowConversion)TypeHelper.GetAnnotationHook(statementSpec.Annotations, HookType.SQLROW, typeof(SQLOutputRowConversion), statementContext.MethodResolutionService);
                    var epStatementAgentInstanceHandle = defaultAgentInstanceContext.EpStatementAgentInstanceHandle;
                    var historicalEventViewable        = DatabasePollingViewableFactory.CreateDBStatementView(
                        statementContext.StatementId, i, sqlStreamSpec,
                        services.DatabaseRefService,
                        services.EventAdapterService,
                        epStatementAgentInstanceHandle,
                        statementContext.Annotations,
                        typeConversionHook,
                        outputRowConversionHook,
                        statementContext.ConfigSnapshot.EngineDefaults.LoggingConfig.IsEnableADO,
                        services.DataCacheFactory,
                        statementContext);
                    historicalEventViewables[i]            = historicalEventViewable;
                    unmaterializedViewChain[i]             = ViewFactoryChain.FromTypeNoViews(historicalEventViewable.EventType);
                    eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.MakeHistorical(historicalEventViewable);
                    stopCallbacks.Add(historicalEventViewable);
                }
                else if (streamSpec is MethodStreamSpec)
                {
                    ValidateNoViews(streamSpec, "Method data");
                    var methodStreamSpec = (MethodStreamSpec)streamSpec;
                    var epStatementAgentInstanceHandle = defaultAgentInstanceContext.EpStatementAgentInstanceHandle;
                    var historicalEventViewable        = MethodPollingViewableFactory.CreatePollMethodView(
                        i, methodStreamSpec, services.EventAdapterService, epStatementAgentInstanceHandle,
                        statementContext.MethodResolutionService, services.EngineImportService,
                        statementContext.SchedulingService, statementContext.ScheduleBucket, evaluatorContextStmt,
                        statementContext.VariableService, statementContext.ContextName, services.DataCacheFactory,
                        statementContext);
                    historicalEventViewables[i]            = historicalEventViewable;
                    unmaterializedViewChain[i]             = ViewFactoryChain.FromTypeNoViews(historicalEventViewable.EventType);
                    eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.MakeHistorical(historicalEventViewable);
                    stopCallbacks.Add(historicalEventViewable);
                }
                else if (streamSpec is TableQueryStreamSpec)
                {
                    ValidateNoViews(streamSpec, "Table data");
                    var tableStreamSpec = (TableQueryStreamSpec)streamSpec;
                    if (isJoin && tableStreamSpec.FilterExpressions.Count > 0)
                    {
                        throw new ExprValidationException("Joins with tables do not allow table filter expressions, please add table filters to the where-clause instead");
                    }
                    var             metadata         = services.TableService.GetTableMetadata(tableStreamSpec.TableName);
                    ExprEvaluator[] tableFilterEvals = null;
                    if (tableStreamSpec.FilterExpressions.Count > 0)
                    {
                        tableFilterEvals = ExprNodeUtility.GetEvaluators(tableStreamSpec.FilterExpressions);
                    }
                    EPLValidationUtil.ValidateContextName(true, metadata.TableName, metadata.ContextName, statementSpec.OptionalContextName, false);
                    eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.CreateTable(metadata, tableFilterEvals);
                    unmaterializedViewChain[i]             = ViewFactoryChain.FromTypeNoViews(metadata.InternalEventType);
                    eventTypeNames[i] = tableStreamSpec.TableName;
                    joinAnalysisResult.SetTablesForStream(i, metadata);
                    if (tableStreamSpec.Options.IsUnidirectional)
                    {
                        throw new ExprValidationException("Tables cannot be marked as unidirectional");
                    }
                    if (tableStreamSpec.Options.IsRetainIntersection || tableStreamSpec.Options.IsRetainUnion)
                    {
                        throw new ExprValidationException("Tables cannot be marked with retain");
                    }
                    if (isJoin)
                    {
                        destroyCallbacks.AddCallback(new EPStatementDestroyCallbackTableIdxRef(services.TableService, metadata, statementContext.StatementName));
                    }
                    services.StatementVariableRefService.AddReferences(statementContext.StatementName, metadata.TableName);
                }
                else if (streamSpec is NamedWindowConsumerStreamSpec)
                {
                    var namedSpec       = (NamedWindowConsumerStreamSpec)streamSpec;
                    var processor       = services.NamedWindowMgmtService.GetProcessor(namedSpec.WindowName);
                    var namedWindowType = processor.TailView.EventType;
                    if (namedSpec.OptPropertyEvaluator != null)
                    {
                        namedWindowType = namedSpec.OptPropertyEvaluator.FragmentEventType;
                    }

                    eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.CreateNamedWindow(processor, namedSpec, statementContext);
                    services.NamedWindowConsumerMgmtService.AddConsumer(statementContext, namedSpec);
                    unmaterializedViewChain[i] = services.ViewService.CreateFactories(i, namedWindowType, namedSpec.ViewSpecs, namedSpec.Options, statementContext, false, -1);
                    joinAnalysisResult.SetNamedWindow(i);
                    eventTypeNames[i] = namedSpec.WindowName;
                    isNamedWindow[i]  = true;

                    // Consumers to named windows cannot declare a data window view onto the named window to avoid duplicate remove streams
                    EPStatementStartMethodHelperValidate.ValidateNoDataWindowOnNamedWindow(unmaterializedViewChain[i].FactoryChain);
                }
                else
                {
                    throw new ExprValidationException("Unknown stream specification type: " + streamSpec);
                }
            }

            // handle match-recognize pattern
            if (statementSpec.MatchRecognizeSpec != null)
            {
                if (isJoin)
                {
                    throw new ExprValidationException("Joins are not allowed when using match-recognize");
                }
                if (joinAnalysisResult.TablesPerStream[0] != null)
                {
                    throw new ExprValidationException("Tables cannot be used with match-recognize");
                }
                var isUnbound = (unmaterializedViewChain[0].FactoryChain.IsEmpty()) && (!(statementSpec.StreamSpecs[0] is NamedWindowConsumerStreamSpec));
                var factoryX  = services.RegexHandlerFactory.MakeViewFactory(unmaterializedViewChain[0], statementSpec.MatchRecognizeSpec, defaultAgentInstanceContext, isUnbound, statementSpec.Annotations, services.ConfigSnapshot.EngineDefaults.MatchRecognizeConfig);
                unmaterializedViewChain[0].FactoryChain.Add(factoryX);

                EPStatementStartMethodHelperAssignExpr.AssignAggregations(factoryX.AggregationService, factoryX.AggregationExpressions);
            }

            // Obtain event types from view factory chains
            var streamEventTypes = new EventType[statementSpec.StreamSpecs.Length];

            for (var i = 0; i < unmaterializedViewChain.Length; i++)
            {
                streamEventTypes[i] = unmaterializedViewChain[i].EventType;
            }

            // Add uniqueness information useful for joins
            joinAnalysisResult.AddUniquenessInfo(unmaterializedViewChain, statementSpec.Annotations);

            // Validate sub-select views
            var subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.PlanSubSelect(services, statementContext, queryPlanLogging, subSelectStreamDesc, streamNames, streamEventTypes, eventTypeNames, statementSpec.DeclaredExpressions, contextPropertyRegistry);

            // Construct type information per stream
            StreamTypeService typeService      = new StreamTypeServiceImpl(streamEventTypes, streamNames, EPStatementStartMethodHelperUtil.GetHasIStreamOnly(isNamedWindow, unmaterializedViewChain), services.EngineURI, false);
            var viewResourceDelegateUnverified = new ViewResourceDelegateUnverified();

            // Validate views that require validation, specifically streams that don't have
            // sub-views such as DB SQL joins
            var historicalViewableDesc = new HistoricalViewableDesc(numStreams);

            for (var stream = 0; stream < historicalEventViewables.Length; stream++)
            {
                var historicalEventViewable = historicalEventViewables[stream];
                if (historicalEventViewable == null)
                {
                    continue;
                }
                historicalEventViewable.Validate(
                    services.EngineImportService,
                    typeService,
                    statementContext.MethodResolutionService,
                    statementContext.TimeProvider,
                    statementContext.VariableService, statementContext.TableService,
                    statementContext.ScriptingService, evaluatorContextStmt,
                    services.ConfigSnapshot, services.SchedulingService, services.EngineURI,
                    statementSpec.SqlParameters,
                    statementContext.EventAdapterService, statementContext);
                historicalViewableDesc.SetHistorical(stream, historicalEventViewable.RequiredStreams);
                if (historicalEventViewable.RequiredStreams.Contains(stream))
                {
                    throw new ExprValidationException("Parameters for historical stream " + stream + " indicate that the stream is subordinate to itself as stream parameters originate in the same stream");
                }
            }

            // unidirectional is not supported with into-table
            if (joinAnalysisResult.IsUnidirectional && statementSpec.IntoTableSpec != null)
            {
                throw new ExprValidationException("Into-table does not allow unidirectional joins");
            }

            // Construct a processor for results posted by views and joins, which takes care of aggregation if required.
            // May return null if we don't need to post-process results posted by views or joins.
            var resultSetProcessorPrototypeDesc = ResultSetProcessorFactoryFactory.GetProcessorPrototype(
                statementSpec, statementContext, typeService, viewResourceDelegateUnverified, joinAnalysisResult.UnidirectionalInd, true, contextPropertyRegistry, selectExprProcessorDeliveryCallback, services.ConfigSnapshot, services.ResultSetProcessorHelperFactory, false, false);

            // Validate where-clause filter tree, outer join clause and output limit expression
            EPStatementStartMethodHelperValidate.ValidateNodes(statementSpec, statementContext, typeService, viewResourceDelegateUnverified);

            // Handle 'prior' function nodes in terms of view requirements
            var viewResourceDelegateVerified = EPStatementStartMethodHelperViewResources.VerifyPreviousAndPriorRequirements(unmaterializedViewChain, viewResourceDelegateUnverified);

            // handle join
            JoinSetComposerPrototype joinSetComposerPrototype = null;

            if (numStreams > 1)
            {
                var selectsRemoveStream =
                    statementSpec.SelectStreamSelectorEnum.IsSelectsRStream() ||
                    statementSpec.OutputLimitSpec != null;
                var hasAggregations = !resultSetProcessorPrototypeDesc.AggregationServiceFactoryDesc.Expressions.IsEmpty();
                joinSetComposerPrototype = JoinSetComposerPrototypeFactory.MakeComposerPrototype(
                    statementContext.StatementName, statementContext.StatementId,
                    statementSpec.OuterJoinDescList, statementSpec.FilterRootNode, typeService.EventTypes, streamNames,
                    joinAnalysisResult, queryPlanLogging, statementContext, historicalViewableDesc, defaultAgentInstanceContext,
                    selectsRemoveStream, hasAggregations, services.TableService, false, services.EventTableIndexService.AllowInitIndex(recoveringResilient));
            }

            // obtain factory for output limiting
            var outputViewFactory = OutputProcessViewFactoryFactory.Make(statementSpec, services.InternalEventRouter, statementContext, resultSetProcessorPrototypeDesc.ResultSetProcessorFactory.ResultEventType, optionalOutputProcessViewCallback, services.TableService, resultSetProcessorPrototypeDesc.ResultSetProcessorFactory.ResultSetProcessorType, services.ResultSetProcessorHelperFactory, services.StatementVariableRefService);

            // Factory for statement-context instances
            var factory = new StatementAgentInstanceFactorySelect(
                numStreams, eventStreamParentViewableActivators,
                statementContext, statementSpec, services,
                typeService, unmaterializedViewChain, resultSetProcessorPrototypeDesc, joinAnalysisResult, recoveringResilient,
                joinSetComposerPrototype, subSelectStrategyCollection, viewResourceDelegateVerified, outputViewFactory);

            EPStatementStopMethod stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks);

            return(new EPStatementStartMethodSelectDesc(factory, subSelectStrategyCollection, viewResourceDelegateUnverified, resultSetProcessorPrototypeDesc, stopMethod, destroyCallbacks));
        }
Ejemplo n.º 17
0
        private static void HandleSubselectSelectClauses(
            int subselectStreamNumber,
            StatementContext statementContext,
            ExprSubselectNode subselect,
            EventType outerEventType,
            string outerEventTypeName,
            string outerStreamName,
            IDictionary <string, Pair <EventType, string> > taggedEventTypes,
            IDictionary <string, Pair <EventType, string> > arrayEventTypes)
        {
            var statementSpec    = subselect.StatementSpecCompiled;
            var filterStreamSpec = statementSpec.StreamSpecs[0];

            ViewFactoryChain viewFactoryChain;
            string           subselecteventTypeName = null;

            // construct view factory chain
            try {
                if (statementSpec.StreamSpecs[0] is FilterStreamSpecCompiled)
                {
                    var filterStreamSpecCompiled = (FilterStreamSpecCompiled)statementSpec.StreamSpecs[0];
                    subselecteventTypeName = filterStreamSpecCompiled.FilterSpec.FilterForEventTypeName;

                    // A child view is required to limit the stream
                    if (filterStreamSpec.ViewSpecs.Length == 0)
                    {
                        throw new ExprValidationException("Subqueries require one or more views to limit the stream, consider declaring a length or time window");
                    }

                    // Register filter, create view factories
                    viewFactoryChain       = statementContext.ViewService.CreateFactories(subselectStreamNumber, filterStreamSpecCompiled.FilterSpec.ResultEventType, filterStreamSpec.ViewSpecs, filterStreamSpec.Options, statementContext);
                    subselect.RawEventType = viewFactoryChain.EventType;
                }
                else
                {
                    var namedSpec = (NamedWindowConsumerStreamSpec)statementSpec.StreamSpecs[0];
                    var processor = statementContext.NamedWindowService.GetProcessor(namedSpec.WindowName);
                    viewFactoryChain       = statementContext.ViewService.CreateFactories(0, processor.NamedWindowType, namedSpec.ViewSpecs, namedSpec.Options, statementContext);
                    subselecteventTypeName = namedSpec.WindowName;
                    EPLValidationUtil.ValidateContextName(false, processor.NamedWindowName, processor.ContextName, statementContext.ContextName, true);
                }
            }
            catch (ViewProcessingException ex) {
                throw new ExprValidationException("Error validating subexpression: " + ex.Message, ex);
            }

            // the final event type
            var eventType = viewFactoryChain.EventType;

            // determine a stream name unless one was supplied
            var subexpressionStreamName = filterStreamSpec.OptionalStreamName;

            if (subexpressionStreamName == null)
            {
                subexpressionStreamName = "$subselect_" + subselectStreamNumber;
            }

            // Named windows don't allow data views
            if (filterStreamSpec is NamedWindowConsumerStreamSpec)
            {
                EPStatementStartMethodHelperValidate.ValidateNoDataWindowOnNamedWindow(viewFactoryChain.FactoryChain);
            }

            // Streams event types are the original stream types with the stream zero the subselect stream
            var namesAndTypes = new LinkedHashMap <string, Pair <EventType, string> >();

            namesAndTypes.Put(subexpressionStreamName, new Pair <EventType, string>(eventType, subselecteventTypeName));
            namesAndTypes.Put(outerStreamName, new Pair <EventType, string>(outerEventType, outerEventTypeName));
            if (taggedEventTypes != null)
            {
                foreach (KeyValuePair <string, Pair <EventType, string> > entry in taggedEventTypes)
                {
                    namesAndTypes.Put(entry.Key, new Pair <EventType, string>(entry.Value.First, entry.Value.Second));
                }
            }
            if (arrayEventTypes != null)
            {
                foreach (KeyValuePair <string, Pair <EventType, string> > entry in arrayEventTypes)
                {
                    namesAndTypes.Put(entry.Key, new Pair <EventType, string>(entry.Value.First, entry.Value.Second));
                }
            }
            StreamTypeService subselectTypeService = new StreamTypeServiceImpl(namesAndTypes, statementContext.EngineURI, true, true);
            var viewResourceDelegateSubselect      = new ViewResourceDelegateUnverified();

            subselect.FilterSubqueryStreamTypes = subselectTypeService;

            // Validate select expression
            var selectClauseSpec = subselect.StatementSpecCompiled.SelectClauseSpec;

            if (selectClauseSpec.SelectExprList.Length > 0)
            {
                if (selectClauseSpec.SelectExprList.Length > 1)
                {
                    throw new ExprValidationException("Subquery multi-column select is not allowed in this context.");
                }

                var element = selectClauseSpec.SelectExprList[0];
                if (element is SelectClauseExprCompiledSpec)
                {
                    // validate
                    var compiled             = (SelectClauseExprCompiledSpec)element;
                    var selectExpression     = compiled.SelectExpression;
                    var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);
                    var validationContext    = new ExprValidationContext(
                        subselectTypeService, statementContext.MethodResolutionService, viewResourceDelegateSubselect,
                        statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService,
                        evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName,
                        statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor,
                        statementContext.ScriptingService,
                        false, false, true, false, null, false);
                    selectExpression        = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.SUBQUERYSELECT, selectExpression, validationContext);
                    subselect.SelectClause  = new ExprNode[] { selectExpression };
                    subselect.SelectAsNames = new string[] { compiled.AssignedName };

                    // handle aggregation
                    var aggExprNodes = new List <ExprAggregateNode>();
                    ExprAggregateNodeUtil.GetAggregatesBottomUp(selectExpression, aggExprNodes);
                    if (aggExprNodes.Count > 0)
                    {
                        // Other stream properties, if there is aggregation, cannot be under aggregation.
                        foreach (var aggNode in aggExprNodes)
                        {
                            var propertiesNodesAggregated = ExprNodeUtility.GetExpressionProperties(aggNode, true);
                            foreach (var pair in propertiesNodesAggregated)
                            {
                                if (pair.First != 0)
                                {
                                    throw new ExprValidationException("Subselect aggregation function cannot aggregate across correlated properties");
                                }
                            }
                        }

                        // This stream (stream 0) properties must either all be under aggregation, or all not be.
                        var propertiesNotAggregated = ExprNodeUtility.GetExpressionProperties(selectExpression, false);
                        foreach (var pair in propertiesNotAggregated)
                        {
                            if (pair.First == 0)
                            {
                                throw new ExprValidationException("Subselect properties must all be within aggregation functions");
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 18
0
        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);
        }
Ejemplo n.º 19
0
        public FAFQueryMethodIUDBaseForge(
            StatementSpecCompiled spec,
            Compilable compilable,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            this.annotations = spec.Annotations;
            this.hasTableAccess = spec.Raw.IntoTableSpec != null ||
                                  (spec.TableAccessNodes != null && spec.TableAccessNodes.Count > 0);
            if (spec.Raw.InsertIntoDesc != null &&
                services.TableCompileTimeResolver.Resolve(spec.Raw.InsertIntoDesc.EventTypeName) != null) {
                hasTableAccess = true;
            }

            if (spec.Raw.FireAndForgetSpec is FireAndForgetSpecUpdate ||
                spec.Raw.FireAndForgetSpec is FireAndForgetSpecDelete) {
                hasTableAccess |= spec.StreamSpecs[0] is TableQueryStreamSpec;
            }

            hasTableAccess |= StatementLifecycleSvcUtil.IsSubqueryWithTable(
                spec.SubselectNodes, services.TableCompileTimeResolver);

            // validate general FAF criteria
            FAFQueryMethodHelper.ValidateFAFQuery(spec);

            // obtain processor
            StreamSpecCompiled streamSpec = spec.StreamSpecs[0];
            processor = FireAndForgetProcessorForgeFactory.ValidateResolveProcessor(streamSpec);

            // obtain name and type
            string processorName = processor.NamedWindowOrTableName;
            EventType eventType = processor.EventTypeRspInputEvents;

            // determine alias
            string aliasName = processorName;
            if (streamSpec.OptionalStreamName != null) {
                aliasName = streamSpec.OptionalStreamName;
            }
            
            // activate subselect activations
            var @base = new StatementBaseInfo(compilable, spec, null, statementRawInfo, null);
            var subqueryNamedWindowConsumers = new List<NamedWindowConsumerStreamSpec>();
            var subSelectActivationDesc = SubSelectHelperActivations.CreateSubSelectActivation(
                EmptyList<FilterSpecCompiled>.Instance, subqueryNamedWindowConsumers, @base, services);
            var subselectActivation = subSelectActivationDesc.Subselects;
            _additionalForgeables.AddAll(subSelectActivationDesc.AdditionalForgeables);

            // plan subselects
            var namesPerStream = new[] {aliasName};
            var typesPerStream = new[] { processor.EventTypePublic };
            var eventTypeNames = new[] {typesPerStream[0].Name};
            SubSelectHelperForgePlan subSelectForgePlan = SubSelectHelperForgePlanner.PlanSubSelect(
                @base, subselectActivation, namesPerStream, typesPerStream, eventTypeNames, services);
            _subselectForges = subSelectForgePlan.Subselects;
            _additionalForgeables.AddAll(subSelectForgePlan.AdditionalForgeables);

            // compile filter to optimize access to named window
            StreamTypeServiceImpl typeService = new StreamTypeServiceImpl(
                new[] {eventType},
                new[] {aliasName},
                new[] {true},
                true,
                false);
            ExcludePlanHint excludePlanHint = ExcludePlanHint.GetHint(
                typeService.StreamNames,
                statementRawInfo,
                services);
            if (spec.Raw.WhereClause != null) {
                queryGraph = new QueryGraphForge(1, excludePlanHint, false);
                EPLValidationUtil.ValidateFilterWQueryGraphSafe(
                    queryGraph,
                    spec.Raw.WhereClause,
                    typeService,
                    statementRawInfo,
                    services);
            }
            else {
                queryGraph = null;
            }

            // validate expressions
            whereClause = EPStatementStartMethodHelperValidate.ValidateNodes(
                spec.Raw,
                typeService,
                null,
                statementRawInfo,
                services);

            // get executor
            InitExec(aliasName, spec, statementRawInfo, services);

            // plan table access
            tableAccessForges = ExprTableEvalHelperPlan.PlanTableAccess(spec.Raw.TableExpressions);
        }
Ejemplo n.º 20
0
        public static IList <StmtClassForgeableFactory> HandleSubselectSelectClauses(
            ExprSubselectNode subselect,
            EventType outerEventType,
            string outerEventTypeName,
            string outerStreamName,
            IDictionary <string, Pair <EventType, string> > taggedEventTypes,
            IDictionary <string, Pair <EventType, string> > arrayEventTypes,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            if (subselect.SubselectNumber == -1)
            {
                throw new IllegalStateException("Subselect is unassigned");
            }

            var statementSpec    = subselect.StatementSpecCompiled;
            var filterStreamSpec = statementSpec.StreamSpecs[0];

            IList <ViewFactoryForge> viewForges;
            string subselecteventTypeName;
            IList <StmtClassForgeableFactory> additionalForgeables;

            // construct view factory chain
            EventType eventType;

            try {
                var args = new ViewFactoryForgeArgs(
                    -1,
                    true,
                    subselect.SubselectNumber,
                    StreamSpecOptions.DEFAULT,
                    null,
                    statementRawInfo,
                    services);
                var streamSpec = statementSpec.StreamSpecs[0];

                if (streamSpec is FilterStreamSpecCompiled)
                {
                    var filterStreamSpecCompiled = (FilterStreamSpecCompiled)statementSpec.StreamSpecs[0];
                    subselecteventTypeName = filterStreamSpecCompiled.FilterSpecCompiled.FilterForEventTypeName;

                    // A child view is required to limit the stream
                    if (filterStreamSpec.ViewSpecs.Length == 0)
                    {
                        throw new ExprValidationException(
                                  "Subqueries require one or more views to limit the stream, consider declaring a length or time window");
                    }

                    ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(
                        filterStreamSpecCompiled.ViewSpecs,
                        args,
                        filterStreamSpecCompiled.FilterSpecCompiled.ResultEventType);
                    viewForges           = viewForgeDesc.Forges;
                    additionalForgeables = viewForgeDesc.MultikeyForges;
                    // Register filter, create view factories
                    eventType = viewForges.IsEmpty() ? filterStreamSpecCompiled.FilterSpecCompiled.ResultEventType : viewForges[viewForges.Count - 1].EventType;
                    subselect.RawEventType = eventType;
                }
                else if (streamSpec is NamedWindowConsumerStreamSpec)
                {
                    var namedSpec   = (NamedWindowConsumerStreamSpec)statementSpec.StreamSpecs[0];
                    var namedWindow = namedSpec.NamedWindow;
                    ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(namedSpec.ViewSpecs, args, namedWindow.EventType);
                    viewForges           = viewForgeDesc.Forges;
                    additionalForgeables = viewForgeDesc.MultikeyForges;
                    var namedWindowName = namedWindow.EventType.Name;
                    subselecteventTypeName = namedWindowName;
                    EPLValidationUtil.ValidateContextName(false, namedWindowName, namedWindow.ContextName, statementRawInfo.ContextName, true);
                    subselect.RawEventType = namedWindow.EventType;
                    eventType = namedWindow.EventType;
                }
                else if (streamSpec is TableQueryStreamSpec)
                {
                    var namedSpec = (TableQueryStreamSpec)statementSpec.StreamSpecs[0];
                    var table     = namedSpec.Table;
                    ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(namedSpec.ViewSpecs, args, table.InternalEventType);
                    viewForges           = viewForgeDesc.Forges;
                    additionalForgeables = viewForgeDesc.MultikeyForges;
                    var namedWindowName = table.TableName;
                    subselecteventTypeName = namedWindowName;
                    EPLValidationUtil.ValidateContextName(false, namedWindowName, table.OptionalContextName, statementRawInfo.ContextName, true);
                    subselect.RawEventType = table.InternalEventType;
                    eventType = table.InternalEventType;
                }
                else
                {
                    throw new IllegalStateException("Unexpected stream spec " + streamSpec);
                }
            }
            catch (ViewProcessingException ex) {
                throw new ExprValidationException("Failed to validate subexpression: " + ex.Message, ex);
            }

            // determine a stream name unless one was supplied
            var subexpressionStreamName = SubselectUtil.GetStreamName(filterStreamSpec.OptionalStreamName, subselect.SubselectNumber);

            // Named windows don't allow data views
            if (filterStreamSpec is NamedWindowConsumerStreamSpec | filterStreamSpec is TableQueryStreamSpec)
            {
                EPStatementStartMethodHelperValidate.ValidateNoDataWindowOnNamedWindow(viewForges);
            }

            // Streams event types are the original stream types with the stream zero the subselect stream
            var namesAndTypes = new LinkedHashMap <string, Pair <EventType, string> >();

            namesAndTypes.Put(subexpressionStreamName, new Pair <EventType, string>(eventType, subselecteventTypeName));
            namesAndTypes.Put(outerStreamName, new Pair <EventType, string>(outerEventType, outerEventTypeName));
            if (taggedEventTypes != null)
            {
                foreach (var entry in taggedEventTypes)
                {
                    namesAndTypes.Put(entry.Key, new Pair <EventType, string>(entry.Value.First, entry.Value.Second));
                }
            }

            if (arrayEventTypes != null)
            {
                foreach (var entry in arrayEventTypes)
                {
                    namesAndTypes.Put(entry.Key, new Pair <EventType, string>(entry.Value.First, entry.Value.Second));
                }
            }

            StreamTypeService subselectTypeService = new StreamTypeServiceImpl(namesAndTypes, true, true);
            var viewResourceDelegateSubselect      = new ViewResourceDelegateExpr();

            subselect.FilterSubqueryStreamTypes = subselectTypeService;

            // Validate select expression
            var selectClauseSpec = subselect.StatementSpecCompiled.SelectClauseCompiled;

            if (selectClauseSpec.SelectExprList.Length > 0)
            {
                if (selectClauseSpec.SelectExprList.Length > 1)
                {
                    throw new ExprValidationException("Subquery multi-column select is not allowed in this context.");
                }

                var element = selectClauseSpec.SelectExprList[0];
                if (element is SelectClauseExprCompiledSpec)
                {
                    // validate
                    var compiled          = (SelectClauseExprCompiledSpec)element;
                    var selectExpression  = compiled.SelectExpression;
                    var validationContext = new ExprValidationContextBuilder(subselectTypeService, statementRawInfo, services)
                                            .WithViewResourceDelegate(viewResourceDelegateSubselect)
                                            .WithAllowBindingConsumption(true)
                                            .WithMemberName(new ExprValidationMemberNameQualifiedSubquery(subselect.SubselectNumber))
                                            .Build();
                    selectExpression        = ExprNodeUtilityValidate.GetValidatedSubtree(ExprNodeOrigin.SUBQUERYSELECT, selectExpression, validationContext);
                    subselect.SelectClause  = new ExprNode[] { selectExpression };
                    subselect.SelectAsNames = new string[] { compiled.AssignedName };

                    // handle aggregation
                    var aggExprNodes = new List <ExprAggregateNode>();
                    ExprAggregateNodeUtil.GetAggregatesBottomUp(selectExpression, aggExprNodes);
                    if (aggExprNodes.Count > 0)
                    {
                        // Other stream properties, if there is aggregation, cannot be under aggregation.
                        foreach (var aggNode in aggExprNodes)
                        {
                            var propertiesNodesAggregated = ExprNodeUtilityQuery.GetExpressionProperties(aggNode, true);
                            foreach (var pair in propertiesNodesAggregated)
                            {
                                if (pair.First != 0)
                                {
                                    throw new ExprValidationException("Subselect aggregation function cannot aggregate across correlated properties");
                                }
                            }
                        }

                        // This stream (stream 0) properties must either all be under aggregation, or all not be.
                        var propertiesNotAggregated = ExprNodeUtilityQuery.GetExpressionProperties(selectExpression, false);
                        foreach (var pair in propertiesNotAggregated)
                        {
                            if (pair.First == 0)
                            {
                                throw new ExprValidationException("Subselect properties must all be within aggregation functions");
                            }
                        }
                    }
                }
            }

            return(additionalForgeables);
        }
Ejemplo n.º 21
0
        public override EPStatementStartResult StartInternal(EPServicesContext services, StatementContext statementContext, bool isNewStatement, bool isRecoveringStatement, bool isRecoveringResilient)
        {
            var spec = _statementSpec.CreateIndexDesc;
            var namedWindowProcessor = services.NamedWindowMgmtService.GetProcessor(spec.WindowName);
            var tableMetadata        = services.TableService.GetTableMetadata(spec.WindowName);

            if (namedWindowProcessor == null && tableMetadata == null)
            {
                throw new ExprValidationException("A named window or table by name '" + spec.WindowName + "' does not exist");
            }
            var indexedEventType = namedWindowProcessor != null ? namedWindowProcessor.NamedWindowType : tableMetadata.InternalEventType;
            var infraContextName = namedWindowProcessor != null ? namedWindowProcessor.ContextName : tableMetadata.ContextName;

            EPLValidationUtil.ValidateContextName(namedWindowProcessor == null, spec.WindowName, infraContextName, _statementSpec.OptionalContextName, true);

            // validate index
            var explicitIndexDesc = EventTableIndexUtil.ValidateCompileExplicitIndex(spec.IndexName, spec.IsUnique, spec.Columns, indexedEventType, statementContext);
            var advancedIndexDesc = explicitIndexDesc.AdvancedIndexProvisionDesc == null ? null : explicitIndexDesc.AdvancedIndexProvisionDesc.IndexDesc;
            var imk = new IndexMultiKey(spec.IsUnique, explicitIndexDesc.HashPropsAsList, explicitIndexDesc.BtreePropsAsList, advancedIndexDesc);

            // for tables we add the index to metadata
            if (tableMetadata != null)
            {
                services.TableService.ValidateAddIndex(statementContext.StatementName, tableMetadata, spec.IndexName, explicitIndexDesc, imk);
            }
            else
            {
                namedWindowProcessor.ValidateAddIndex(statementContext.StatementName, spec.IndexName, explicitIndexDesc, imk);
            }

            // allocate context factory
            Viewable viewable       = new ViewableDefaultImpl(indexedEventType);
            var      contextFactory = new StatementAgentInstanceFactoryCreateIndex(
                services, spec, viewable, namedWindowProcessor,
                tableMetadata?.TableName,
                _statementSpec.OptionalContextName,
                explicitIndexDesc);

            statementContext.StatementAgentInstanceFactory = contextFactory;

            // provide destroy method which de-registers interest in this index
            var finalTableService  = services.TableService;
            var finalStatementName = statementContext.StatementName;
            var destroyMethod      = new EPStatementDestroyCallbackList();

            if (tableMetadata != null)
            {
                destroyMethod.AddCallback(() => finalTableService.RemoveIndexReferencesStmtMayRemoveIndex(finalStatementName, tableMetadata));
            }
            else
            {
                destroyMethod.AddCallback(() => namedWindowProcessor.RemoveIndexReferencesStmtMayRemoveIndex(imk, finalStatementName));
            }

            EPStatementStopMethod stopMethod;

            if (_statementSpec.OptionalContextName != null)
            {
                var mergeView = new ContextMergeView(indexedEventType);
                var statement = new ContextManagedStatementCreateIndexDesc(_statementSpec, statementContext, mergeView, contextFactory);
                services.ContextManagementService.AddStatement(_statementSpec.OptionalContextName, statement, isRecoveringResilient);
                stopMethod = new ProxyEPStatementStopMethod(() => {});

                var contextManagementService = services.ContextManagementService;
                destroyMethod.AddCallback(() => contextManagementService.DestroyedStatement(_statementSpec.OptionalContextName, statementContext.StatementName, statementContext.StatementId));
            }
            else
            {
                var defaultAgentInstanceContext = GetDefaultAgentInstanceContext(statementContext);
                StatementAgentInstanceFactoryResult result;
                try {
                    result = contextFactory.NewContext(defaultAgentInstanceContext, isRecoveringResilient);
                }
                catch (EPException ex) {
                    if (ex.InnerException is ExprValidationException)
                    {
                        throw (ExprValidationException)ex.InnerException;
                    }
                    destroyMethod.Destroy();
                    throw;
                }
                catch (Exception)
                {
                    destroyMethod.Destroy();
                    throw;
                }
                var stopCallback = services.EpStatementFactory.MakeStopMethod(result);
                stopMethod = new ProxyEPStatementStopMethod(stopCallback.Stop);

                if (statementContext.StatementExtensionServicesContext != null && statementContext.StatementExtensionServicesContext.StmtResources != null)
                {
                    var holder = statementContext.StatementExtensionServicesContext.ExtractStatementResourceHolder(result);
                    statementContext.StatementExtensionServicesContext.StmtResources.Unpartitioned = holder;
                    statementContext.StatementExtensionServicesContext.PostProcessStart(result, isRecoveringResilient);
                }
            }

            if (tableMetadata != null)
            {
                services.StatementVariableRefService.AddReferences(statementContext.StatementName, tableMetadata.TableName);
            }
            else
            {
                services.StatementVariableRefService.AddReferences(statementContext.StatementName, namedWindowProcessor.NamedWindowType.Name);
            }

            return(new EPStatementStartResult(viewable, stopMethod, destroyMethod));
        }
Ejemplo n.º 22
0
        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);
        }
Ejemplo n.º 23
0
        private ExprDotEvalParam GetBodyAndParameter(
            EnumForgeDescFactory forgeDescFactory,
            string enumMethodUsedName,
            int parameterNum,
            ExprNode parameterNode,
            ExprValidationContext validationContext,
            DotMethodFP footprint)
        {
            // handle an expression that is a constant or other (not =>)
            if (!(parameterNode is ExprLambdaGoesNode)) {
                // no node subtree validation is required here, the chain parameter validation has taken place in ExprDotNode.validate
                // validation of parameter types has taken place in footprint matching
                return new ExprDotEvalParamExpr(parameterNum, parameterNode, parameterNode.Forge);
            }

            var goesNode = (ExprLambdaGoesNode) parameterNode;

            // Get secondary
            var lambdaDesc = forgeDescFactory.GetLambdaStreamTypesForParameter(parameterNum);
            string[] additionalStreamNames = lambdaDesc.StreamNames;
            var additionalEventTypes = lambdaDesc.Types;

            ValidateDuplicateStreamNames(validationContext.StreamTypeService.StreamNames, goesNode.GoesToNames);

            // add name and type to list of known types
            var addTypes = CollectionUtil.ArrayExpandAddElements<EventType>(
                validationContext.StreamTypeService.EventTypes, additionalEventTypes);
            var addNames = CollectionUtil.ArrayExpandAddElements<string>(
                validationContext.StreamTypeService.StreamNames, additionalStreamNames);

            var types = new StreamTypeServiceImpl(
                addTypes,
                addNames,
                new bool[addTypes.Length],
                false,
                validationContext.StreamTypeService.IsOptionalStreams);

            // validate expression body
            var filter = goesNode.ChildNodes[0];
            try {
                var filterValidationContext = new ExprValidationContext(types, validationContext);
                filter = ExprNodeUtilityValidate.GetValidatedSubtree(ExprNodeOrigin.DECLAREDEXPRBODY, filter, filterValidationContext);
            }
            catch (ExprValidationException ex) {
                throw new ExprValidationException(
                    "Failed to validate enumeration method '" + enumMethodUsedName + "' parameter " + parameterNum + ": " + ex.Message,
                    ex);
            }

            var filterForge = filter.Forge;
            var expectedType = footprint.Parameters[parameterNum].ParamType;
            // Lambda-methods don't use a specific expected return-type, so passing null for type is fine.
            EPLValidationUtil.ValidateParameterType(
                enumMethodUsedName,
                DotMethodTypeEnum.ENUM.GetTypeName(),
                false,
                expectedType,
                null,
                filterForge.EvaluationType,
                parameterNum,
                filter);

            var numStreamsIncoming = validationContext.StreamTypeService.EventTypes.Length;
            return new ExprDotEvalParamLambda(
                parameterNum,
                filter,
                filterForge,
                numStreamsIncoming,
                goesNode.GoesToNames,
                lambdaDesc);
        }
        public override EPStatementStartResult StartInternal(
            EPServicesContext services,
            StatementContext statementContext,
            bool isNewStatement,
            bool isRecoveringStatement,
            bool isRecoveringResilient)
        {
            var spec = StatementSpec.CreateIndexDesc;
            var namedWindowProcessor = services.NamedWindowService.GetProcessor(spec.WindowName);
            var tableMetadata        = services.TableService.GetTableMetadata(spec.WindowName);

            if (namedWindowProcessor == null && tableMetadata == null)
            {
                throw new ExprValidationException("A named window or table by name '" + spec.WindowName + "' does not exist");
            }
            var indexedEventType = namedWindowProcessor != null ? namedWindowProcessor.NamedWindowType : tableMetadata.InternalEventType;
            var infraContextName = namedWindowProcessor != null ? namedWindowProcessor.ContextName : tableMetadata.ContextName;

            EPLValidationUtil.ValidateContextName(namedWindowProcessor == null, spec.WindowName, infraContextName, StatementSpec.OptionalContextName, true);

            // validate index
            var validated = EventTableIndexUtil.ValidateCompileExplicitIndex(spec.IsUnique, spec.Columns, indexedEventType);
            var imk       = new IndexMultiKey(spec.IsUnique, validated.HashProps, validated.BtreeProps);

            // for tables we add the index to metadata
            if (tableMetadata != null)
            {
                services.TableService.ValidateAddIndex(statementContext.StatementName, tableMetadata, spec.IndexName, imk);
            }
            else
            {
                namedWindowProcessor.ValidateAddIndex(statementContext.StatementName, spec.IndexName, imk);
            }

            // allocate context factory
            Viewable viewable       = new ViewableDefaultImpl(indexedEventType);
            var      contextFactory = new StatementAgentInstanceFactoryCreateIndex(services, spec, viewable, namedWindowProcessor, tableMetadata == null ? null : tableMetadata.TableName);

            // provide destroy method which de-registers interest in this index
            var finalTableService  = services.TableService;
            var finalStatementName = statementContext.StatementName;
            var destroyMethod      = new EPStatementDestroyCallbackList();

            if (tableMetadata != null)
            {
                destroyMethod.AddCallback(() => finalTableService.RemoveIndexReferencesStmtMayRemoveIndex(finalStatementName, tableMetadata));
            }
            else
            {
                destroyMethod.AddCallback(() => namedWindowProcessor.RemoveIndexReferencesStmtMayRemoveIndex(imk, finalStatementName));
            }

            EPStatementStopMethod stopMethod;

            if (StatementSpec.OptionalContextName != null)
            {
                var mergeView = new ContextMergeView(indexedEventType);
                var statement = new ContextManagedStatementCreateIndexDesc(StatementSpec, statementContext, mergeView, contextFactory);
                services.ContextManagementService.AddStatement(StatementSpec.OptionalContextName, statement, isRecoveringResilient);
                stopMethod = () => {};

                var contextManagementService = services.ContextManagementService;
                destroyMethod.AddCallback(() => contextManagementService.DestroyedStatement(StatementSpec.OptionalContextName, statementContext.StatementName, statementContext.StatementId));
            }
            else
            {
                var defaultAgentInstanceContext = GetDefaultAgentInstanceContext(statementContext);
                StatementAgentInstanceFactoryCreateIndexResult result;
                try {
                    result = (StatementAgentInstanceFactoryCreateIndexResult)contextFactory.NewContext(defaultAgentInstanceContext, false);
                }
                catch (EPException ex) {
                    if (ex.InnerException is ExprValidationException)
                    {
                        throw (ExprValidationException)ex.InnerException;
                    }
                    throw;
                }
                var stopCallback = result.StopCallback;
                stopMethod = stopCallback.Invoke;
            }

            return(new EPStatementStartResult(viewable, stopMethod, destroyMethod.Destroy));
        }
Ejemplo n.º 25
0
        public StmtForgeMethodResult Make(
            string @namespace,
            string classPostfix,
            StatementCompileTimeServices services)
        {
            var spec = @base.StatementSpec.Raw.CreateIndexDesc;

            var infraName = spec.WindowName;
            var namedWindow = services.NamedWindowCompileTimeResolver.Resolve(infraName);
            var table = services.TableCompileTimeResolver.Resolve(infraName);
            if (namedWindow == null && table == null) {
                throw new ExprValidationException("A named window or table by name '" + infraName + "' does not exist");
            }

            if (namedWindow != null && table != null) {
                throw new ExprValidationException("A named window or table by name '" + infraName + "' are both found");
            }

            string infraModuleName;
            NameAccessModifier infraVisibility;
            EventType indexedEventType;
            string infraContextName;
            if (namedWindow != null) {
                infraModuleName = namedWindow.NamedWindowModuleName;
                infraVisibility = namedWindow.EventType.Metadata.AccessModifier;
                indexedEventType = namedWindow.EventType;
                infraContextName = namedWindow.ContextName;
            }
            else {
                infraModuleName = table.TableModuleName;
                infraVisibility = table.TableVisibility;
                indexedEventType = table.InternalEventType;
                infraContextName = table.OptionalContextName;

                if (!table.IsKeyed) {
                    throw new ExprValidationException(
                        "Tables without primary key column(s) do not allow creating an index");
                }
            }

            EPLValidationUtil.ValidateContextName(
                namedWindow == null,
                infraName,
                infraContextName,
                @base.StatementSpec.Raw.OptionalContextName,
                true);

            // validate index
            var explicitIndexDesc = EventTableIndexUtil.ValidateCompileExplicitIndex(
                spec.IndexName,
                spec.IsUnique,
                spec.Columns,
                indexedEventType,
                @base.StatementRawInfo,
                services);
            var advancedIndexDesc = explicitIndexDesc.AdvancedIndexProvisionDesc == null
                ? null
                : explicitIndexDesc.AdvancedIndexProvisionDesc.IndexDesc.AdvancedIndexDescRuntime;
            var imk = new IndexMultiKey(
                spec.IsUnique,
                explicitIndexDesc.HashPropsAsList,
                explicitIndexDesc.BtreePropsAsList,
                advancedIndexDesc);

            // add index as a new index to module-init
            var indexKey = new IndexCompileTimeKey(
                infraModuleName,
                infraName,
                infraVisibility,
                namedWindow != null,
                spec.IndexName,
                @base.ModuleName);
            services.IndexCompileTimeRegistry.NewIndex(indexKey, new IndexDetailForge(imk, explicitIndexDesc));

            // add index current named window information
            if (namedWindow != null) {
                namedWindow.AddIndex(spec.IndexName, @base.ModuleName, imk, explicitIndexDesc.ToRuntime());
            }
            else {
                table.AddIndex(spec.IndexName, @base.ModuleName, imk, explicitIndexDesc.ToRuntime());
            }

            var statementFieldsClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementFields), classPostfix);
            var namespaceScope = new CodegenNamespaceScope(
                @namespace, statementFieldsClassName, services.IsInstrumented);
            var fieldsForgable = new StmtClassForgableStmtFields(statementFieldsClassName, namespaceScope, 0);

            var aiFactoryProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementAIFactoryProvider),
                classPostfix);
            var forge = new StatementAgentInstanceFactoryCreateIndexForge(
                indexedEventType,
                spec.IndexName,
                @base.ModuleName,
                explicitIndexDesc,
                imk,
                namedWindow,
                table);
            var aiFactoryForgable = new StmtClassForgableAIFactoryProviderCreateIndex(
                aiFactoryProviderClassName,
                namespaceScope,
                forge);

            var selectSubscriberDescriptor = new SelectSubscriberDescriptor();
            var informationals = StatementInformationalsUtil.GetInformationals(
                @base,
                new EmptyList<FilterSpecCompiled>(),
                new EmptyList<ScheduleHandleCallbackProvider>(),
                new EmptyList<NamedWindowConsumerStreamSpec>(),
                true,
                selectSubscriberDescriptor,
                namespaceScope,
                services);
            var statementProviderClassName =
                CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementProvider), classPostfix);
            var stmtProvider = new StmtClassForgableStmtProvider(
                aiFactoryProviderClassName,
                statementProviderClassName,
                informationals,
                namespaceScope);

            IList<StmtClassForgable> forgables = new List<StmtClassForgable>();
            forgables.Add(fieldsForgable);
            forgables.Add(aiFactoryForgable);
            forgables.Add(stmtProvider);
            return new StmtForgeMethodResult(
                forgables,
                new EmptyList<FilterSpecCompiled>(),
                new EmptyList<ScheduleHandleCallbackProvider>(),
                new EmptyList<NamedWindowConsumerStreamSpec>(),
                new EmptyList<FilterSpecParamExprNodeForge>());
        }
Ejemplo n.º 26
0
        public static HistoricalEventViewableMethodForge CreateMethodStatementView(
            int stream,
            MethodStreamSpec methodStreamSpec,
            StatementBaseInfo @base,
            StatementCompileTimeServices services)
        {
            var variableMetaData = services.VariableCompileTimeResolver.Resolve(methodStreamSpec.ClassName);
            MethodPollingExecStrategyEnum strategy;
            MethodInfo methodReflection = null;
            string eventTypeNameProvidedUDFOrScript = null;
            var contextName = @base.StatementSpec.Raw.OptionalContextName;
            var classpathImportService = services.ImportServiceCompileTime;

            // see if this is a script in the from-clause
            ExprNodeScript scriptExpression = null;
            if (methodStreamSpec.ClassName == null && methodStreamSpec.MethodName != null) {
                var script = services.ScriptCompileTimeResolver.Resolve(
                    methodStreamSpec.MethodName,
                    methodStreamSpec.Expressions.Count);
                if (script != null) {
                    scriptExpression = new ExprNodeScript(
                        services.Configuration.Compiler.Scripts.DefaultDialect,
                        script,
                        methodStreamSpec.Expressions);
                }
            }

            try {
                if (scriptExpression != null) {
                    eventTypeNameProvidedUDFOrScript = scriptExpression.EventTypeNameAnnotation;
                    strategy = MethodPollingExecStrategyEnum.TARGET_SCRIPT;
                    EPLValidationUtil.ValidateSimpleGetSubtree(
                        ExprNodeOrigin.METHODINVJOIN,
                        scriptExpression,
                        null,
                        false,
                        @base.StatementRawInfo,
                        services);
                }
                else if (variableMetaData != null) {
                    var variableName = variableMetaData.VariableName;
                    if (variableMetaData.OptionalContextName != null) {
                        if (contextName == null || !contextName.Equals(variableMetaData.OptionalContextName)) {
                            throw new ExprValidationException(
                                "Variable by name '" +
                                variableMetaData.VariableName +
                                "' has been declared for context '" +
                                variableMetaData.OptionalContextName +
                                "' and can only be used within the same context");
                        }

                        strategy = MethodPollingExecStrategyEnum.TARGET_VAR_CONTEXT;
                    }
                    else {
                        if (variableMetaData.IsConstant) {
                            strategy = MethodPollingExecStrategyEnum.TARGET_CONST;
                        }
                        else {
                            strategy = MethodPollingExecStrategyEnum.TARGET_VAR;
                        }
                    }

                    methodReflection = classpathImportService.ResolveNonStaticMethodOverloadChecked(
                        variableMetaData.Type,
                        methodStreamSpec.MethodName);
                }
                else if (methodStreamSpec.ClassName == null) { // must be either UDF or script
                    Pair<Type, ImportSingleRowDesc> udf;
                    try {
                        udf = classpathImportService.ResolveSingleRow(
                            methodStreamSpec.MethodName,
                            services.ClassProvidedExtension);
                    }
                    catch (ImportException ex) {
                        throw new ExprValidationException(
                            "Failed to find user-defined function '" + methodStreamSpec.MethodName + "': " + ex.Message,
                            ex);
                    }

                    methodReflection = classpathImportService.ResolveMethodOverloadChecked(
                        udf.First,
                        methodStreamSpec.MethodName);
                    eventTypeNameProvidedUDFOrScript = udf.Second.OptionalEventTypeName;
                    strategy = MethodPollingExecStrategyEnum.TARGET_CONST;
                }
                else {
                    methodReflection = classpathImportService.ResolveMethodOverloadChecked(
                        methodStreamSpec.ClassName,
                        methodStreamSpec.MethodName,
                        services.ClassProvidedExtension);
                    strategy = MethodPollingExecStrategyEnum.TARGET_CONST;
                }
            }
            catch (ExprValidationException) {
                throw;
            }
            catch (Exception e) {
                throw new ExprValidationException(e.Message, e);
            }

            Type methodProviderClass = null;
            Type beanClass;
            IDictionary<string, object> oaType = null;
            IDictionary<string, object> mapType = null;
            var isCollection = false;
            var isEnumerator = false;
            EventType eventType;
            EventType eventTypeWhenMethodReturnsEventBeans = null;
            var isStaticMethod = false;

            if (methodReflection != null) {
                methodProviderClass = methodReflection.DeclaringType;
                isStaticMethod = variableMetaData == null;

                // Determine object type returned by method
                beanClass = methodReflection.ReturnType;
                if (beanClass == typeof(void) || beanClass == typeof(void) || beanClass.IsBuiltinDataType()) {
                    throw new ExprValidationException(
                        "Invalid return type for static method '" +
                        methodReflection.Name +
                        "' of class '" +
                        methodStreamSpec.ClassName +
                        "', expecting a type");
                }

                if (methodReflection.ReturnType.IsArray &&
                    methodReflection.ReturnType.GetElementType() != typeof(EventBean)) {
                    beanClass = methodReflection.ReturnType.GetElementType();
                }

                isCollection = beanClass.IsGenericCollection() && !beanClass.IsGenericDictionary();
                Type collectionClass = null;
                if (isCollection) {
                    collectionClass = TypeHelper.GetGenericReturnType(methodReflection, true);
                    beanClass = collectionClass;
                }

                isEnumerator = beanClass.IsGenericEnumerator();
                Type enumerator = null;
                if (isEnumerator) {
                    enumerator = TypeHelper.GetGenericReturnType(methodReflection, true);
                    beanClass = enumerator;
                }

                // If the method returns a Map, look up the map type
                string mapTypeName = null;
                if (methodReflection.ReturnType.IsGenericDictionary() ||
                    methodReflection.ReturnType.IsArray &&
                    methodReflection.ReturnType.GetElementType().IsGenericDictionary() ||
                    isCollection && collectionClass.IsGenericDictionary() ||
                    isEnumerator && enumerator.IsGenericDictionary()) {
                    MethodMetadataDesc metadata;
                    if (variableMetaData != null) {
                        metadata = GetCheckMetadataVariable(
                            methodStreamSpec.MethodName,
                            variableMetaData,
                            classpathImportService,
                            typeof(IDictionary<string, object>));
                    }
                    else {
                        metadata = GetCheckMetadataNonVariable(
                            methodStreamSpec.MethodName,
                            methodStreamSpec.ClassName,
                            classpathImportService,
                            typeof(IDictionary<string, object>));
                    }

                    mapTypeName = metadata.TypeName;
                    mapType = (IDictionary<string, object>) metadata.TypeMetadata;
                }

                // If the method returns an Object[] or Object[][], look up the type information
                string oaTypeName = null;
                if (methodReflection.ReturnType == typeof(object[]) ||
                    methodReflection.ReturnType == typeof(object[][]) ||
                    isCollection && collectionClass == typeof(object[]) ||
                    isEnumerator && enumerator == typeof(object[])) {
                    MethodMetadataDesc metadata;
                    if (variableMetaData != null) {
                        metadata = GetCheckMetadataVariable(
                            methodStreamSpec.MethodName,
                            variableMetaData,
                            classpathImportService,
                            typeof(IDictionary<string, object>));
                    }
                    else {
                        metadata = GetCheckMetadataNonVariable(
                            methodStreamSpec.MethodName,
                            methodStreamSpec.ClassName,
                            classpathImportService,
                            typeof(IDictionary<string, object>));
                    }

                    oaTypeName = metadata.TypeName;
                    oaType = (IDictionary<string, object>) metadata.TypeMetadata;
                }

                // Determine event type from class and method name
                // If the method returns EventBean[], require the event type
                Func<EventTypeApplicationType, EventTypeMetadata> metadataFunction = apptype => {
                    var eventTypeName = services.EventTypeNameGeneratorStatement.GetAnonymousMethodHistorical(stream);
                    return new EventTypeMetadata(
                        eventTypeName,
                        @base.ModuleName,
                        EventTypeTypeClass.METHODPOLLDERIVED,
                        apptype,
                        NameAccessModifier.TRANSIENT,
                        EventTypeBusModifier.NONBUS,
                        false,
                        EventTypeIdPair.Unassigned());
                };
                if (methodReflection.ReturnType.IsArray &&
                    methodReflection.ReturnType.GetElementType() == typeof(EventBean) ||
                    isCollection && collectionClass == typeof(EventBean) ||
                    isEnumerator && enumerator == typeof(EventBean)) {
                    var typeName = methodStreamSpec.EventTypeName == null
                        ? eventTypeNameProvidedUDFOrScript
                        : methodStreamSpec.EventTypeName;
                    eventType = EventTypeUtility.RequireEventType(
                        "Method",
                        methodReflection.Name,
                        typeName,
                        services.EventTypeCompileTimeResolver);
                    eventTypeWhenMethodReturnsEventBeans = eventType;
                }
                else if (mapType != null) {
                    eventType = BaseNestableEventUtil.MakeMapTypeCompileTime(
                        metadataFunction.Invoke(EventTypeApplicationType.MAP),
                        mapType,
                        null,
                        null,
                        null,
                        null,
                        services.BeanEventTypeFactoryPrivate,
                        services.EventTypeCompileTimeResolver);
                    services.EventTypeCompileTimeRegistry.NewType(eventType);
                }
                else if (oaType != null) {
                    eventType = BaseNestableEventUtil.MakeOATypeCompileTime(
                        metadataFunction.Invoke(EventTypeApplicationType.OBJECTARR),
                        oaType,
                        null,
                        null,
                        null,
                        null,
                        services.BeanEventTypeFactoryPrivate,
                        services.EventTypeCompileTimeResolver);
                    services.EventTypeCompileTimeRegistry.NewType(eventType);
                }
                else {
                    var stem = services.BeanEventTypeStemService.GetCreateStem(beanClass, null);
                    eventType = new BeanEventType(
                        services.Container,
                        stem,
                        metadataFunction.Invoke(EventTypeApplicationType.CLASS),
                        services.BeanEventTypeFactoryPrivate,
                        null,
                        null,
                        null,
                        null);
                    services.EventTypeCompileTimeRegistry.NewType(eventType);
                }

                // the @type is only allowed in conjunction with EventBean return types
                if (methodStreamSpec.EventTypeName != null && eventTypeWhenMethodReturnsEventBeans == null) {
                    throw new ExprValidationException(EventTypeUtility.DisallowedAtTypeMessage());
                }
            }
            else {
                var eventTypeName = methodStreamSpec.EventTypeName == null
                    ? scriptExpression.EventTypeNameAnnotation
                    : methodStreamSpec.EventTypeName;
                eventType = EventTypeUtility.RequireEventType(
                    "Script",
                    scriptExpression.Script.Name,
                    eventTypeName,
                    services.EventTypeCompileTimeResolver);
            }

            // metadata
            var meta = new MethodPollingViewableMeta(
                methodProviderClass,
                isStaticMethod,
                mapType,
                oaType,
                strategy,
                isCollection,
                isEnumerator,
                variableMetaData,
                eventTypeWhenMethodReturnsEventBeans,
                scriptExpression);
            return new HistoricalEventViewableMethodForge(stream, eventType, methodStreamSpec, meta);
        }
Ejemplo n.º 27
0
        private DataFlowOpForgeInitializeResult InitializeTypeDeclared(
            DataFlowOpOutputPort port,
            DataFlowOpForgeInitializeContext context)
        {
            produceEventBean = port.OptionalDeclaredType != null && !port.OptionalDeclaredType.IsUnderlying;

            // compile properties to populate
            outputEventType = port.OptionalDeclaredType.EventType;
            var props = allProperties.Keys;
            props.RemoveAll(PARAMETER_PROPERTIES);
            var writables = SetupProperties(props.ToArray(), outputEventType);
            try {
                eventBeanManufacturer = EventTypeUtility.GetManufacturer(
                    outputEventType,
                    writables,
                    context.Services.ImportServiceCompileTime,
                    false,
                    context.Services.EventTypeAvroHandler);
            }
            catch (EventBeanManufactureException e) {
                throw new ExprValidationException(
                    "Cannot manufacture event for the provided type '" + outputEventType.Name + "': " + e.Message,
                    e);
            }

            var index = 0;
            evaluatorForges = new ExprForge[writables.Length];
            var typeWidenerCustomizer =
                context.Services.EventTypeAvroHandler.GetTypeWidenerCustomizer(outputEventType);
            foreach (var writable in writables) {
                object providedProperty = allProperties.Get(writable.PropertyName);
                var exprNode = (ExprNode) providedProperty;
                var validated = EPLValidationUtil.ValidateSimpleGetSubtree(
                    ExprNodeOrigin.DATAFLOWBEACON,
                    exprNode,
                    null,
                    false,
                    context.Base.StatementRawInfo,
                    context.Services);
                TypeWidenerSPI widener;
                try {
                    widener = TypeWidenerFactory.GetCheckPropertyAssignType(
                        ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(validated),
                        validated.Forge.EvaluationType,
                        writable.PropertyType,
                        writable.PropertyName,
                        false,
                        typeWidenerCustomizer,
                        context.Base.StatementName);
                }
                catch (TypeWidenerException e) {
                    throw new ExprValidationException("Failed for property '" + writable.PropertyName + "'", e);
                }

                if (widener != null) {
                    evaluatorForges[index] = new ExprEvalWithTypeWidener(widener, validated, writable.PropertyType);
                }
                else {
                    evaluatorForges[index] = validated.Forge;
                }

                index++;
            }

            return null;
        }
Ejemplo n.º 28
0
        private StmtForgeMethodResult Build(
            string @namespace,
            string classPostfix,
            StatementCompileTimeServices services)
        {
            var createDesc = @base.StatementSpec.Raw.CreateTableDesc;
            var tableName = createDesc.TableName;
            var additionalForgeables = new List<StmtClassForgeableFactory>();

            // determine whether already declared as table or variable
            EPLValidationUtil.ValidateAlreadyExistsTableOrVariable(
                tableName,
                services.VariableCompileTimeResolver,
                services.TableCompileTimeResolver,
                services.EventTypeCompileTimeResolver);

            // determine key types
            ValidateKeyTypes(createDesc.Columns, services.ImportServiceCompileTime);

            // check column naming, interpret annotations
            var columnsValidated = ValidateExpressions(createDesc.Columns, services);
            var columnDescs = columnsValidated.First;
            additionalForgeables.AddRange(columnsValidated.Second);

            // analyze and plan the state holders
            var plan = AnalyzePlanAggregations(createDesc.TableName, columnDescs, @base.StatementRawInfo, services);
            additionalForgeables.AddAll(plan.AdditionalForgeables);
            var visibility = plan.PublicEventType.Metadata.AccessModifier;

            // determine context information
            var contextName = @base.StatementRawInfo.ContextName;
            NameAccessModifier? contextVisibility = null;
            string contextModuleName = null;
            if (contextName != null) {
                var contextDetail = services.ContextCompileTimeResolver.GetContextInfo(contextName);
                if (contextDetail == null) {
                    throw new ExprValidationException("Failed to find context '" + contextName + "'");
                }

                contextVisibility = contextDetail.ContextVisibility;
                contextModuleName = contextDetail.ContextModuleName;
            }

            // add table
            var tableMetaData = new TableMetaData(
                tableName,
                @base.ModuleName,
                visibility,
                contextName,
                contextVisibility,
                contextModuleName,
                plan.InternalEventType,
                plan.PublicEventType,
                plan.PrimaryKeyColumns,
                plan.PrimaryKeyTypes,
                plan.PrimaryKeyColNums,
                plan.TableColumns,
                plan.ColsAggMethod.Length);
            services.TableCompileTimeRegistry.NewTable(tableMetaData);

            var aiFactoryProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementAIFactoryProvider),
                classPostfix);
            var statementFieldsClassName =
                CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementFields), classPostfix);
            var statementProviderClassName =
                CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementProvider), classPostfix);

            var forge = new StatementAgentInstanceFactoryCreateTableForge(
                aiFactoryProviderClassName,
                tableMetaData.TableName,
                plan);

            // build forge list
            var namespaceScope = new CodegenNamespaceScope(
                @namespace,
                statementFieldsClassName,
                services.IsInstrumented);
            var forgeables = additionalForgeables
                .Select(additional => additional.Make(namespaceScope, classPostfix))
                .ToList();

            var aiFactoryForgeable = new StmtClassForgeableAIFactoryProviderCreateTable(
                aiFactoryProviderClassName,
                namespaceScope,
                forge,
                tableName);
            forgeables.Add(aiFactoryForgeable);

            var selectSubscriberDescriptor = new SelectSubscriberDescriptor();
            var informationals = StatementInformationalsUtil.GetInformationals(
                @base,
                EmptyList<FilterSpecCompiled>.Instance,
                EmptyList<ScheduleHandleCallbackProvider>.Instance,
                EmptyList<NamedWindowConsumerStreamSpec>.Instance,
                true,
                selectSubscriberDescriptor,
                namespaceScope,
                services);
            informationals.Properties.Put(StatementProperty.CREATEOBJECTNAME, createDesc.TableName);

            forgeables.Add(
                new StmtClassForgeableStmtProvider(
                    aiFactoryProviderClassName,
                    statementProviderClassName,
                    informationals,
                    namespaceScope));
            forgeables.Add(
                new StmtClassForgeableStmtFields(
                    statementFieldsClassName,
                    namespaceScope,
                    1));

            return new StmtForgeMethodResult(
                forgeables,
                EmptyList<FilterSpecCompiled>.Instance,
                EmptyList<ScheduleHandleCallbackProvider>.Instance,
                EmptyList<NamedWindowConsumerStreamSpec>.Instance,
                EmptyList<FilterSpecParamExprNodeForge>.Instance);
        }
Ejemplo n.º 29
0
        public StmtForgeMethodResult Make(
            string @namespace,
            string classPostfix,
            StatementCompileTimeServices services)
        {
            var statementSpec = @base.StatementSpec;

            var spec = statementSpec.Raw.CreateSchemaDesc;

            if (services.EventTypeCompileTimeResolver.GetTypeByName(spec.SchemaName) != null) {
                throw new ExprValidationException(
                    "Event type named '" + spec.SchemaName + "' has already been declared");
            }

            EPLValidationUtil.ValidateTableExists(services.TableCompileTimeResolver, spec.SchemaName);
            var eventType = HandleCreateSchema(spec, services);

            var statementFieldsClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementFields), classPostfix);
            var namespaceScope = new CodegenNamespaceScope(
                @namespace, statementFieldsClassName, services.IsInstrumented);
            var fieldsForgable = new StmtClassForgableStmtFields(statementFieldsClassName, namespaceScope, 0);

            var aiFactoryProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementAIFactoryProvider),
                classPostfix);
            var forge = new StatementAgentInstanceFactoryCreateSchemaForge(eventType);
            var aiFactoryForgable = new StmtClassForgableAIFactoryProviderCreateSchema(
                aiFactoryProviderClassName,
                namespaceScope,
                forge);

            var selectSubscriberDescriptor = new SelectSubscriberDescriptor();
            var informationals = StatementInformationalsUtil.GetInformationals(
                @base,
                new EmptyList<FilterSpecCompiled>(),
                new EmptyList<ScheduleHandleCallbackProvider>(),
                new EmptyList<NamedWindowConsumerStreamSpec>(),
                false,
                selectSubscriberDescriptor,
                namespaceScope,
                services);
            var statementProviderClassName =
                CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementProvider), classPostfix);
            var stmtProvider = new StmtClassForgableStmtProvider(
                aiFactoryProviderClassName,
                statementProviderClassName,
                informationals,
                namespaceScope);

            IList<StmtClassForgable> forgables = new List<StmtClassForgable>();
            forgables.Add(fieldsForgable);
            forgables.Add(aiFactoryForgable);
            forgables.Add(stmtProvider);
            return new StmtForgeMethodResult(
                forgables,
                new EmptyList<FilterSpecCompiled>(),
                new EmptyList<ScheduleHandleCallbackProvider>(),
                new EmptyList<NamedWindowConsumerStreamSpec>(),
                new EmptyList<FilterSpecParamExprNodeForge>());
        }
Ejemplo n.º 30
0
        public static StmtForgeMethodSelectResult Make(
            IContainer container,
            bool dataflowOperator,
            string @namespace,
            string classPostfix,
            StatementBaseInfo @base,
            StatementCompileTimeServices services)
        {
            var filterSpecCompileds = new List<FilterSpecCompiled>();
            var scheduleHandleCallbackProviders = new List<ScheduleHandleCallbackProvider>();
            var namedWindowConsumers = new List<NamedWindowConsumerStreamSpec>();
            var statementSpec = @base.StatementSpec;
            var additionalForgeables = new List<StmtClassForgeableFactory>();

            var streamNames = StatementForgeMethodSelectUtil.DetermineStreamNames(statementSpec.StreamSpecs);
            var numStreams = streamNames.Length;
            if (numStreams == 0) {
                throw new ExprValidationException("The from-clause is required but has not been specified");
            }

            // first we create streams for subselects, if there are any
            SubSelectActivationDesc subSelectActivationDesc = SubSelectHelperActivations.CreateSubSelectActivation(
                filterSpecCompileds, namedWindowConsumers, @base, services);
            IDictionary<ExprSubselectNode, SubSelectActivationPlan> subselectActivation = subSelectActivationDesc.Subselects;
            additionalForgeables.AddAll(subSelectActivationDesc.AdditionalForgeables);

            // verify for joins that required views are present
            StreamJoinAnalysisResultCompileTime joinAnalysisResult = StatementForgeMethodSelectUtil.VerifyJoinViews(statementSpec);

            var streamEventTypes = new EventType[statementSpec.StreamSpecs.Length];
            var eventTypeNames = new string[numStreams];
            var isNamedWindow = new bool[numStreams];
            var viewableActivatorForges = new ViewableActivatorForge[numStreams];
            var viewForges = new IList<ViewFactoryForge>[numStreams];
            var historicalEventViewables = new HistoricalEventViewableForge[numStreams];

            for (var stream = 0; stream < numStreams; stream++) {
                var streamSpec = statementSpec.StreamSpecs[stream];
                var isCanIterateUnbound = streamSpec.ViewSpecs.Length == 0 &&
                                          (services.Configuration.Compiler.ViewResources.IsIterableUnbound ||
                                           AnnotationUtil.HasAnnotation(statementSpec.Annotations, typeof(IterableUnboundAttribute)));

                var args = new ViewFactoryForgeArgs(
                    stream,
                    false,
                    -1,
                    streamSpec.Options,
                    null,
                    @base.StatementRawInfo,
                    services);

                if (dataflowOperator) {
                    var dfResult = HandleDataflowActivation(args, streamSpec);
                    streamEventTypes[stream] = dfResult.StreamEventType;
                    eventTypeNames[stream] = dfResult.EventTypeName;
                    viewableActivatorForges[stream] = dfResult.ViewableActivatorForge;
                    viewForges[stream] = dfResult.ViewForges;
                    additionalForgeables.AddAll(dfResult.AdditionalForgeables);
                }
                else if (streamSpec is FilterStreamSpecCompiled) {
                    var filterStreamSpec = (FilterStreamSpecCompiled) statementSpec.StreamSpecs[stream];
                    var filterSpecCompiled = filterStreamSpec.FilterSpecCompiled;
                    streamEventTypes[stream] = filterSpecCompiled.ResultEventType;
                    eventTypeNames[stream] = filterStreamSpec.FilterSpecCompiled.FilterForEventTypeName;

                    viewableActivatorForges[stream] = new ViewableActivatorFilterForge(
                        filterSpecCompiled,
                        isCanIterateUnbound,
                        stream,
                        false,
                        -1);
                    ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(streamSpec.ViewSpecs, args, streamEventTypes[stream]);
                    viewForges[stream] = viewForgeDesc.Forges;
                    additionalForgeables.AddAll(viewForgeDesc.MultikeyForges);
                    filterSpecCompileds.Add(filterSpecCompiled);
                }
                else if (streamSpec is PatternStreamSpecCompiled) {
                    var patternStreamSpec = (PatternStreamSpecCompiled) streamSpec;
                    var forges = patternStreamSpec.Root.CollectFactories();
                    foreach (var forgeNode in forges) {
                        forgeNode.CollectSelfFilterAndSchedule(filterSpecCompileds, scheduleHandleCallbackProviders);
                    }

                    var patternType = ViewableActivatorPatternForge.MakeRegisterPatternType(
                        @base,
                        stream,
                        patternStreamSpec,
                        services);
                    var patternContext = new PatternContext(0, patternStreamSpec.MatchedEventMapMeta, false, -1, false);
                    viewableActivatorForges[stream] = new ViewableActivatorPatternForge(
                        patternType,
                        patternStreamSpec,
                        patternContext,
                        isCanIterateUnbound);
                    streamEventTypes[stream] = patternType;
                    ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(streamSpec.ViewSpecs, args, patternType);
                    viewForges[stream] = viewForgeDesc.Forges;
                    additionalForgeables.AddAll(viewForgeDesc.MultikeyForges);
                }
                else if (streamSpec is NamedWindowConsumerStreamSpec) {
                    var namedSpec = (NamedWindowConsumerStreamSpec) streamSpec;
                    var namedWindow =
                        services.NamedWindowCompileTimeResolver.Resolve(namedSpec.NamedWindow.EventType.Name);
                    var namedWindowType = namedWindow.EventType;
                    if (namedSpec.OptPropertyEvaluator != null) {
                        namedWindowType = namedSpec.OptPropertyEvaluator.FragmentEventType;
                    }

                    var typesFilterValidation = new StreamTypeServiceImpl(
                        namedWindowType,
                        namedSpec.OptionalStreamName,
                        false);
                    var filterSingle =
                        ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(namedSpec.FilterExpressions);
                    var filterQueryGraph = EPLValidationUtil.ValidateFilterGetQueryGraphSafe(
                        filterSingle,
                        typesFilterValidation,
                        @base.StatementRawInfo,
                        services);

                    namedWindowConsumers.Add(namedSpec);
                    viewableActivatorForges[stream] = new ViewableActivatorNamedWindowForge(
                        namedSpec,
                        namedWindow,
                        filterSingle,
                        filterQueryGraph,
                        true,
                        namedSpec.OptPropertyEvaluator);
                    streamEventTypes[stream] = namedWindowType;
                    viewForges[stream] = Collections.GetEmptyList<ViewFactoryForge>();
                    joinAnalysisResult.SetNamedWindowsPerStream(stream, namedWindow);
                    eventTypeNames[stream] = namedSpec.NamedWindow.EventType.Name;
                    isNamedWindow[stream] = true;

                    // Consumers to named windows cannot declare a data window view onto the named window to avoid duplicate remove streams
                    ViewFactoryForgeDesc viewForgeDesc = ViewFactoryForgeUtil.CreateForges(streamSpec.ViewSpecs, args, namedWindowType);
                    viewForges[stream] = viewForgeDesc.Forges;
                    additionalForgeables.AddAll(viewForgeDesc.MultikeyForges);

                    EPStatementStartMethodHelperValidate.ValidateNoDataWindowOnNamedWindow(viewForges[stream]);
                }
                else if (streamSpec is TableQueryStreamSpec) {
                    ValidateNoViews(streamSpec, "Table data");
                    var tableStreamSpec = (TableQueryStreamSpec) streamSpec;
                    if (numStreams > 1 && tableStreamSpec.FilterExpressions.Count > 0) {
                        throw new ExprValidationException(
                            "Joins with tables do not allow table filter expressions, please add table filters to the where-clause instead");
                    }

                    var table = tableStreamSpec.Table;
                    EPLValidationUtil.ValidateContextName(
                        true,
                        table.TableName,
                        table.OptionalContextName,
                        statementSpec.Raw.OptionalContextName,
                        false);
                    var filter =
                        ExprNodeUtilityMake.ConnectExpressionsByLogicalAndWhenNeeded(tableStreamSpec.FilterExpressions);
                    viewableActivatorForges[stream] = new ViewableActivatorTableForge(table, filter);
                    viewForges[stream] = Collections.GetEmptyList<ViewFactoryForge>();
                    eventTypeNames[stream] = tableStreamSpec.Table.TableName;
                    streamEventTypes[stream] = tableStreamSpec.Table.InternalEventType;
                    joinAnalysisResult.SetTablesForStream(stream, table);

                    if (tableStreamSpec.Options.IsUnidirectional) {
                        throw new ExprValidationException("Tables cannot be marked as unidirectional");
                    }

                    if (tableStreamSpec.Options.IsRetainIntersection || tableStreamSpec.Options.IsRetainUnion) {
                        throw new ExprValidationException("Tables cannot be marked with retain");
                    }
                }
                else if (streamSpec is DBStatementStreamSpec) {
                    ValidateNoViews(streamSpec, "Historical data");
                    var sqlStreamSpec = (DBStatementStreamSpec) streamSpec;
                    var typeConversionHook = (SQLColumnTypeConversion) ImportUtil.GetAnnotationHook(
                        statementSpec.Annotations,
                        HookType.SQLCOL,
                        typeof(SQLColumnTypeConversion),
                        services.ImportServiceCompileTime);
                    var outputRowConversionHook = (SQLOutputRowConversion) ImportUtil.GetAnnotationHook(
                        statementSpec.Annotations,
                        HookType.SQLROW,
                        typeof(SQLOutputRowConversion),
                        services.ImportServiceCompileTime);
                    var viewable = HistoricalEventViewableDatabaseForgeFactory.CreateDBStatementView(
                        stream,
                        sqlStreamSpec,
                        typeConversionHook,
                        outputRowConversionHook,
                        @base,
                        services,
                        statementSpec.Annotations);
                    streamEventTypes[stream] = viewable.EventType;
                    viewForges[stream] = Collections.GetEmptyList<ViewFactoryForge>();
                    viewableActivatorForges[stream] = new ViewableActivatorHistoricalForge(viewable);
                    historicalEventViewables[stream] = viewable;
                }
                else if (streamSpec is MethodStreamSpec) {
                    ValidateNoViews(streamSpec, "Method data");
                    var methodStreamSpec = (MethodStreamSpec) streamSpec;
                    var viewable = HistoricalEventViewableMethodForgeFactory.CreateMethodStatementView(
                        stream,
                        methodStreamSpec,
                        @base,
                        services);
                    historicalEventViewables[stream] = viewable;
                    streamEventTypes[stream] = viewable.EventType;
                    viewForges[stream] = Collections.GetEmptyList<ViewFactoryForge>();
                    viewableActivatorForges[stream] = new ViewableActivatorHistoricalForge(viewable);
                    historicalEventViewables[stream] = viewable;
                }
                else {
                    throw new IllegalStateException("Unrecognized stream " + streamSpec);
                }
                
                // plan serde for iterate-unbound
                if (isCanIterateUnbound) {
                    var serdeForgeables = SerdeEventTypeUtility.Plan(
                        streamEventTypes[stream], @base.StatementRawInfo, services.SerdeEventTypeRegistry, services.SerdeResolver);
                    additionalForgeables.AddAll(serdeForgeables);
                }
            }

            // handle match-recognize pattern
            if (statementSpec.Raw.MatchRecognizeSpec != null) {
                if (numStreams > 1) {
                    throw new ExprValidationException("Joins are not allowed when using match-recognize");
                }

                if (joinAnalysisResult.TablesPerStream[0] != null) {
                    throw new ExprValidationException("Tables cannot be used with match-recognize");
                }

                var isUnbound = viewForges[0].IsEmpty() &&
                                !(statementSpec.StreamSpecs[0] is NamedWindowConsumerStreamSpec);
                var eventType = viewForges[0].IsEmpty()
                    ? streamEventTypes[0]
                    : viewForges[0][(viewForges[0].Count - 1)].EventType;
                
                var plan = RowRecogNFAViewPlanUtil.ValidateAndPlan(services.Container, eventType, isUnbound, @base, services);
                var forge = new RowRecogNFAViewFactoryForge(plan.Forge);
                additionalForgeables.AddAll(plan.AdditionalForgeables);
                scheduleHandleCallbackProviders.Add(forge);
                viewForges[0].Add(forge);
                var serdeForgeables = SerdeEventTypeUtility.Plan(
                    eventType, @base.StatementRawInfo, services.SerdeEventTypeRegistry, services.SerdeResolver);
                additionalForgeables.AddAll(serdeForgeables);
            }

            // Obtain event types from view factory chains
            for (var i = 0; i < viewForges.Length; i++) {
                streamEventTypes[i] = viewForges[i].IsEmpty()
                    ? streamEventTypes[i]
                    : viewForges[i][(viewForges[i].Count - 1)].EventType;
            }

            // add unique-information to join analysis
            joinAnalysisResult.AddUniquenessInfo(viewForges, statementSpec.Annotations);

            // plan sub-selects
            SubSelectHelperForgePlan subselectForgePlan = SubSelectHelperForgePlanner.PlanSubSelect(
                @base, subselectActivation, streamNames, streamEventTypes, eventTypeNames, services);
            var subselectForges = subselectForgePlan.Subselects;
            additionalForgeables.AddAll(subselectForgePlan.AdditionalForgeables);

            DetermineViewSchedules(subselectForges, scheduleHandleCallbackProviders);

            // determine view schedules
            var viewResourceDelegateExpr = new ViewResourceDelegateExpr();
            ViewFactoryForgeUtil.DetermineViewSchedules(viewForges, scheduleHandleCallbackProviders);

            var hasIStreamOnly = StatementForgeMethodSelectUtil.GetHasIStreamOnly(isNamedWindow, viewForges);
            var optionalStreamsIfAny = OuterJoinAnalyzer.OptionalStreamsIfAny(statementSpec.Raw.OuterJoinDescList);
            StreamTypeService typeService = new StreamTypeServiceImpl(
                streamEventTypes,
                streamNames,
                hasIStreamOnly,
                false,
                optionalStreamsIfAny);

            // Validate views that require validation, specifically streams that don't have
            // sub-views such as DB SQL joins
            var historicalViewableDesc = new HistoricalViewableDesc(numStreams);
            for (var stream = 0; stream < historicalEventViewables.Length; stream++) {
                var historicalEventViewable = historicalEventViewables[stream];
                if (historicalEventViewable == null) {
                    continue;
                }

                scheduleHandleCallbackProviders.Add(historicalEventViewable);
                IList<StmtClassForgeableFactory> forgeables = historicalEventViewable.Validate(typeService, @base, services);
                additionalForgeables.AddAll(forgeables);
                historicalViewableDesc.SetHistorical(stream, historicalEventViewable.RequiredStreams);
                if (historicalEventViewable.RequiredStreams.Contains(stream)) {
                    throw new ExprValidationException(
                        "Parameters for historical stream " +
                        stream +
                        " indicate that the stream is subordinate to itself as stream parameters originate in the same stream");
                }
            }

            // Validate where-clause filter tree, outer join clause and output limit expression
            var whereClauseValidated = EPStatementStartMethodHelperValidate.ValidateNodes(
                statementSpec.Raw,
                typeService,
                viewResourceDelegateExpr,
                @base.StatementRawInfo,
                services);
            var whereClauseForge = whereClauseValidated?.Forge;

            // Obtain result set processor
            var resultSetProcessorDesc = ResultSetProcessorFactoryFactory.GetProcessorPrototype(
                new ResultSetSpec(statementSpec),
                typeService,
                viewResourceDelegateExpr,
                joinAnalysisResult.UnidirectionalInd,
                true,
                @base.ContextPropertyRegistry,
                false,
                false,
                @base.StatementRawInfo,
                services);
            additionalForgeables.AddAll(resultSetProcessorDesc.AdditionalForgeables);

            // Handle 'prior' function nodes in terms of view requirements
            var viewResourceDelegateDesc =
                ViewResourceVerifyHelper.VerifyPreviousAndPriorRequirements(viewForges, viewResourceDelegateExpr);
            var hasPrior = ViewResourceDelegateDesc.HasPrior(viewResourceDelegateDesc);
            if (hasPrior) {
                for (var stream = 0; stream < numStreams; stream++) {
                    if (!viewResourceDelegateDesc[stream].PriorRequests.IsEmpty()) {
                        viewForges[stream].Add(new PriorEventViewForge(viewForges[stream].IsEmpty(), streamEventTypes[stream]));
                        var serdeForgeables = SerdeEventTypeUtility.Plan(
                            streamEventTypes[stream], @base.StatementRawInfo, services.SerdeEventTypeRegistry, services.SerdeResolver);
                        additionalForgeables.AddAll(serdeForgeables);
                    }
                }
            }

            var outputProcessDesc = OutputProcessViewForgeFactory.Make(
                typeService.EventTypes,
                resultSetProcessorDesc.ResultEventType,
                resultSetProcessorDesc.ResultSetProcessorType,
                statementSpec,
                @base.StatementRawInfo,
                services);
            var outputProcessViewFactoryForge = outputProcessDesc.Forge;
            additionalForgeables.AddAll(outputProcessDesc.AdditionalForgeables);
            outputProcessViewFactoryForge.CollectSchedules(scheduleHandleCallbackProviders);

            JoinSetComposerPrototypeForge joinForge = null;
            if (numStreams > 1) {
                var hasAggregations = !resultSetProcessorDesc.AggregationServiceForgeDesc.Expressions.IsEmpty();
                var desc = JoinSetComposerPrototypeForgeFactory.MakeComposerPrototype(
                    statementSpec,
                    joinAnalysisResult,
                    typeService,
                    historicalViewableDesc,
                    false,
                    hasAggregations,
                    @base.StatementRawInfo,
                    services);
                joinForge = desc.Forge;
                additionalForgeables.AddAll(desc.AdditionalForgeables);
                HandleIndexDependencies(joinForge.OptionalQueryPlan, services);
            }

            // plan table access
            var tableAccessForges =
                ExprTableEvalHelperPlan.PlanTableAccess(@base.StatementSpec.TableAccessNodes);
            ValidateTableAccessUse(statementSpec.Raw.IntoTableSpec, statementSpec.Raw.TableExpressions);
            if (joinAnalysisResult.IsUnidirectional && statementSpec.Raw.IntoTableSpec != null) {
                throw new ExprValidationException("Into-table does not allow unidirectional joins");
            }

            var orderByWithoutOutputLimit = statementSpec.Raw.OrderByList != null &&
                                            !statementSpec.Raw.OrderByList.IsEmpty() &&
                                            statementSpec.Raw.OutputLimitSpec == null;

            var statementAIFactoryProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementAIFactoryProvider),
                classPostfix);
            var resultSetProcessorProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(ResultSetProcessorFactoryProvider),
                classPostfix);
            var outputProcessViewProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(OutputProcessViewFactoryProvider),
                classPostfix);
            var statementProviderClassName =
                CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementProvider), classPostfix);
            var statementFieldsClassName =
                CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(StatementFields), classPostfix);
            //var statementFieldsClassName = namespaceScope.FieldsClassNameOptional;

            var forgeX = new StatementAgentInstanceFactorySelectForge(
                typeService.StreamNames,
                viewableActivatorForges,
                resultSetProcessorProviderClassName,
                viewForges,
                viewResourceDelegateDesc,
                whereClauseForge,
                joinForge,
                outputProcessViewProviderClassName,
                subselectForges,
                tableAccessForges,
                orderByWithoutOutputLimit,
                joinAnalysisResult.IsUnidirectional);

            var namespaceScope = new CodegenNamespaceScope(
                @namespace,
                statementFieldsClassName,
                services.IsInstrumented);

            var forgeablesX = additionalForgeables
                .Select(additional => additional.Make(namespaceScope, classPostfix))
                .ToList();

            forgeablesX.Add(
                new StmtClassForgeableRSPFactoryProvider(
                    resultSetProcessorProviderClassName,
                    resultSetProcessorDesc,
                    namespaceScope,
                    @base.StatementRawInfo));
            forgeablesX.Add(
                new StmtClassForgeableOPVFactoryProvider(
                    outputProcessViewProviderClassName,
                    outputProcessViewFactoryForge,
                    namespaceScope,
                    numStreams,
                    @base.StatementRawInfo));
            forgeablesX.Add(
                new StmtClassForgeableAIFactoryProviderSelect(statementAIFactoryProviderClassName, namespaceScope, forgeX));
            forgeablesX.Add(
                new StmtClassForgeableStmtFields(statementFieldsClassName, namespaceScope, numStreams));

            if (!dataflowOperator) {
                var informationals = StatementInformationalsUtil.GetInformationals(
                    @base,
                    filterSpecCompileds,
                    scheduleHandleCallbackProviders,
                    namedWindowConsumers,
                    true,
                    resultSetProcessorDesc.SelectSubscriberDescriptor,
                    namespaceScope,
                    services);
                forgeablesX.Add(
                    new StmtClassForgeableStmtProvider(statementAIFactoryProviderClassName, statementProviderClassName, informationals, namespaceScope));
            }

            var forgeableResult = new StmtForgeMethodResult(
                forgeablesX,
                filterSpecCompileds,
                scheduleHandleCallbackProviders,
                namedWindowConsumers,
                FilterSpecCompiled.MakeExprNodeList(filterSpecCompileds, EmptyList<FilterSpecParamExprNodeForge>.Instance));
            return new StmtForgeMethodSelectResult(forgeableResult, resultSetProcessorDesc.ResultEventType, numStreams);
        }