Ejemplo n.º 1
0
        private ExprNode ValidateMeasureClause(ExprNode measureNode, StreamTypeService typeServiceMeasure, ISet <string> variablesMultiple, ISet <string> variablesSingle, StatementContext statementContext)

        {
            try
            {
                var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false);
                var validationContext    = new ExprValidationContext(
                    typeServiceMeasure, statementContext.MethodResolutionService, null, statementContext.SchedulingService,
                    statementContext.VariableService, statementContext.TableService, exprEvaluatorContext,
                    statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId,
                    statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService,
                    false, false, true, false, null, false);
                return(ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.MATCHRECOGMEASURE, measureNode, validationContext));
            }
            catch (ExprValidationPropertyException e)
            {
                var grouped = CollectionUtil.ToString(variablesMultiple);
                var single  = CollectionUtil.ToString(variablesSingle);
                var message = e.Message;
                if (!variablesMultiple.IsEmpty())
                {
                    message += ", ensure that grouped variables (variables " + grouped + ") are accessed via index (i.e. variable[0].property) or appear within an aggregation";
                }
                if (!variablesSingle.IsEmpty())
                {
                    message += ", ensure that singleton variables (variables " + single + ") are not accessed via index";
                }
                throw new ExprValidationPropertyException(message, e);
            }
        }
Ejemplo n.º 2
0
 public EventTable[] Index(IList<EventBean> pollResult, bool isActiveCache, StatementContext statementContext)
 {
     if (!isActiveCache)
     {
         return new EventTable[]
         {
             new UnindexedEventTableList(pollResult, _streamNum)
         };
     }
     PropertySortedEventTableFactory tableFactory;
     if (_coercionType == null)
     {
         tableFactory = new PropertySortedEventTableFactory(_streamNum, _eventType, _propertyName);
     }
     else
     {
         tableFactory = new PropertySortedEventTableCoercedFactory(
             _streamNum, _eventType, _propertyName, _coercionType);
     }
     var evaluatorContextStatement = new ExprEvaluatorContextStatement(statementContext, false);
     EventTable[] tables = tableFactory.MakeEventTables(new EventTableFactoryTableIdentStmt(statementContext), evaluatorContextStatement);
     foreach (EventTable table in tables)
     {
         table.Add(pollResult.ToArray(), evaluatorContextStatement);
     }
     return tables;
 }
Ejemplo n.º 3
0
        public static FilterSpecCompiled Build(
            IList <ExprNode> validatedNodes,
            EventType eventType,
            string eventTypeName,
            PropertyEvalSpec optionalPropertyEvalSpec,
            IDictionary <string, Pair <EventType, string> > taggedEventTypes,
            IDictionary <string, Pair <EventType, string> > arrayEventTypes,
            StreamTypeService streamTypeService,
            string optionalStreamName,
            StatementContext stmtContext,
            ICollection <int> assignedTypeNumberStack)
        {
            var evaluatorContextStmt = new ExprEvaluatorContextStatement(stmtContext, false);

            return(BuildNoStmtCtx(validatedNodes, eventType, eventTypeName, optionalPropertyEvalSpec, taggedEventTypes, arrayEventTypes, streamTypeService,
                                  optionalStreamName, assignedTypeNumberStack,
                                  evaluatorContextStmt,
                                  stmtContext.StatementId,
                                  stmtContext.StatementName,
                                  stmtContext.Annotations,
                                  stmtContext.ContextDescriptor,
                                  stmtContext.MethodResolutionService,
                                  stmtContext.EventAdapterService,
                                  stmtContext.TimeProvider,
                                  stmtContext.VariableService,
                                  stmtContext.ScriptingService,
                                  stmtContext.TableService,
                                  stmtContext.ConfigSnapshot,
                                  stmtContext.NamedWindowService));
        }
Ejemplo n.º 4
0
        public void Attach(EventType parentEventType, StatementContext statementContext, ViewFactory optionalParentFactory, IList <ViewFactory> parentViewFactories)
        {
            _parentEventType = parentEventType;

            var validatedNodes = ViewFactorySupport.Validate(_viewFactoryContext.ViewName, parentEventType, _viewFactoryContext.StatementContext, _viewParameters, true);

            _viewParameterArr = new Object[validatedNodes.Length];
            var evaluatorContextStmt = new ExprEvaluatorContextStatement(_viewFactoryContext.StatementContext, false);

            for (var i = 0; i < validatedNodes.Length; i++)
            {
                try {
                    _viewParameterArr[i] = ViewFactorySupport.EvaluateAssertNoProperties(_viewFactoryContext.ViewName, validatedNodes[i], i, evaluatorContextStmt);
                }
                catch (Exception) {
                    // expected
                }
            }

            _viewParameterExp = ViewFactorySupport.Validate(_viewFactoryContext.ViewName, parentEventType, _viewFactoryContext.StatementContext, _viewParameters, true);

            // initialize
            try {
                _eventBeanFactory = EventAdapterServiceHelper.GetFactoryForType(parentEventType, statementContext.EventAdapterService);
                _virtualDataWindowFactory.Initialize(new VirtualDataWindowFactoryContext(parentEventType, _viewParameterArr, _viewParameterExp, _eventBeanFactory, _namedWindowName, _viewFactoryContext, _customConfiguration));
            }
            catch (Exception ex) {
                throw new ViewParameterException("Validation exception initializing virtual data window '" + _namedWindowName + "': " + ex.Message, ex);
            }
        }
Ejemplo n.º 5
0
        public ViewableActivator CreateStreamReuseView(
            EPServicesContext services,
            StatementContext statementContext,
            StatementSpecCompiled statementSpec,
            FilterStreamSpecCompiled filterStreamSpec,
            bool isJoin,
            ExprEvaluatorContextStatement evaluatorContextStmt,
            bool filterSubselectSameStream,
            int streamNum,
            bool isCanIterateUnbound)
        {
            if (ProcCreateStreamReuseView == null)
            {
                throw new NotSupportedException();
            }

            return(ProcCreateStreamReuseView.Invoke(
                       services,
                       statementContext,
                       statementSpec,
                       filterStreamSpec,
                       isJoin,
                       evaluatorContextStmt,
                       filterSubselectSameStream,
                       streamNum,
                       isCanIterateUnbound));
        }
Ejemplo n.º 6
0
        public static ExprNode ValidateExpr(String viewName, StatementContext statementContext, ExprNode expression, StreamTypeService streamTypeService, int expressionNumber)
        {
            ExprNode validated;

            try
            {
                var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false);
                var validationContext    = new ExprValidationContext(
                    streamTypeService,
                    statementContext.EngineImportService,
                    statementContext.StatementExtensionServicesContext, null,
                    statementContext.SchedulingService, statementContext.VariableService,
                    statementContext.TableService, exprEvaluatorContext,
                    statementContext.EventAdapterService, statementContext.StatementName,
                    statementContext.StatementId, statementContext.Annotations,
                    statementContext.ContextDescriptor, statementContext.ScriptingService,
                    false, false, false, false, null, false);
                validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.VIEWPARAMETER, expression, validationContext);
            }
            catch (ExprValidationException ex)
            {
                var message = "Invalid parameter expression " + expressionNumber + GetViewDesc(viewName);
                if (ex.Message != null)
                {
                    message += ": " + ex.Message;
                }
                Log.Error(message, ex);
                throw new ViewParameterException(message, ex);
            }
            return(validated);
        }
