public FilterExprAnalyzerAffector GetFilterExprAnalyzerAffector()
        {
            var visitor = new ExprNodeIdentifierAndStreamRefVisitor(false);

            foreach (ExprNode lhsNode in _lhs)
            {
                lhsNode.Accept(visitor);
            }

            var indexedPropertyStreams = new HashSet <int>();

            foreach (ExprNodePropOrStreamDesc @ref in visitor.GetRefs())
            {
                indexedPropertyStreams.Add(@ref.StreamNum);
            }

            if (indexedPropertyStreams.Count == 0 || indexedPropertyStreams.Count > 1)
            {
                return
                    (null); // there are no properties from any streams that could be used for building an index, or the properties come from different disjoint streams
            }

            var streamNumIndex = indexedPropertyStreams.First();

            var keyExpressions = new List <Pair <ExprNode, int[]> >();
            var dependencies   = new HashSet <int>();

            foreach (ExprNode node in _rhs)
            {
                visitor.Reset();
                dependencies.Clear();
                node.Accept(visitor);

                foreach (ExprNodePropOrStreamDesc @ref in visitor.GetRefs())
                {
                    dependencies.Add(@ref.StreamNum);
                }

                if (dependencies.Contains(streamNumIndex))
                {
                    return(null);
                }

                var pair = new Pair <ExprNode, int[]>(node, CollectionUtil.IntArray(dependencies));
                keyExpressions.Add(pair);
            }

            return(new FilterExprAnalyzerAffectorIndexProvision(OperationName, _lhs, keyExpressions, streamNumIndex));
        }
Example #2
0
        private static EventAdvancedIndexProvisionDesc ValidateAdvanced(
            string indexName,
            string indexType,
            CreateIndexItem columnDesc,
            EventType eventType,
            StatementContext statementContext)
        {
            // validate index expressions: valid and plain expressions
            ExprValidationContext validationContextColumns = GetValidationContext(eventType, statementContext);

            ExprNode[] columns = columnDesc.Expressions.ToArray();
            ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.CREATEINDEXCOLUMN, columns, validationContextColumns);
            ExprNodeUtility.ValidatePlainExpression(ExprNodeOrigin.CREATEINDEXCOLUMN, columns);

            // validate parameters, may not depend on props
            ExprNode[] parameters = null;
            if (columnDesc.Parameters != null && !columnDesc.Parameters.IsEmpty())
            {
                parameters = columnDesc.Parameters.ToArray();
                ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.CREATEINDEXPARAMETER, parameters, validationContextColumns);
                ExprNodeUtility.ValidatePlainExpression(ExprNodeOrigin.CREATEINDEXPARAMETER, parameters);

                // validate no stream dependency of parameters
                var visitor = new ExprNodeIdentifierAndStreamRefVisitor(false);
                foreach (ExprNode param in columnDesc.Parameters)
                {
                    param.Accept(visitor);
                    if (!visitor.GetRefs().IsEmpty())
                    {
                        throw new ExprValidationException("Index parameters may not refer to event properties");
                    }
                }
            }

            // obtain provider
            AdvancedIndexFactoryProvider provider;

            try {
                provider = statementContext.EngineImportService.ResolveAdvancedIndexProvider(indexType);
            } catch (EngineImportException ex) {
                throw new ExprValidationException(ex.Message, ex);
            }

            return(provider.ValidateEventIndex(indexName, indexType, columns, parameters));
        }