Ejemplo n.º 7
0
        private NamedWindowOnMergeActionIns SetupInsert(string namedWindowName, InternalEventRouter internalEventRouter, EventTypeSPI eventTypeNamedWindow, int selectClauseNumber, OnTriggerMergeActionInsert desc, EventType triggeringEventType, string triggeringStreamName, StatementContext statementContext)
        {
            // Compile insert-into INFO
            string streamName     = desc.OptionalStreamName ?? eventTypeNamedWindow.Name;
            var    insertIntoDesc = InsertIntoDesc.FromColumns(streamName, desc.Columns);

            // rewrite any wildcards to use "stream.wildcard"
            if (triggeringStreamName == null)
            {
                triggeringStreamName = UuidGenerator.Generate();
            }
            var selectNoWildcard = CompileSelectNoWildcard(triggeringStreamName, desc.SelectClauseCompiled);

            // Set up event types for select-clause evaluation: The first type does not contain anything as its the named window row which is not present for insert
            var dummyTypeNoProperties = new MapEventType(EventTypeMetadata.CreateAnonymous("merge_named_window_insert", ApplicationType.MAP), "merge_named_window_insert", 0, null, Collections.EmptyDataMap, null, null, null);
            var eventTypes            = new EventType[] { dummyTypeNoProperties, triggeringEventType };
            var streamNames           = new string[] { UuidGenerator.Generate(), triggeringStreamName };
            var streamTypeService     = new StreamTypeServiceImpl(eventTypes, streamNames, new bool[1], statementContext.EngineURI, false);

            // Get select expr processor
            var selectExprEventTypeRegistry = new SelectExprEventTypeRegistry(statementContext.StatementName, statementContext.StatementEventTypeRef);
            var exprEvaluatorContext        = new ExprEvaluatorContextStatement(statementContext, false);
            var insertHelper = SelectExprProcessorFactory.GetProcessor(
                statementContext.Container,
                Collections.SingletonList(selectClauseNumber),
                selectNoWildcard.ToArray(), false,
                insertIntoDesc, null, null, streamTypeService,
                statementContext.EventAdapterService,
                statementContext.StatementResultService,
                statementContext.ValueAddEventService,
                selectExprEventTypeRegistry,
                statementContext.EngineImportService,
                exprEvaluatorContext,
                statementContext.VariableService,
                statementContext.ScriptingService,
                statementContext.TableService,
                statementContext.TimeProvider,
                statementContext.EngineURI,
                statementContext.StatementId,
                statementContext.StatementName,
                statementContext.Annotations,
                statementContext.ContextDescriptor,
                statementContext.ConfigSnapshot, null,
                statementContext.NamedWindowMgmtService, null, null,
                statementContext.StatementExtensionServicesContext);
            var filterEval = desc.OptionalWhereClause == null ? null : desc.OptionalWhereClause.ExprEvaluator;

            var routerToUser = streamName.Equals(namedWindowName) ? null : internalEventRouter;
            var audit        = AuditEnum.INSERT.GetAudit(statementContext.Annotations) != null;

            string insertIntoTableName = null;

            if (statementContext.TableService.GetTableMetadata(insertIntoDesc.EventTypeName) != null)
            {
                insertIntoTableName = insertIntoDesc.EventTypeName;
            }

            return(new NamedWindowOnMergeActionIns(filterEval, insertHelper, routerToUser, insertIntoTableName, statementContext.TableService, statementContext.EpStatementHandle, statementContext.InternalEventEngineRouteDest, audit));
        }
        public override EPPreparedExecuteIUDSingleStreamExec GetExecutor(FilterSpecCompiled filter, string aliasName)
        {
            var services         = base.Services;
            var processor        = base.Processor;
            var statementContext = base.StatementContext;
            var statementSpec    = base.StatementSpec;
            var updateSpec       = (FireAndForgetSpecUpdate)statementSpec.FireAndForgetSpec;

            var assignmentTypeService = new StreamTypeServiceImpl(
                new EventType[] { processor.EventTypeResultSetProcessor, null, processor.EventTypeResultSetProcessor },
                new string[] { aliasName, "", EPStatementStartMethodOnTrigger.INITIAL_VALUE_STREAM_NAME },
                new bool[] { true, true, true }, services.EngineURI, true);

            assignmentTypeService.IsStreamZeroUnambigous = true;
            var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, true);
            var validationContext    = new ExprValidationContext(
                assignmentTypeService, statementContext.EngineImportService,
                statementContext.StatementExtensionServicesContext, null, 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);

            // validate update expressions
            try {
                foreach (OnTriggerSetAssignment assignment in updateSpec.Assignments)
                {
                    ExprNode validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.UPDATEASSIGN, assignment.Expression, validationContext);
                    assignment.Expression = validated;
                    EPStatementStartMethodHelperValidate.ValidateNoAggregations(validated, "Aggregation functions may not be used within an update-clause");
                }
            } catch (ExprValidationException e) {
                throw new EPException(e.Message, e);
            }

            // make updater
            EventBeanUpdateHelper updateHelper;
            TableUpdateStrategy   tableUpdateStrategy = null;

            try {
                bool copyOnWrite = !(processor is FireAndForgetProcessorTable);
                updateHelper = EventBeanUpdateHelperFactory.Make(processor.NamedWindowOrTableName,
                                                                 (EventTypeSPI)processor.EventTypeResultSetProcessor, updateSpec.Assignments, aliasName, null, copyOnWrite, statementContext.StatementName, services.EngineURI, services.EventAdapterService);

                if (processor is FireAndForgetProcessorTable)
                {
                    FireAndForgetProcessorTable tableProcessor = (FireAndForgetProcessorTable)processor;
                    tableUpdateStrategy = services.TableService.GetTableUpdateStrategy(tableProcessor.TableMetadata, updateHelper, false);
                    copyOnWrite         = false;
                }
            } catch (ExprValidationException e) {
                throw new EPException(e.Message, e);
            }

            return(new EPPreparedExecuteIUDSingleStreamExecUpdate(filter, statementSpec.FilterRootNode, statementSpec.Annotations, updateHelper, tableUpdateStrategy, statementSpec.TableNodes, services));
        }
Ejemplo n.º 9
0
 internal ViewableActivatorStreamReuseView(EPServicesContext services, StatementContext statementContext, StatementSpecCompiled statementSpec, FilterStreamSpecCompiled filterStreamSpec, bool join, ExprEvaluatorContextStatement evaluatorContextStmt, bool filterSubselectSameStream, int streamNum, bool isCanIterateUnbound)
 {
     _services                  = services;
     _statementContext          = statementContext;
     _statementSpec             = statementSpec;
     _filterStreamSpec          = filterStreamSpec;
     _join                      = join;
     _evaluatorContextStmt      = evaluatorContextStmt;
     _filterSubselectSameStream = filterSubselectSameStream;
     _streamNum                 = streamNum;
     _isCanIterateUnbound       = isCanIterateUnbound;
 }
Ejemplo n.º 10
0
        public void Attach(EventType parentEventType, StatementContext statementContext, ViewFactory optionalParentFactory, IList <ViewFactory> parentViewFactories)
        {
            EventType = parentEventType;
            var message = NAME + " window requires a numeric size parameter and a list of expressions providing sort keys";

            if (_viewParameters.Count < 2)
            {
                throw new ViewParameterException(message);
            }

            var validated = ViewFactorySupport.Validate(NAME + " window", parentEventType, statementContext, _viewParameters, true);

            for (var i = 1; i < validated.Length; i++)
            {
                ViewFactorySupport.AssertReturnsNonConstant(NAME + " window", validated[i], i);
            }

            var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false);
            var sortSize             = ViewFactorySupport.EvaluateAssertNoProperties(NAME + " window", validated[0], 0, exprEvaluatorContext);

            if ((sortSize == null) || (!sortSize.IsNumber()))
            {
                throw new ViewParameterException(message);
            }
            SortWindowSize = sortSize.AsInt();

            sortCriteriaExpressions = new ExprNode[validated.Length - 1];
            IsDescendingValues      = new bool[sortCriteriaExpressions.Length];

            for (var i = 1; i < validated.Length; i++)
            {
                if (validated[i] is ExprOrderedExpr)
                {
                    IsDescendingValues[i - 1]      = ((ExprOrderedExpr)validated[i]).IsDescending;
                    sortCriteriaExpressions[i - 1] = validated[i].ChildNodes[0];
                }
                else
                {
                    sortCriteriaExpressions[i - 1] = validated[i];
                }
            }
            SortCriteriaEvaluators = ExprNodeUtility.GetEvaluators(sortCriteriaExpressions);

            if (statementContext.ConfigSnapshot != null)
            {
                IsUseCollatorSort = statementContext.ConfigSnapshot.EngineDefaults.LanguageConfig.IsSortUsingCollator;
            }
        }
Ejemplo n.º 11
0
        public EventTable[] Index(IList <EventBean> pollResult, bool isActiveCache, StatementContext statementContext)
        {
            if (!isActiveCache)
            {
                return(new EventTable[] { new UnindexedEventTableList(pollResult, _streamNum) });
            }
            var tables = new EventTable[_propertyNames.Length];
            var evaluatorContextStatement = new ExprEvaluatorContextStatement(statementContext, false);

            for (var i = 0; i < _propertyNames.Length; i++)
            {
                var factory = new PropertyIndexedEventTableSingleFactory(_streamNum, _eventType, _propertyNames[i], false, null);
                tables[i] = factory.MakeEventTables(new EventTableFactoryTableIdentStmt(statementContext), evaluatorContextStatement)[0];
                tables[i].Add(pollResult.ToArray(), evaluatorContextStatement);
            }
            return(tables);
        }
        public EventTable[] Index(IList <EventBean> pollResult, bool isActiveCache, StatementContext statementContext)
        {
            if (!isActiveCache)
            {
                return(new EventTable[]
                {
                    new UnindexedEventTableList(pollResult, _streamNum)
                });
            }
            var factory = new PropertyIndexedEventTableFactory(_streamNum, _eventType, _propertyNames, false, null);
            var evaluatorContextStatement = new ExprEvaluatorContextStatement(statementContext, false);
            var tables = factory.MakeEventTables(new EventTableFactoryTableIdentStmt(statementContext), evaluatorContextStatement);

            foreach (var table in tables)
            {
                table.Add(pollResult.ToArray(), evaluatorContextStatement);
            }
            return(tables);
        }
Ejemplo n.º 13
0
        public override EPPreparedExecuteIUDSingleStreamExec GetExecutor(FilterSpecCompiled filter, string aliasName)
        {
            var selectNoWildcard = NamedWindowOnMergeHelper.CompileSelectNoWildcard(UuidGenerator.Generate(), StatementSpec.SelectClauseSpec.SelectExprList);

            StreamTypeService streamTypeService = new StreamTypeServiceImpl(StatementContext.EngineURI, true);
            var exprEvaluatorContextStatement   = new ExprEvaluatorContextStatement(StatementContext, true);

            // assign names
            var validationContext = new ExprValidationContext(
                streamTypeService,
                StatementContext.EngineImportService,
                StatementContext.StatementExtensionServicesContext,
                null, StatementContext.TimeProvider,
                StatementContext.VariableService,
                StatementContext.TableService,
                exprEvaluatorContextStatement,
                StatementContext.EventAdapterService,
                StatementContext.StatementName,
                StatementContext.StatementId,
                StatementContext.Annotations,
                StatementContext.ContextDescriptor,
                StatementContext.ScriptingService,
                false, false, true, false, null, false);

            // determine whether column names are provided
            // if the "values" keyword was used, allow sequential automatic name assignment
            string[] assignedSequentialNames = null;
            if (StatementSpec.InsertIntoDesc.ColumnNames.IsEmpty())
            {
                var insert = (FireAndForgetSpecInsert)StatementSpec.FireAndForgetSpec;
                if (insert.IsUseValuesKeyword)
                {
                    assignedSequentialNames = Processor.EventTypePublic.PropertyNames;
                }
            }

            var count = -1;

            foreach (var compiled in StatementSpec.SelectClauseSpec.SelectExprList)
            {
                count++;
                if (compiled is SelectClauseExprCompiledSpec)
                {
                    var      expr = (SelectClauseExprCompiledSpec)compiled;
                    ExprNode validatedExpression = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.SELECT, expr.SelectExpression, validationContext);
                    expr.SelectExpression = validatedExpression;
                    if (expr.AssignedName == null)
                    {
                        if (expr.ProvidedName == null)
                        {
                            if (assignedSequentialNames != null && count < assignedSequentialNames.Length)
                            {
                                expr.AssignedName = assignedSequentialNames[count];
                            }
                            else
                            {
                                expr.AssignedName = ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(expr.SelectExpression);
                            }
                        }
                        else
                        {
                            expr.AssignedName = expr.ProvidedName;
                        }
                    }
                }
            }

            EventType optionalInsertIntoEventType = Processor.EventTypeResultSetProcessor;
            var       selectExprEventTypeRegistry = new SelectExprEventTypeRegistry(StatementContext.StatementName, StatementContext.StatementEventTypeRef);
            var       insertHelper = SelectExprProcessorFactory.GetProcessor(
                Collections.SingletonList(0),
                selectNoWildcard.ToArray(), false,
                StatementSpec.InsertIntoDesc, optionalInsertIntoEventType, null, streamTypeService,
                StatementContext.EventAdapterService,
                StatementContext.StatementResultService,
                StatementContext.ValueAddEventService, selectExprEventTypeRegistry,
                StatementContext.EngineImportService, exprEvaluatorContextStatement,
                StatementContext.VariableService,
                StatementContext.ScriptingService,
                StatementContext.TableService,
                StatementContext.TimeProvider,
                StatementContext.EngineURI,
                StatementContext.StatementId,
                StatementContext.StatementName,
                StatementContext.Annotations,
                StatementContext.ContextDescriptor,
                StatementContext.ConfigSnapshot, null,
                StatementContext.NamedWindowMgmtService, null, null,
                StatementContext.StatementExtensionServicesContext);

            return(new EPPreparedExecuteIUDSingleStreamExecInsert(exprEvaluatorContextStatement, insertHelper, StatementSpec.TableNodes, Services));
        }
Ejemplo n.º 14
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.º 15
0
        /// <summary>
        /// Validates expression nodes and returns a list of validated nodes.
        /// </summary>
        /// <param name="exprNodeOrigin">The expr node origin.</param>
        /// <param name="exprNodes">is the nodes to validate</param>
        /// <param name="streamTypeService">is provding type information for each stream</param>
        /// <param name="statementContext">context</param>
        /// <param name="taggedEventTypes">pattern tagged types</param>
        /// <param name="arrayEventTypes">@return list of validated expression nodes</param>
        /// <returns>
        /// expr nodes
        /// </returns>
        /// <exception cref="ExprValidationException">
        /// Failed to validate  + EPStatementStartMethodHelperSubselect.GetSubqueryInfoText(count, subselect) + :  + ex.Message
        /// or
        /// Filter expression not returning a boolean value: ' + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(validated) + '
        /// </exception>
        /// <throws>ExprValidationException for validation errors</throws>
        public static IList <ExprNode> ValidateAllowSubquery(
            ExprNodeOrigin exprNodeOrigin,
            IList <ExprNode> exprNodes,
            StreamTypeService streamTypeService,
            StatementContext statementContext,
            IDictionary <string, Pair <EventType, string> > taggedEventTypes,
            IDictionary <string, Pair <EventType, string> > arrayEventTypes)
        {
            IList <ExprNode> validatedNodes = new List <ExprNode>();

            var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);
            var validationContext    = new ExprValidationContext(
                streamTypeService, statementContext.MethodResolutionService, null, statementContext.TimeProvider,
                statementContext.VariableService,
                statementContext.TableService,
                evaluatorContextStmt,
                statementContext.EventAdapterService,
                statementContext.StatementName,
                statementContext.StatementId,
                statementContext.Annotations,
                statementContext.ContextDescriptor,
                statementContext.ScriptingService,
                false, false, true, false, null, true);

            foreach (var node in exprNodes)
            {
                // Determine subselects
                var visitor = new ExprNodeSubselectDeclaredDotVisitor();
                node.Accept(visitor);

                // Compile subselects
                if (!visitor.Subselects.IsEmpty())
                {
                    // The outer event type is the filtered-type itself
                    var subselectStreamNumber = 2048;
                    var count = -1;
                    foreach (var subselect in visitor.Subselects)
                    {
                        count++;
                        subselectStreamNumber++;
                        try {
                            HandleSubselectSelectClauses(subselectStreamNumber, statementContext, subselect,
                                                         streamTypeService.EventTypes[0], streamTypeService.StreamNames[0], streamTypeService.StreamNames[0],
                                                         taggedEventTypes, arrayEventTypes);
                        }
                        catch (ExprValidationException ex) {
                            throw new ExprValidationException("Failed to validate " + EPStatementStartMethodHelperSubselect.GetSubqueryInfoText(count, subselect) + ": " + ex.Message, ex);
                        }
                    }
                }

                var validated = ExprNodeUtility.GetValidatedSubtree(exprNodeOrigin, node, validationContext);
                validatedNodes.Add(validated);

                if ((validated.ExprEvaluator.ReturnType != typeof(bool?)) && ((validated.ExprEvaluator.ReturnType != typeof(bool))))
                {
                    throw new ExprValidationException("Filter expression not returning a boolean value: '" + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(validated) + "'");
                }
            }

            return(validatedNodes);
        }
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));
        }
        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="statementSpec">
        /// is a container for the definition of all statement constructs that may have been used in the
        /// statement, i.e. if defines the select clauses, insert into, outer joins etc.
        /// </param>
        /// <param name="services">is the service instances for dependency injection</param>
        /// <param name="statementContext">is statement-level information and statement services</param>
        /// <throws>ExprValidationException if the preparation failed</throws>
        public EPPreparedExecuteMethodQuery(
            StatementSpecCompiled statementSpec,
            EPServicesContext services,
            StatementContext statementContext)
        {
            var queryPlanLogging = services.ConfigSnapshot.EngineDefaults.Logging.IsEnableQueryPlan;

            if (queryPlanLogging)
            {
                QueryPlanLog.Info("Query plans for Fire-and-forget query '" + statementContext.Expression + "'");
            }

            _hasTableAccess = (statementSpec.TableNodes != null && statementSpec.TableNodes.Length > 0);
            foreach (var streamSpec in statementSpec.StreamSpecs)
            {
                _hasTableAccess |= streamSpec is TableQueryStreamSpec;
            }

            _statementSpec = statementSpec;
            _services      = services;

            EPPreparedExecuteMethodHelper.ValidateFAFQuery(statementSpec);

            var numStreams     = statementSpec.StreamSpecs.Length;
            var typesPerStream = new EventType[numStreams];
            var namesPerStream = new string[numStreams];

            _processors           = new FireAndForgetProcessor[numStreams];
            _agentInstanceContext = new AgentInstanceContext(statementContext, null, -1, null, null, statementContext.DefaultAgentInstanceScriptContext);

            // resolve types and processors
            for (var i = 0; i < numStreams; i++)
            {
                var streamSpec = statementSpec.StreamSpecs[i];
                _processors[i] = FireAndForgetProcessorFactory.ValidateResolveProcessor(streamSpec, services);

                string streamName = _processors[i].NamedWindowOrTableName;
                if (streamSpec.OptionalStreamName != null)
                {
                    streamName = streamSpec.OptionalStreamName;
                }
                namesPerStream[i] = streamName;
                typesPerStream[i] = _processors[i].EventTypeResultSetProcessor;
            }

            // compile filter to optimize access to named window
            var types           = new StreamTypeServiceImpl(typesPerStream, namesPerStream, new bool[numStreams], services.EngineURI, false);
            var excludePlanHint = ExcludePlanHint.GetHint(types.StreamNames, statementContext);

            _queryGraph = new QueryGraph(numStreams, excludePlanHint, false);

            if (statementSpec.FilterRootNode != null)
            {
                for (var i = 0; i < numStreams; i++)
                {
                    try
                    {
                        ExprEvaluatorContextStatement evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);
                        ExprValidationContext         validationContext    = new ExprValidationContext(
                            statementContext.Container,
                            types,
                            statementContext.EngineImportService,
                            statementContext.StatementExtensionServicesContext, null,
                            statementContext.TimeProvider,
                            statementContext.VariableService,
                            statementContext.TableService, evaluatorContextStmt,
                            statementContext.EventAdapterService,
                            statementContext.StatementName,
                            statementContext.StatementId,
                            statementContext.Annotations,
                            statementContext.ContextDescriptor,
                            statementContext.ScriptingService,
                            false, false, true, false, null, true);
                        ExprNode validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.FILTER, statementSpec.FilterRootNode, validationContext);
                        FilterExprAnalyzer.Analyze(validated, _queryGraph, false);
                    }
                    catch (Exception ex)
                    {
                        Log.Warn("Unexpected exception analyzing filter paths: " + ex.Message, ex);
                    }
                }
            }

            // obtain result set processor
            var isIStreamOnly = new bool[namesPerStream.Length];

            CompatExtensions.Fill(isIStreamOnly, true);
            StreamTypeService typeService = new StreamTypeServiceImpl(typesPerStream, namesPerStream, isIStreamOnly, services.EngineURI, true);

            EPStatementStartMethodHelperValidate.ValidateNodes(statementSpec, statementContext, typeService, null);

            var resultSetProcessorPrototype = ResultSetProcessorFactoryFactory.GetProcessorPrototype(statementSpec, statementContext, typeService, null, new bool[0], true, ContextPropertyRegistryImpl.EMPTY_REGISTRY, null, services.ConfigSnapshot, services.ResultSetProcessorHelperFactory, true, false);

            _resultSetProcessor = EPStatementStartMethodHelperAssignExpr.GetAssignResultSetProcessor(_agentInstanceContext, resultSetProcessorPrototype, false, null, true);

            if (statementSpec.SelectClauseSpec.IsDistinct)
            {
                if (_resultSetProcessor.ResultEventType is EventTypeSPI)
                {
                    _eventBeanReader = ((EventTypeSPI)_resultSetProcessor.ResultEventType).Reader;
                }
                if (_eventBeanReader == null)
                {
                    _eventBeanReader = new EventBeanReaderDefaultImpl(_resultSetProcessor.ResultEventType);
                }
            }

            // check context partition use
            if (statementSpec.OptionalContextName != null)
            {
                if (numStreams > 1)
                {
                    throw new ExprValidationException("Joins in runtime queries for context partitions are not supported");
                }
            }

            // plan joins or simple queries
            if (numStreams > 1)
            {
                var streamJoinAnalysisResult = new StreamJoinAnalysisResult(numStreams);
                CompatExtensions.Fill(streamJoinAnalysisResult.NamedWindow, true);
                for (var i = 0; i < numStreams; i++)
                {
                    var processorInstance = _processors[i].GetProcessorInstance(_agentInstanceContext);
                    if (_processors[i].IsVirtualDataWindow)
                    {
                        streamJoinAnalysisResult.ViewExternal[i] = agentInstanceContext => processorInstance.VirtualDataWindow;
                    }
                    var uniqueIndexes = _processors[i].GetUniqueIndexes(processorInstance);
                    streamJoinAnalysisResult.UniqueKeys[i] = uniqueIndexes;
                }

                var hasAggregations = !resultSetProcessorPrototype.AggregationServiceFactoryDesc.Expressions.IsEmpty();

                _joinSetComposerPrototype = JoinSetComposerPrototypeFactory.MakeComposerPrototype(null, -1,
                                                                                                  statementSpec.OuterJoinDescList, statementSpec.FilterRootNode, typesPerStream, namesPerStream,
                                                                                                  streamJoinAnalysisResult, queryPlanLogging, statementContext, new HistoricalViewableDesc(numStreams),
                                                                                                  _agentInstanceContext, false, hasAggregations, services.TableService, true,
                                                                                                  services.EventTableIndexService.AllowInitIndex(false));
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="viewChain">views</param>
        /// <param name="matchRecognizeSpec">specification</param>
        /// <param name="agentInstanceContext">The agent instance context.</param>
        /// <param name="isUnbound">true for unbound stream</param>
        /// <param name="annotations">annotations</param>
        /// <exception cref="ExprValidationException">
        /// Variable ' + defineItem.Identifier + ' has already been defined
        /// or
        /// An aggregate function may not appear in a DEFINE clause
        /// or
        /// Failed to validate condition expression for variable ' + defineItem.Identifier + ':  + ex.Message
        /// or
        /// Aggregation functions in the measure-clause must only refer to properties of exactly one group variable returning multiple events
        /// or
        /// Aggregation functions in the measure-clause must refer to one or more properties of exactly one group variable returning multiple events
        /// or
        /// The measures clause requires that each expression utilizes the AS keyword to assign a column name
        /// </exception>
        /// <throws>ExprValidationException if validation fails</throws>
        public EventRowRegexNFAViewFactory(
            ViewFactoryChain viewChain,
            MatchRecognizeSpec matchRecognizeSpec,
            AgentInstanceContext agentInstanceContext,
            bool isUnbound,
            Attribute[] annotations,
            ConfigurationEngineDefaults.MatchRecognizeConfig matchRecognizeConfig)
        {
            var parentViewType = viewChain.EventType;

            _matchRecognizeSpec   = matchRecognizeSpec;
            _isUnbound            = isUnbound;
            _isIterateOnly        = HintEnum.ITERATE_ONLY.GetHint(annotations) != null;
            _matchRecognizeConfig = matchRecognizeConfig;

            var statementContext = agentInstanceContext.StatementContext;

            // Expand repeats and permutations
            _expandedPatternNode = RegexPatternExpandUtil.Expand(matchRecognizeSpec.Pattern);

            // Determine single-row and multiple-row variables
            _variablesSingle = new LinkedHashSet <string>();
            ISet <string> variablesMultiple = new LinkedHashSet <string>();

            EventRowRegexHelper.RecursiveInspectVariables(_expandedPatternNode, false, _variablesSingle, variablesMultiple);

            // each variable gets associated with a stream number (multiple-row variables as well to hold the current event for the expression).
            var streamNum = 0;

            _variableStreams = new LinkedHashMap <string, Pair <int, bool> >();
            foreach (var variableSingle in _variablesSingle)
            {
                _variableStreams.Put(variableSingle, new Pair <int, bool>(streamNum, false));
                streamNum++;
            }
            foreach (var variableMultiple in variablesMultiple)
            {
                _variableStreams.Put(variableMultiple, new Pair <int, bool>(streamNum, true));
                streamNum++;
            }

            // mapping of stream to variable
            _streamVariables = new SortedDictionary <int, string>();
            foreach (var entry in _variableStreams)
            {
                _streamVariables.Put(entry.Value.First, entry.Key);
            }

            // determine visibility rules
            var visibility = EventRowRegexHelper.DetermineVisibility(_expandedPatternNode);

            // assemble all single-row variables for expression validation
            var allStreamNames = new string[_variableStreams.Count];
            var allTypes       = new EventType[_variableStreams.Count];

            streamNum = 0;
            foreach (var variableSingle in _variablesSingle)
            {
                allStreamNames[streamNum] = variableSingle;
                allTypes[streamNum]       = parentViewType;
                streamNum++;
            }
            foreach (var variableMultiple in variablesMultiple)
            {
                allStreamNames[streamNum] = variableMultiple;
                allTypes[streamNum]       = parentViewType;
                streamNum++;
            }

            // determine type service for use with DEFINE
            // validate each DEFINE clause expression
            ISet <string>             definedVariables = new HashSet <string>();
            IList <ExprAggregateNode> aggregateNodes   = new List <ExprAggregateNode>();
            var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false);

            _isExprRequiresMultimatchState = new bool[_variableStreams.Count];

            for (var defineIndex = 0; defineIndex < matchRecognizeSpec.Defines.Count; defineIndex++)
            {
                var defineItem = matchRecognizeSpec.Defines[defineIndex];
                if (definedVariables.Contains(defineItem.Identifier))
                {
                    throw new ExprValidationException("Variable '" + defineItem.Identifier + "' has already been defined");
                }
                definedVariables.Add(defineItem.Identifier);

                // stream-type visibilities handled here
                var typeServiceDefines = EventRowRegexNFAViewFactoryHelper.BuildDefineStreamTypeServiceDefine(statementContext, _variableStreams, defineItem, visibility, parentViewType);

                var exprNodeResult    = HandlePreviousFunctions(defineItem.Expression);
                var validationContext = new ExprValidationContext(
                    typeServiceDefines,
                    statementContext.EngineImportService,
                    statementContext.StatementExtensionServicesContext, null,
                    statementContext.SchedulingService,
                    statementContext.VariableService,
                    statementContext.TableService, exprEvaluatorContext,
                    statementContext.EventAdapterService,
                    statementContext.StatementName,
                    statementContext.StatementId,
                    statementContext.Annotations,
                    statementContext.ContextDescriptor,
                    statementContext.ScriptingService,
                    true, false, true, false, null, false);

                ExprNode validated;
                try {
                    // validate
                    validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.MATCHRECOGDEFINE, exprNodeResult, validationContext);

                    // check aggregates
                    defineItem.Expression = validated;
                    ExprAggregateNodeUtil.GetAggregatesBottomUp(validated, aggregateNodes);
                    if (!aggregateNodes.IsEmpty())
                    {
                        throw new ExprValidationException("An aggregate function may not appear in a DEFINE clause");
                    }
                }
                catch (ExprValidationException ex) {
                    throw new ExprValidationException("Failed to validate condition expression for variable '" + defineItem.Identifier + "': " + ex.Message, ex);
                }

                // determine access to event properties from multi-matches
                var visitor = new ExprNodeStreamRequiredVisitor();
                validated.Accept(visitor);
                var streamsRequired = visitor.StreamsRequired;
                foreach (var streamRequired in streamsRequired)
                {
                    if (streamRequired >= _variableStreams.Count)
                    {
                        var streamNumIdent = _variableStreams.Get(defineItem.Identifier).First;
                        _isExprRequiresMultimatchState[streamNumIdent] = true;
                        break;
                    }
                }
            }
            _isDefineAsksMultimatches  = CollectionUtil.IsAnySet(_isExprRequiresMultimatchState);
            _defineMultimatchEventBean = _isDefineAsksMultimatches ? EventRowRegexNFAViewFactoryHelper.GetDefineMultimatchBean(statementContext, _variableStreams, parentViewType) : null;

            // assign "prev" node indexes
            // Since an expression such as "prior(2, price), prior(8, price)" translates into {2, 8} the relative index is {0, 1}.
            // Map the expression-supplied index to a relative index
            var countPrev = 0;

            foreach (var entry in _callbacksPerIndex)
            {
                foreach (var callback in entry.Value)
                {
                    callback.AssignedIndex = countPrev;
                }
                countPrev++;
            }

            // determine type service for use with MEASURE
            IDictionary <string, object> measureTypeDef = new LinkedHashMap <string, object>();

            foreach (var variableSingle in _variablesSingle)
            {
                measureTypeDef.Put(variableSingle, parentViewType);
            }
            foreach (var variableMultiple in variablesMultiple)
            {
                measureTypeDef.Put(variableMultiple, new EventType[] { parentViewType });
            }
            var outputEventTypeName = statementContext.StatementId + "_rowrecog";

            _compositeEventType = (ObjectArrayEventType)statementContext.EventAdapterService.CreateAnonymousObjectArrayType(outputEventTypeName, measureTypeDef);
            StreamTypeService typeServiceMeasure = new StreamTypeServiceImpl(_compositeEventType, "MATCH_RECOGNIZE", true, statementContext.EngineURI);

            // find MEASURE clause aggregations
            var measureReferencesMultivar = false;
            IList <ExprAggregateNode> measureAggregateExprNodes = new List <ExprAggregateNode>();

            foreach (var measureItem in matchRecognizeSpec.Measures)
            {
                ExprAggregateNodeUtil.GetAggregatesBottomUp(measureItem.Expr, measureAggregateExprNodes);
            }
            if (!measureAggregateExprNodes.IsEmpty())
            {
                var isIStreamOnly = new bool[allStreamNames.Length];
                CompatExtensions.Fill(isIStreamOnly, true);
                var typeServiceAggregateMeasure  = new StreamTypeServiceImpl(allTypes, allStreamNames, isIStreamOnly, statementContext.EngineURI, false);
                var measureExprAggNodesPerStream = new Dictionary <int, IList <ExprAggregateNode> >();

                foreach (var aggregateNode in measureAggregateExprNodes)
                {
                    // validate absence of group-by
                    aggregateNode.ValidatePositionals();
                    if (aggregateNode.OptionalLocalGroupBy != null)
                    {
                        throw new ExprValidationException("Match-recognize does not allow aggregation functions to specify a group-by");
                    }

                    // validate node and params
                    var count   = 0;
                    var visitor = new ExprNodeIdentifierVisitor(true);

                    var validationContext = new ExprValidationContext(
                        typeServiceAggregateMeasure,
                        statementContext.EngineImportService,
                        statementContext.StatementExtensionServicesContext, null,
                        statementContext.SchedulingService,
                        statementContext.VariableService,
                        statementContext.TableService,
                        exprEvaluatorContext,
                        statementContext.EventAdapterService,
                        statementContext.StatementName,
                        statementContext.StatementId,
                        statementContext.Annotations,
                        statementContext.ContextDescriptor,
                        statementContext.ScriptingService,
                        false, false, true, false, null, false);
                    for (int ii = 0; ii < aggregateNode.ChildNodes.Count; ii++)
                    {
                        var child     = aggregateNode.ChildNodes[ii];
                        var validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.MATCHRECOGMEASURE, child, validationContext);
                        validated.Accept(visitor);
                        aggregateNode.SetChildNode(count++, new ExprNodeValidated(validated));
                    }
                    validationContext = new ExprValidationContext(
                        typeServiceMeasure,
                        statementContext.EngineImportService,
                        statementContext.StatementExtensionServicesContext, null,
                        statementContext.SchedulingService,
                        statementContext.VariableService,
                        statementContext.TableService,
                        exprEvaluatorContext,
                        statementContext.EventAdapterService,
                        statementContext.StatementName,
                        statementContext.StatementId,
                        statementContext.Annotations,
                        statementContext.ContextDescriptor,
                        statementContext.ScriptingService,
                        false, false, true, false, null, false);
                    aggregateNode.Validate(validationContext);

                    // verify properties used within the aggregation
                    var aggregatedStreams = new HashSet <int>();
                    foreach (var pair in visitor.ExprProperties)
                    {
                        aggregatedStreams.Add(pair.First);
                    }

                    int?multipleVarStream = null;
                    foreach (int streamNumAggregated in aggregatedStreams)
                    {
                        var variable = _streamVariables.Get(streamNumAggregated);
                        if (variablesMultiple.Contains(variable))
                        {
                            measureReferencesMultivar = true;
                            if (multipleVarStream == null)
                            {
                                multipleVarStream = streamNumAggregated;
                                continue;
                            }
                            throw new ExprValidationException("Aggregation functions in the measure-clause must only refer to properties of exactly one group variable returning multiple events");
                        }
                    }

                    if (multipleVarStream == null)
                    {
                        throw new ExprValidationException("Aggregation functions in the measure-clause must refer to one or more properties of exactly one group variable returning multiple events");
                    }

                    var aggNodesForStream = measureExprAggNodesPerStream.Get(multipleVarStream.Value);
                    if (aggNodesForStream == null)
                    {
                        aggNodesForStream = new List <ExprAggregateNode>();
                        measureExprAggNodesPerStream.Put(multipleVarStream.Value, aggNodesForStream);
                    }
                    aggNodesForStream.Add(aggregateNode);
                }

                var factoryDesc = AggregationServiceFactoryFactory.GetServiceMatchRecognize(_streamVariables.Count, measureExprAggNodesPerStream, typeServiceAggregateMeasure.EventTypes);
                _aggregationService     = factoryDesc.AggregationServiceFactory.MakeService(agentInstanceContext);
                _aggregationExpressions = factoryDesc.Expressions;
            }
            else
            {
                _aggregationService     = null;
                _aggregationExpressions = Collections.GetEmptyList <AggregationServiceAggExpressionDesc>();
            }

            // validate each MEASURE clause expression
            IDictionary <string, object> rowTypeDef = new LinkedHashMap <string, object>();
            var streamRefVisitor = new ExprNodeStreamUseCollectVisitor();

            foreach (var measureItem in matchRecognizeSpec.Measures)
            {
                if (measureItem.Name == null)
                {
                    throw new ExprValidationException("The measures clause requires that each expression utilizes the AS keyword to assign a column name");
                }
                var validated = ValidateMeasureClause(measureItem.Expr, typeServiceMeasure, variablesMultiple, _variablesSingle, statementContext);
                measureItem.Expr = validated;
                rowTypeDef.Put(measureItem.Name, validated.ExprEvaluator.ReturnType);
                validated.Accept(streamRefVisitor);
            }

            // Determine if any of the multi-var streams are referenced in the measures (non-aggregated only)
            foreach (var @ref in streamRefVisitor.Referenced)
            {
                var rootPropName = @ref.RootPropertyNameIfAny;
                if (rootPropName != null)
                {
                    if (variablesMultiple.Contains(rootPropName))
                    {
                        measureReferencesMultivar = true;
                        break;
                    }
                }

                var streamRequired = @ref.StreamReferencedIfAny;
                if (streamRequired != null)
                {
                    var streamVariable = _streamVariables.Get(streamRequired.Value);
                    if (streamVariable != null)
                    {
                        var def = _variableStreams.Get(streamVariable);
                        if (def != null && def.Second)
                        {
                            measureReferencesMultivar = true;
                            break;
                        }
                    }
                }
            }
            _isCollectMultimatches = measureReferencesMultivar || _isDefineAsksMultimatches;

            // create rowevent type
            var rowEventTypeName = statementContext.StatementId + "_rowrecogrow";

            _rowEventType = statementContext.EventAdapterService.CreateAnonymousMapType(rowEventTypeName, rowTypeDef, true);

            // validate partition-by expressions, if any
            if (!matchRecognizeSpec.PartitionByExpressions.IsEmpty())
            {
                var typeServicePartition = new StreamTypeServiceImpl(parentViewType, "MATCH_RECOGNIZE_PARTITION", true, statementContext.EngineURI);
                var validated            = new List <ExprNode>();
                var validationContext    = new ExprValidationContext(
                    typeServicePartition,
                    statementContext.EngineImportService,
                    statementContext.StatementExtensionServicesContext, null,
                    statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService,
                    exprEvaluatorContext, statementContext.EventAdapterService, statementContext.StatementName,
                    statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor,
                    statementContext.ScriptingService,
                    false, false, true, false, null, false);
                foreach (var partitionExpr in matchRecognizeSpec.PartitionByExpressions)
                {
                    validated.Add(ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.MATCHRECOGPARTITION, partitionExpr, validationContext));
                }
                matchRecognizeSpec.PartitionByExpressions = validated;
            }

            // validate interval if present
            if (matchRecognizeSpec.Interval != null)
            {
                var validationContext =
                    new ExprValidationContext(
                        new StreamTypeServiceImpl(statementContext.EngineURI, false),
                        statementContext.EngineImportService,
                        statementContext.StatementExtensionServicesContext, null,
                        statementContext.SchedulingService,
                        statementContext.VariableService, statementContext.TableService, exprEvaluatorContext,
                        statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId,
                        statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService,
                        false, false, true, false, null, false);
                matchRecognizeSpec.Interval.Validate(validationContext);
            }
        }
Ejemplo n.º 19
0
        public void Attach(EventType parentEventType, StatementContext statementContext, ViewFactory optionalParentFactory, IList <ViewFactory> parentViewFactories)
        {
            EventType = parentEventType;
            var message = NAME + " view requires a list of expressions providing unique keys, a numeric size parameter and a list of expressions providing sort keys";

            if (_viewParameters.Count < 3)
            {
                throw new ViewParameterException(message);
            }

            // validate
            var validated = ViewFactorySupport.Validate(NAME, parentEventType, statementContext, _viewParameters, true);

            // find size-parameter index
            var indexNumericSize = -1;

            for (var i = 0; i < validated.Length; i++)
            {
                if (validated[i] is ExprConstantNode)
                {
                    indexNumericSize = i;
                    break;
                }
            }
            if (indexNumericSize == -1)
            {
                throw new ViewParameterException("Failed to find constant value for the numeric size parameter");
            }
            if (indexNumericSize == 0)
            {
                throw new ViewParameterException("Failed to find unique value expressions that are expected to occur before the numeric size parameter");
            }
            if (indexNumericSize == validated.Length - 1)
            {
                throw new ViewParameterException("Failed to find sort key expressions after the numeric size parameter");
            }

            // validate non-constant for unique-keys and sort-keys
            for (var i = 0; i < indexNumericSize; i++)
            {
                ViewFactorySupport.AssertReturnsNonConstant(NAME, validated[i], i);
            }
            for (var i = indexNumericSize + 1; i < validated.Length; i++)
            {
                ViewFactorySupport.AssertReturnsNonConstant(NAME, validated[i], i);
            }

            // get sort size
            var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false);
            var sortSize             = ViewFactorySupport.EvaluateAssertNoProperties(NAME, validated[indexNumericSize], indexNumericSize, exprEvaluatorContext);

            if ((sortSize == null) || (!sortSize.IsNumber()))
            {
                throw new ViewParameterException(message);
            }
            SortWindowSize = sortSize.AsInt();

            // compile unique expressions
            uniqueCriteriaExpressions = new ExprNode[indexNumericSize];
            Array.Copy(validated, 0, uniqueCriteriaExpressions, 0, indexNumericSize);

            // compile sort expressions
            sortCriteriaExpressions = new ExprNode[validated.Length - indexNumericSize - 1];
            IsDescendingValues      = new bool[sortCriteriaExpressions.Length];

            var count = 0;

            for (var i = indexNumericSize + 1; i < validated.Length; i++)
            {
                if (validated[i] is ExprOrderedExpr)
                {
                    IsDescendingValues[count]      = ((ExprOrderedExpr)validated[i]).IsDescending;
                    sortCriteriaExpressions[count] = validated[i].ChildNodes[0];
                }
                else
                {
                    sortCriteriaExpressions[count] = validated[i];
                }
                count++;
            }

            UniqueEvals = ExprNodeUtility.GetEvaluators(uniqueCriteriaExpressions);
            SortEvals   = ExprNodeUtility.GetEvaluators(sortCriteriaExpressions);

            if (statementContext.ConfigSnapshot != null)
            {
                IsUseCollatorSort = statementContext.ConfigSnapshot.EngineDefaults.LanguageConfig.IsSortUsingCollator;
            }
        }
        internal static UniformPair <int?> ValidateOuterJoinPropertyPair(
            StatementContext statementContext,
            ExprIdentNode leftNode,
            ExprIdentNode rightNode,
            int outerJoinCount,
            StreamTypeService typeService,
            ViewResourceDelegateUnverified viewResourceDelegate)
        {
            // Validate the outer join clause using an artificial equals-node on top.
            // Thus types are checked via equals.
            // Sets stream ids used for validated nodes.
            ExprNode equalsNode = new ExprEqualsNodeImpl(false, false);

            equalsNode.AddChildNode(leftNode);
            equalsNode.AddChildNode(rightNode);
            var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);

            try
            {
                var validationContext = new ExprValidationContext(
                    typeService,
                    statementContext.MethodResolutionService, viewResourceDelegate,
                    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);
                ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.JOINON, equalsNode, validationContext);
            }
            catch (ExprValidationException ex)
            {
                Log.Debug("Validation exception for outer join node=" + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(equalsNode), ex);
                throw new EPStatementException("Error validating expression: " + ex.Message, statementContext.Expression);
            }

            // Make sure we have left-hand-side and right-hand-side refering to different streams
            var streamIdLeft  = leftNode.StreamId;
            var streamIdRight = rightNode.StreamId;

            if (streamIdLeft == streamIdRight)
            {
                const string message = "Outer join ON-clause cannot refer to properties of the same stream";
                throw new EPStatementException("Error validating expression: " + message, statementContext.Expression);
            }

            // Make sure one of the properties refers to the acutual stream currently being joined
            var expectedStreamJoined = outerJoinCount + 1;

            if ((streamIdLeft != expectedStreamJoined) && (streamIdRight != expectedStreamJoined))
            {
                var message = "Outer join ON-clause must refer to at least one property of the joined stream" +
                              " for stream " + expectedStreamJoined;
                throw new EPStatementException("Error validating expression: " + message, statementContext.Expression);
            }

            // Make sure neither of the streams refer to a 'future' stream
            String badPropertyName = null;

            if (streamIdLeft > outerJoinCount + 1)
            {
                badPropertyName = leftNode.ResolvedPropertyName;
            }
            if (streamIdRight > outerJoinCount + 1)
            {
                badPropertyName = rightNode.ResolvedPropertyName;
            }
            if (badPropertyName != null)
            {
                var message = "Outer join ON-clause invalid scope for property" +
                              " '" + badPropertyName + "', expecting the current or a prior stream scope";
                throw new EPStatementException("Error validating expression: " + message, statementContext.Expression);
            }

            return(new UniformPair <int?>(streamIdLeft, streamIdRight));
        }
        public override EPStatementStartResult StartInternal(
            EPServicesContext services,
            StatementContext statementContext,
            bool isNewStatement,
            bool isRecoveringStatement,
            bool isRecoveringResilient)
        {
            var createDesc = _statementSpec.CreateVariableDesc;

            VariableServiceUtil.CheckAlreadyDeclaredTable(createDesc.VariableName, services.TableService);

            // Get assignment value
            object value = null;

            if (createDesc.Assignment != null)
            {
                // Evaluate assignment expression
                StreamTypeService typeService = new StreamTypeServiceImpl(
                    new EventType[0], new string[0], new bool[0], services.EngineURI, false);
                var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);
                var validationContext    = new ExprValidationContext(
                    typeService,
                    statementContext.MethodResolutionService, null,
                    statementContext.SchedulingService,
                    statementContext.VariableService,
                    statementContext.TableService, evaluatorContextStmt,
                    statementContext.EventAdapterService,
                    statementContext.StatementName, statementContext.StatementId,
                    statementContext.Annotations,
                    statementContext.ContextDescriptor,
                    statementContext.ScriptingService,
                    false, false, false, false, null, false);
                var validated = ExprNodeUtility.GetValidatedSubtree(
                    ExprNodeOrigin.VARIABLEASSIGN, createDesc.Assignment, validationContext);
                value = validated.ExprEvaluator.Evaluate(new EvaluateParams(null, true, evaluatorContextStmt));
            }

            // Create variable
            try
            {
                services.VariableService.CreateNewVariable(
                    _statementSpec.OptionalContextName, createDesc.VariableName, createDesc.VariableType, createDesc.IsConstant,
                    createDesc.IsArray, createDesc.IsArrayOfPrimitive, value, services.EngineImportService);
            }
            catch (VariableExistsException ex)
            {
                // for new statement we don't allow creating the same variable
                if (isNewStatement)
                {
                    throw new ExprValidationException("Cannot create variable: " + ex.Message, ex);
                }
            }
            catch (VariableDeclarationException ex)
            {
                throw new ExprValidationException("Cannot create variable: " + ex.Message, ex);
            }

            var destroyMethod = new EPStatementDestroyCallbackList();

            destroyMethod.AddCallback(new ProxyDestroyCallback(() =>
            {
                try
                {
                    services.StatementVariableRefService.RemoveReferencesStatement(statementContext.StatementName);
                }
                catch (Exception ex)
                {
                    Log.Error("Error removing variable '" + createDesc.VariableName + "': " + ex.Message);
                }
            }));

            var stopMethod = new ProxyEPStatementStopMethod(() => { });

            var      variableMetaData = services.VariableService.GetVariableMetaData(createDesc.VariableName);
            Viewable outputView;
            var      eventType = CreateVariableView.GetEventType(
                statementContext.StatementId, services.EventAdapterService, variableMetaData);
            var contextFactory =
                new StatementAgentInstanceFactoryCreateVariable(
                    createDesc, _statementSpec, statementContext, services, variableMetaData, eventType);

            statementContext.StatementAgentInstanceFactory = contextFactory;

            if (_statementSpec.OptionalContextName != null)
            {
                var mergeView = new ContextMergeView(eventType);
                outputView = mergeView;
                var statement =
                    new ContextManagedStatementCreateVariableDesc(_statementSpec, statementContext, mergeView, contextFactory);
                services.ContextManagementService.AddStatement(
                    _statementSpec.OptionalContextName, statement, isRecoveringResilient);

                var contextManagementService = services.ContextManagementService;
                destroyMethod.AddCallback(new ProxyDestroyCallback(() => contextManagementService.DestroyedStatement(
                                                                       _statementSpec.OptionalContextName, statementContext.StatementName,
                                                                       statementContext.StatementId)));
            }
            else
            {
                var resultOfStart =
                    (StatementAgentInstanceFactoryCreateVariableResult)
                    contextFactory.NewContext(GetDefaultAgentInstanceContext(statementContext), isRecoveringResilient);
                outputView = resultOfStart.FinalView;

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

            services.StatementVariableRefService.AddReferences(
                statementContext.StatementName, Collections.SingletonList(createDesc.VariableName), null);
            return(new EPStatementStartResult(outputView, stopMethod, destroyMethod));
        }
Ejemplo n.º 22
0
        public override EPStatementStartResult StartInternal(EPServicesContext services, StatementContext statementContext, bool isNewStatement, bool isRecoveringStatement, bool isRecoveringResilient)
        {
            // define stop and destroy
            var stopCallbacks    = new List <StopCallback>();
            var destroyCallbacks = new EPStatementDestroyCallbackList();

            // determine context
            var contextName = StatementSpec.OptionalContextName;

            if (contextName != null)
            {
                throw new ExprValidationException("Update IStream is not supported in conjunction with a context");
            }

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

            var    streamSpec = StatementSpec.StreamSpecs[0];
            var    updateSpec = StatementSpec.UpdateSpec;
            String triggereventTypeName;

            if (streamSpec is FilterStreamSpecCompiled)
            {
                var filterStreamSpec = (FilterStreamSpecCompiled)streamSpec;
                triggereventTypeName = filterStreamSpec.FilterSpec.FilterForEventTypeName;
            }
            else if (streamSpec is NamedWindowConsumerStreamSpec)
            {
                var namedSpec = (NamedWindowConsumerStreamSpec)streamSpec;
                triggereventTypeName = namedSpec.WindowName;
            }
            else if (streamSpec is TableQueryStreamSpec)
            {
                throw new ExprValidationException("Tables cannot be used in an update-istream statement");
            }
            else
            {
                throw new ExprValidationException("Unknown stream specification streamEventType: " + streamSpec);
            }

            // determine a stream name
            var streamName = triggereventTypeName;

            if (updateSpec.OptionalStreamName != null)
            {
                streamName = updateSpec.OptionalStreamName;
            }

            var streamEventType           = services.EventAdapterService.GetEventTypeByName(triggereventTypeName);
            StreamTypeService typeService = new StreamTypeServiceImpl(new EventType[] { streamEventType }, new String[] { streamName }, new bool[] { true }, services.EngineURI, false);

            // determine subscriber result types
            var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);

            statementContext.StatementResultService.SetSelectClause(new Type[] { streamEventType.UnderlyingType }, new String[] { "*" }, false, null, evaluatorContextStmt);

            // Materialize sub-select views
            var subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.PlanSubSelect(services, statementContext, IsQueryPlanLogging(services), subSelectStreamDesc, new String[] { streamName }, new EventType[] { streamEventType }, new String[] { triggereventTypeName }, StatementSpec.DeclaredExpressions, null);

            var validationContext = new ExprValidationContext(
                typeService,
                statementContext.MethodResolutionService, null,
                statementContext.SchedulingService,
                statementContext.VariableService,
                statementContext.TableService,
                evaluatorContextStmt,
                statementContext.EventAdapterService,
                statementContext.StatementName,
                statementContext.StatementId,
                statementContext.Annotations,
                statementContext.ContextDescriptor,
                statementContext.ScriptingService,
                false, false, false, false,
                null, false);

            foreach (var assignment in updateSpec.Assignments)
            {
                var validated = ExprNodeUtility.GetValidatedAssignment(assignment, validationContext);
                assignment.Expression = validated;
                EPStatementStartMethodHelperValidate.ValidateNoAggregations(validated, "Aggregation functions may not be used within an update-clause");
            }
            if (updateSpec.OptionalWhereClause != null)
            {
                var validated = ExprNodeUtility.GetValidatedSubtree(
                    ExprNodeOrigin.WHERE, updateSpec.OptionalWhereClause, validationContext);
                updateSpec.OptionalWhereClause = validated;
                EPStatementStartMethodHelperValidate.ValidateNoAggregations(validated, "Aggregation functions may not be used within an update-clause");
            }

            // preprocessing view
            var onExprView = new InternalRoutePreprocessView(streamEventType, statementContext.StatementResultService);

            // validation
            var routerDesc = services.InternalEventRouter.GetValidatePreprocessing(onExprView.EventType, updateSpec, statementContext.Annotations);

            // create context factory
            var contextFactory = new StatementAgentInstanceFactoryUpdate(statementContext, services, streamEventType, updateSpec, onExprView, routerDesc, subSelectStrategyCollection);

            // perform start of hook-up to start
            Viewable finalViewable;
            EPStatementStopMethod stopStatementMethod;
            IDictionary <ExprSubselectNode, SubSelectStrategyHolder> subselectStrategyInstances;

            // With context - delegate instantiation to context
            EPStatementStopMethod stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks).Stop;

            if (StatementSpec.OptionalContextName != null)
            {
                // use statement-wide agent-instance-specific subselects
                var aiRegistryExpr = statementContext.StatementAgentInstanceRegistry.AgentInstanceExprService;
                subselectStrategyInstances = new Dictionary <ExprSubselectNode, SubSelectStrategyHolder>();
                foreach (var node in subSelectStrategyCollection.Subqueries.Keys)
                {
                    var specificService = aiRegistryExpr.AllocateSubselect(node);
                    node.Strategy = specificService;
                    subselectStrategyInstances.Put(node, new SubSelectStrategyHolder(null, null, null, null, null, null));
                }

                var mergeView = new ContextMergeView(onExprView.EventType);
                finalViewable = mergeView;

                var statement = new ContextManagedStatementOnTriggerDesc(StatementSpec, statementContext, mergeView, contextFactory);
                services.ContextManagementService.AddStatement(StatementSpec.OptionalContextName, statement, isRecoveringResilient);
                stopStatementMethod = () =>
                {
                    services.ContextManagementService.StoppedStatement(contextName, statementContext.StatementName, statementContext.StatementId);
                    stopMethod.Invoke();
                };

                destroyCallbacks.AddCallback(EPStatementDestroyCallbackContext.New(
                                                 services.ContextManagementService,
                                                 StatementSpec.OptionalContextName,
                                                 statementContext.StatementName,
                                                 statementContext.StatementId));
            }
            // Without context - start here
            else
            {
                var agentInstanceContext = GetDefaultAgentInstanceContext(statementContext);
                var resultOfStart        = (StatementAgentInstanceFactoryUpdateResult)
                                           contextFactory.NewContext(agentInstanceContext, isRecoveringResilient);
                finalViewable       = resultOfStart.FinalView;
                stopStatementMethod = new EPStatementStopMethod(() =>
                {
                    resultOfStart.StopCallback.Invoke();
                    stopMethod.Invoke();
                });
                subselectStrategyInstances = resultOfStart.SubselectStrategies;
            }

            // assign subquery nodes
            EPStatementStartMethodHelperAssignExpr.AssignSubqueryStrategies(subSelectStrategyCollection, subselectStrategyInstances);

            return(new EPStatementStartResult(finalViewable, stopStatementMethod, destroyCallbacks.Destroy));
        }
        public override EPStatementStartResult StartInternal(EPServicesContext services, StatementContext statementContext, bool isNewStatement, bool isRecoveringStatement, bool isRecoveringResilient)
        {
            var createDesc = StatementSpec.CreateVariableDesc;

            VariableServiceUtil.CheckAlreadyDeclaredTable(createDesc.VariableName, services.TableService);

            // Get assignment value
            Object value = null;

            if (createDesc.Assignment != null)
            {
                // Evaluate assignment expression
                var typeService          = new StreamTypeServiceImpl(new EventType[0], new String[0], new bool[0], services.EngineURI, false);
                var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);
                var validationContext    = new ExprValidationContext(
                    typeService,
                    statementContext.MethodResolutionService, null,
                    statementContext.SchedulingService,
                    statementContext.VariableService,
                    statementContext.TableService, evaluatorContextStmt,
                    statementContext.EventAdapterService,
                    statementContext.StatementName,
                    statementContext.StatementId,
                    statementContext.Annotations,
                    statementContext.ContextDescriptor,
                    statementContext.ScriptingService,
                    false, false, false, false, null, false);
                var validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.VARIABLEASSIGN, createDesc.Assignment, validationContext);
                value = validated.ExprEvaluator.Evaluate(new EvaluateParams(null, true, evaluatorContextStmt));
            }

            // Create variable
            try
            {
                services.VariableService.CreateNewVariable(
                    StatementSpec.OptionalContextName,
                    createDesc.VariableName,
                    createDesc.VariableType,
                    createDesc.IsConstant,
                    createDesc.IsArray,
                    createDesc.IsArrayOfPrimitive,
                    value,
                    services.EngineImportService);
            }
            catch (VariableExistsException ex)
            {
                // for new statement we don't allow creating the same variable
                if (isNewStatement)
                {
                    throw new ExprValidationException("Cannot create variable: " + ex.Message, ex);
                }
            }
            catch (VariableDeclarationException ex)
            {
                throw new ExprValidationException("Cannot create variable: " + ex.Message, ex);
            }

            var destroyMethod = new EPStatementDestroyCallbackList();

            destroyMethod.AddCallback(
                () =>
            {
                try
                {
                    services.StatementVariableRefService.RemoveReferencesStatement(statementContext.StatementName);
                }
                catch (Exception ex)
                {
                    Log.Error("Error removing variable '" + createDesc.VariableName + "': " + ex.Message);
                }
            });

            var stopMethod = new EPStatementStopMethod(() => { });

            VariableMetaData variableMetaData = services.VariableService.GetVariableMetaData(createDesc.VariableName);
            Viewable         outputView;

            if (StatementSpec.OptionalContextName != null)
            {
                EventType eventType      = CreateVariableView.GetEventType(statementContext.StatementId, services.EventAdapterService, variableMetaData);
                var       contextFactory = new StatementAgentInstanceFactoryCreateVariable(statementContext, services, variableMetaData, eventType);
                var       mergeView      = new ContextMergeView(eventType);
                outputView = mergeView;
                var statement = new ContextManagedStatementCreateVariableDesc(StatementSpec, statementContext, mergeView, contextFactory);
                services.ContextManagementService.AddStatement(StatementSpec.OptionalContextName, statement, isRecoveringResilient);

                ContextManagementService contextManagementService = services.ContextManagementService;
                destroyMethod.AddCallback(() => contextManagementService.DestroyedStatement(StatementSpec.OptionalContextName, statementContext.StatementName, statementContext.StatementId));
            }
            else
            {
                // allocate
                services.VariableService.AllocateVariableState(createDesc.VariableName, VariableServiceConstants.NOCONTEXT_AGENTINSTANCEID, statementContext.StatementExtensionServicesContext);
                var createView = new CreateVariableView(statementContext.StatementId, services.EventAdapterService, services.VariableService, createDesc.VariableName, statementContext.StatementResultService);

                services.VariableService.RegisterCallback(createDesc.VariableName, 0, createView.Update);
                statementContext.StatementStopService.StatementStopped +=
                    () => services.VariableService.UnregisterCallback(createDesc.VariableName, 0, createView.Update);

                // Create result set processor, use wildcard selection
                StatementSpec.SelectClauseSpec.SetSelectExprList(new SelectClauseElementWildcard());
                StatementSpec.SelectStreamDirEnum = SelectClauseStreamSelectorEnum.RSTREAM_ISTREAM_BOTH;
                StreamTypeService typeService   = new StreamTypeServiceImpl(new EventType[] { createView.EventType }, new String[] { "create_variable" }, new bool[] { true }, services.EngineURI, false);
                var agentInstanceContext        = GetDefaultAgentInstanceContext(statementContext);
                var resultSetProcessorPrototype = ResultSetProcessorFactoryFactory.GetProcessorPrototype(
                    StatementSpec, statementContext, typeService, null, new bool[0], true, ContextPropertyRegistryImpl.EMPTY_REGISTRY, null, services.ConfigSnapshot);
                var resultSetProcessor = EPStatementStartMethodHelperAssignExpr.GetAssignResultSetProcessor(agentInstanceContext, resultSetProcessorPrototype);

                // Attach output view
                var outputViewFactory = OutputProcessViewFactoryFactory.Make(StatementSpec, services.InternalEventRouter, agentInstanceContext.StatementContext, resultSetProcessor.ResultEventType, null, services.TableService, resultSetProcessorPrototype.ResultSetProcessorFactory.ResultSetProcessorType);
                var outputViewBase    = outputViewFactory.MakeView(resultSetProcessor, agentInstanceContext);
                createView.AddView(outputViewBase);
                outputView = outputViewBase;
            }

            services.StatementVariableRefService.AddReferences(statementContext.StatementName, Collections.SingletonList(createDesc.VariableName), null);

            return(new EPStatementStartResult(outputView, stopMethod, destroyMethod.Destroy));
        }
        /// <summary>
        /// Validate filter and join expression nodes.
        /// </summary>
        /// <param name="statementSpec">the compiled statement</param>
        /// <param name="statementContext">the statement services</param>
        /// <param name="typeService">the event types for streams</param>
        /// <param name="viewResourceDelegate">the delegate to verify expressions that use view resources</param>
        internal static void ValidateNodes(
            StatementSpecCompiled statementSpec,
            StatementContext statementContext,
            StreamTypeService typeService,
            ViewResourceDelegateUnverified viewResourceDelegate)
        {
            var methodResolutionService = statementContext.MethodResolutionService;
            var evaluatorContextStmt    = new ExprEvaluatorContextStatement(statementContext, false);
            var intoTableName           = statementSpec.IntoTableSpec == null ? null : statementSpec.IntoTableSpec.Name;

            if (statementSpec.FilterRootNode != null)
            {
                var optionalFilterNode = statementSpec.FilterRootNode;

                // Validate where clause, initializing nodes to the stream ids used
                try
                {
                    var validationContext = new ExprValidationContext(
                        typeService,
                        methodResolutionService,
                        viewResourceDelegate,
                        statementContext.SchedulingService,
                        statementContext.VariableService,
                        statementContext.TableService,
                        evaluatorContextStmt,
                        statementContext.EventAdapterService,
                        statementContext.StatementName,
                        statementContext.StatementId,
                        statementContext.Annotations,
                        statementContext.ContextDescriptor,
                        statementContext.ScriptingService,
                        false, false, true, false,
                        intoTableName, false);
                    optionalFilterNode = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.FILTER, optionalFilterNode, validationContext);
                    if (optionalFilterNode.ExprEvaluator.ReturnType != typeof(bool) && optionalFilterNode.ExprEvaluator.ReturnType != typeof(bool?))
                    {
                        throw new ExprValidationException("The where-clause filter expression must return a boolean value");
                    }
                    statementSpec.FilterExprRootNode = optionalFilterNode;

                    // Make sure there is no aggregation in the where clause
                    var aggregateNodes = new List <ExprAggregateNode>();
                    ExprAggregateNodeUtil.GetAggregatesBottomUp(optionalFilterNode, aggregateNodes);
                    if (!aggregateNodes.IsEmpty())
                    {
                        throw new ExprValidationException("An aggregate function may not appear in a WHERE clause (use the HAVING clause)");
                    }
                }
                catch (ExprValidationException ex)
                {
                    Log.Debug(".validateNodes Validation exception for filter=" + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(optionalFilterNode), ex);
                    throw new EPStatementException("Error validating expression: " + ex.Message, ex, statementContext.Expression);
                }
            }

            if ((statementSpec.OutputLimitSpec != null) && ((statementSpec.OutputLimitSpec.WhenExpressionNode != null) || (statementSpec.OutputLimitSpec.AndAfterTerminateExpr != null)))
            {
                // Validate where clause, initializing nodes to the stream ids used
                try
                {
                    var outputLimitType = OutputConditionExpressionFactory.GetBuiltInEventType(statementContext.EventAdapterService);
                    StreamTypeService typeServiceOutputWhen = new StreamTypeServiceImpl(new EventType[] { outputLimitType }, new String[] { null }, new bool[] { true }, statementContext.EngineURI, false);
                    var validationContext = new ExprValidationContext(
                        typeServiceOutputWhen,
                        methodResolutionService, null,
                        statementContext.SchedulingService,
                        statementContext.VariableService,
                        statementContext.TableService,
                        evaluatorContextStmt,
                        statementContext.EventAdapterService,
                        statementContext.StatementName,
                        statementContext.StatementId,
                        statementContext.Annotations,
                        statementContext.ContextDescriptor,
                        statementContext.ScriptingService,
                        false, false, false, false,
                        intoTableName, false);

                    var outputLimitWhenNode = statementSpec.OutputLimitSpec.WhenExpressionNode;
                    if (outputLimitWhenNode != null)
                    {
                        outputLimitWhenNode = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, outputLimitWhenNode, validationContext);
                        statementSpec.OutputLimitSpec.WhenExpressionNode = outputLimitWhenNode;

                        if (TypeHelper.GetBoxedType(outputLimitWhenNode.ExprEvaluator.ReturnType) != typeof(bool?))
                        {
                            throw new ExprValidationException("The when-trigger expression in the OUTPUT WHEN clause must return a boolean-type value");
                        }
                        EPStatementStartMethodHelperValidate.ValidateNoAggregations(outputLimitWhenNode, "An aggregate function may not appear in a OUTPUT LIMIT clause");
                    }

                    // validate and-terminate expression if provided
                    if (statementSpec.OutputLimitSpec.AndAfterTerminateExpr != null)
                    {
                        if (statementSpec.OutputLimitSpec.RateType != OutputLimitRateType.WHEN_EXPRESSION && statementSpec.OutputLimitSpec.RateType != OutputLimitRateType.TERM)
                        {
                            throw new ExprValidationException("A terminated-and expression must be used with the OUTPUT WHEN clause");
                        }
                        var validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, statementSpec.OutputLimitSpec.AndAfterTerminateExpr, validationContext);
                        statementSpec.OutputLimitSpec.AndAfterTerminateExpr = validated;

                        if (validated.ExprEvaluator.ReturnType.GetBoxedType() != typeof(bool?))
                        {
                            throw new ExprValidationException("The terminated-and expression must return a boolean-type value");
                        }
                        EPStatementStartMethodHelperValidate.ValidateNoAggregations(validated, "An aggregate function may not appear in a terminated-and clause");
                    }

                    // validate then-expression
                    ValidateThenSetAssignments(statementSpec.OutputLimitSpec.ThenExpressions, validationContext);

                    // validate after-terminated then-expression
                    ValidateThenSetAssignments(statementSpec.OutputLimitSpec.AndAfterTerminateThenExpressions, validationContext);
                }
                catch (ExprValidationException ex)
                {
                    throw new EPStatementException("Error validating expression: " + ex.Message, statementContext.Expression);
                }
            }

            for (var outerJoinCount = 0; outerJoinCount < statementSpec.OuterJoinDescList.Length; outerJoinCount++)
            {
                var outerJoinDesc = statementSpec.OuterJoinDescList[outerJoinCount];

                // validate on-expression nodes, if provided
                if (outerJoinDesc.OptLeftNode != null)
                {
                    var streamIdPair = ValidateOuterJoinPropertyPair(statementContext, outerJoinDesc.OptLeftNode, outerJoinDesc.OptRightNode, outerJoinCount,
                                                                     typeService, viewResourceDelegate);

                    if (outerJoinDesc.AdditionalLeftNodes != null)
                    {
                        ISet <int?> streamSet = new HashSet <int?>();
                        streamSet.Add(streamIdPair.First);
                        streamSet.Add(streamIdPair.Second);
                        for (var i = 0; i < outerJoinDesc.AdditionalLeftNodes.Length; i++)
                        {
                            var streamIdPairAdd = ValidateOuterJoinPropertyPair(statementContext, outerJoinDesc.AdditionalLeftNodes[i], outerJoinDesc.AdditionalRightNodes[i], outerJoinCount,
                                                                                typeService, viewResourceDelegate);

                            // make sure all additional properties point to the same two streams
                            if ((!streamSet.Contains(streamIdPairAdd.First) || (!streamSet.Contains(streamIdPairAdd.Second))))
                            {
                                const string message = "Outer join ON-clause columns must refer to properties of the same joined streams" +
                                                       " when using multiple columns in the on-clause";
                                throw new EPStatementException("Error validating expression: " + message, statementContext.Expression);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 25
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.º 26
0
        private PatternStreamSpecCompiled CompileInternal(
            StatementContext context,
            ICollection <string> eventTypeReferences,
            bool isInsertInto,
            ICollection <int> assignedTypeNumberStack,
            MatchEventSpec tags,
            IEnumerable <string> priorAllTags,
            bool isJoin,
            bool isContextDeclaration,
            bool isOnTrigger)
        {
            // validate
            if ((_suppressSameEventMatches || _discardPartialsOnMatch) &&
                (isJoin || isContextDeclaration || isOnTrigger))
            {
                throw new ExprValidationException(
                          "Discard-partials and suppress-matches is not supported in a joins, context declaration and on-action");
            }

            if (tags == null)
            {
                tags = new MatchEventSpec();
            }
            var subexpressionIdStack = new ArrayDeque <int>(assignedTypeNumberStack);
            var evaluatorContextStmt = new ExprEvaluatorContextStatement(context, false);
            var nodeStack            = new Stack <EvalFactoryNode>();

            // detemine ordered tags
            var filterFactoryNodes = EvalNodeUtil.RecursiveGetChildNodes(
                _evalFactoryNode, FilterForFilterFactoryNodes.INSTANCE);
            var allTagNamesOrdered = new LinkedHashSet <string>();

            if (priorAllTags != null)
            {
                allTagNamesOrdered.AddAll(priorAllTags);
            }
            foreach (var filterNode in filterFactoryNodes)
            {
                var factory = (EvalFilterFactoryNode)filterNode;
                int tagNumber;
                if (factory.EventAsName != null)
                {
                    if (!allTagNamesOrdered.Contains(factory.EventAsName))
                    {
                        allTagNamesOrdered.Add(factory.EventAsName);
                        tagNumber = allTagNamesOrdered.Count - 1;
                    }
                    else
                    {
                        tagNumber = FindTagNumber(factory.EventAsName, allTagNamesOrdered);
                    }
                    factory.EventAsTagNumber = tagNumber;
                }
            }

            RecursiveCompile(
                _evalFactoryNode, context, evaluatorContextStmt, eventTypeReferences, isInsertInto, tags,
                subexpressionIdStack, nodeStack, allTagNamesOrdered);

            var auditPattern            = AuditEnum.PATTERN.GetAudit(context.Annotations);
            var auditPatternInstance    = AuditEnum.PATTERNINSTANCES.GetAudit(context.Annotations);
            var compiledEvalFactoryNode = _evalFactoryNode;

            if (context.PatternNodeFactory.IsAuditSupported && (auditPattern != null || auditPatternInstance != null))
            {
                var instanceCount = new EvalAuditInstanceCount();
                compiledEvalFactoryNode = RecursiveAddAuditNode(
                    context.PatternNodeFactory, null, auditPattern != null, auditPatternInstance != null,
                    _evalFactoryNode, instanceCount);
            }

            return(new PatternStreamSpecCompiled(
                       compiledEvalFactoryNode, tags.TaggedEventTypes, tags.ArrayEventTypes, allTagNamesOrdered, ViewSpecs,
                       OptionalStreamName, Options, _suppressSameEventMatches, _discardPartialsOnMatch));
        }
Ejemplo n.º 27
0
 public ViewableActivator CreateStreamReuseView(EPServicesContext services, StatementContext statementContext, StatementSpecCompiled statementSpec, FilterStreamSpecCompiled filterStreamSpec, bool isJoin, ExprEvaluatorContextStatement evaluatorContextStmt, bool filterSubselectSameStream, int streamNum, bool isCanIterateUnbound)
 {
     return(new ViewableActivatorStreamReuseView(services, statementContext, statementSpec, filterStreamSpec, isJoin, evaluatorContextStmt, filterSubselectSameStream, streamNum, isCanIterateUnbound));
 }