public static T DeepCopy <T>(T value, DeepCopyOptions options = DeepCopyOptions.DeepCopier)
 {
     return(options switch
     {
         DeepCopyOptions.DeepCopier => DeepCopier.Copy(value),
         DeepCopyOptions.ExpressionCopier => ExpressionCopier <T> .Copy(value),
         _ => ExpressionCopier <T> .Copy(value)
     });
 public RowRecogExprNode Copy(
     RowRecogExprNode nodeToCopy,
     RowRecogNFATypeEnum newType,
     ExpressionCopier expressionCopier)
 {
     var atom = (RowRecogExprNodeAtom) nodeToCopy;
     return new RowRecogExprNodeAtom(atom.Tag, newType, null);
 }
示例#3
0
        public RowRecogExprNode CheckedCopy(ExpressionCopier expressionCopier)
        {
            var copy = CheckedCopySelf(expressionCopier);
            foreach (var child in ChildNodes) {
                var childCopy = child.CheckedCopy(expressionCopier);
                copy.AddChildNode(childCopy);
            }

            return copy;
        }
            public RowRecogExprNode Copy(
                RowRecogExprNode nodeToCopy,
                RowRecogNFATypeEnum newType,
                ExpressionCopier expressionCopier)
            {
                var nested = (RowRecogExprNodeNested) nodeToCopy;
                var nestedCopy = new RowRecogExprNodeNested(newType, null);
                foreach (var inner in nested.ChildNodes) {
                    var innerCopy = inner.CheckedCopy(expressionCopier);
                    nestedCopy.AddChildNode(innerCopy);
                }

                return nestedCopy;
            }
        private static RowRecogExprNodeAlteration ExpandPermute(
            RowRecogExprNodePermute permute, 
            ExpressionCopier expressionCopier)
        {
            var e = PermutationEnumerator.Create(permute.ChildNodes.Count);
            var parent = new RowRecogExprNodeAlteration();
            foreach (var indexes in e) {
                var concat = new RowRecogExprNodeConcatenation();
                parent.AddChildNode(concat);
                for (var i = 0; i < indexes.Length; i++) {
                    var toCopy = permute.ChildNodes[indexes[i]];
                    var copy = toCopy.CheckedCopy(expressionCopier);
                    concat.AddChildNode(copy);
                }
            }

            return parent;
        }
示例#6
0
 public abstract RowRecogExprNode CheckedCopySelf(ExpressionCopier expressionCopier);
示例#7
0
 private static ExprNode CopyVisitExpression(
     ExprNode expression,
     ExpressionCopier expressionCopier)
 {
     return expressionCopier.Copy(expression);
 }
示例#8
0
        public static GroupByClauseExpressions GetGroupByRollupExpressions(
            IList<GroupByClauseElement> groupByElements,
            SelectClauseSpecRaw selectClauseSpec,
            ExprNode optionalHavingNode,
            IList<OrderByItem> orderByList,
            ExpressionCopier expressionCopier)
        {
            if (groupByElements == null || groupByElements.Count == 0) {
                return null;
            }

            // walk group-by-elements, determine group-by expressions and rollup nodes
            var groupByExpressionInfo = GroupByToRollupNodes(groupByElements);

            // obtain expression nodes, collect unique nodes and assign index
            IList<ExprNode> distinctGroupByExpressions = new List<ExprNode>();
            IDictionary<ExprNode, int> expressionToIndex = new Dictionary<ExprNode, int>();
            foreach (var exprNode in groupByExpressionInfo.Expressions) {
                var found = false;
                for (var i = 0; i < distinctGroupByExpressions.Count; i++) {
                    ExprNode other = distinctGroupByExpressions[i];
                    // find same expression
                    if (ExprNodeUtilityCompare.DeepEquals(exprNode, other, false)) {
                        expressionToIndex.Put(exprNode, i);
                        found = true;
                        break;
                    }
                }

                // not seen before
                if (!found) {
                    expressionToIndex.Put(exprNode, distinctGroupByExpressions.Count);
                    distinctGroupByExpressions.Add(exprNode);
                }
            }

            // determine rollup, validate it is either (not both)
            var hasGroupingSet = false;
            var hasRollup = false;
            foreach (var element in groupByElements) {
                if (element is GroupByClauseElementGroupingSet) {
                    hasGroupingSet = true;
                }

                if (element is GroupByClauseElementRollupOrCube) {
                    hasRollup = true;
                }
            }

            // no-rollup or grouping-sets means simply validate
            ExprNode[] groupByExpressions = distinctGroupByExpressions.ToArray();
            if (!hasRollup && !hasGroupingSet) {
                return new GroupByClauseExpressions(groupByExpressions);
            }

            // evaluate rollup node roots
            var nodes = groupByExpressionInfo.Nodes;
            var perNodeCombinations = new object[nodes.Count][];
            var context = new GroupByRollupEvalContext(expressionToIndex);
            try {
                for (var i = 0; i < nodes.Count; i++) {
                    GroupByRollupNodeBase node = nodes[i];
                    var combinations = node.Evaluate(context);
                    perNodeCombinations[i] = new object[combinations.Count];
                    for (var j = 0; j < combinations.Count; j++) {
                        perNodeCombinations[i][j] = combinations[j];
                    }
                }
            }
            catch (GroupByRollupDuplicateException ex) {
                if (ex.Indexes.Length == 0) {
                    throw new ExprValidationException(
                        "Failed to validate the group-by clause, found duplicate specification of the overall grouping '()'");
                }

                var writer = new StringWriter();
                var delimiter = "";
                for (var i = 0; i < ex.Indexes.Length; i++) {
                    writer.Write(delimiter);
                    writer.Write(
                        ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(groupByExpressions[ex.Indexes[i]]));
                    delimiter = ", ";
                }

                throw new ExprValidationException(
                    "Failed to validate the group-by clause, found duplicate specification of expressions (" +
                    writer +
                    ")");
            }

            // enumerate combinations building an index list
            var combinationEnumeration = new CombinationEnumeration(perNodeCombinations);
            var combination = new SortedSet<int>();
            var indexList = new LinkedHashSet<MultiKeyArrayInt>();
            while (combinationEnumeration.MoveNext()) {
                combination.Clear();
                object[] combinationOA = combinationEnumeration.Current;
                foreach (var indexes in combinationOA) {
                    var indexarr = (int[]) indexes;
                    foreach (var anIndex in indexarr) {
                        combination.Add(anIndex);
                    }
                }

                var indexArr = CollectionUtil.IntArray(combination);
                indexList.Add(new MultiKeyArrayInt(indexArr));
            }

            // obtain rollup levels
            var rollupLevels = new int[indexList.Count][];
            var count = 0;
            foreach (var mk in indexList) {
                rollupLevels[count++] = mk.Keys;
            }

            var numberOfLevels = rollupLevels.Length;
            if (numberOfLevels == 1 && rollupLevels[0].Length == 0) {
                throw new ExprValidationException(
                    "Failed to validate the group-by clause, the overall grouping '()' cannot be the only grouping");
            }

            // obtain select-expression copies for rewrite
            var expressions = selectClauseSpec.SelectExprList;
            var selects = new ExprNode[numberOfLevels][];
            for (var i = 0; i < numberOfLevels; i++) {
                selects[i] = new ExprNode[expressions.Count];
                for (var j = 0; j < expressions.Count; j++) {
                    SelectClauseElementRaw selectRaw = expressions[j];
                    if (!(selectRaw is SelectClauseExprRawSpec)) {
                        throw new ExprValidationException(
                            "Group-by with rollup requires that the select-clause does not use wildcard");
                    }

                    var compiled = (SelectClauseExprRawSpec) selectRaw;
                    selects[i][j] = CopyVisitExpression(compiled.SelectExpression, expressionCopier);
                }
            }

            // obtain having-expression copies for rewrite
            ExprNode[] optHavingNodeCopy = null;
            if (optionalHavingNode != null) {
                optHavingNodeCopy = new ExprNode[numberOfLevels];
                for (var i = 0; i < numberOfLevels; i++) {
                    optHavingNodeCopy[i] = CopyVisitExpression(optionalHavingNode, expressionCopier);
                }
            }

            // obtain orderby-expression copies for rewrite
            ExprNode[][] optOrderByCopy = null;
            if (orderByList != null && orderByList.Count > 0) {
                optOrderByCopy = new ExprNode[numberOfLevels][];
                for (var i = 0; i < numberOfLevels; i++) {
                    optOrderByCopy[i] = new ExprNode[orderByList.Count];
                    for (var j = 0; j < orderByList.Count; j++) {
                        OrderByItem element = orderByList[j];
                        optOrderByCopy[i][j] = CopyVisitExpression(element.ExprNode, expressionCopier);
                    }
                }
            }

            return new GroupByClauseExpressions(
                groupByExpressions,
                rollupLevels,
                selects,
                optHavingNodeCopy,
                optOrderByCopy);
        }
示例#9
0
 public override RowRecogExprNode CheckedCopySelf(ExpressionCopier expressionCopier)
 {
     return new RowRecogExprNodeNested(Type, OptionalRepeat == null ? null : OptionalRepeat.CheckedCopy(expressionCopier));
 }
 public override RowRecogExprNode CheckedCopySelf(ExpressionCopier expressionCopier)
 {
     return new RowRecogExprNodeConcatenation();
 }
示例#11
0
        public static RowRecogExprNode Expand(
            RowRecogExprNode pattern,
            ExpressionCopier expressionCopier)
        {
            var visitor = new RowRecogExprNodeVisitorRepeat();
            pattern.Accept(visitor);
            var newParentNode = pattern;

            // expand permutes
            var permutes = visitor.Permutes;
            permutes.SortInPlace(
                (
                    o1,
                    o2) => {
                    if (o1.Level > o2.Level) {
                        return -1;
                    }

                    return o1.Level == o2.Level ? 0 : 1;
                });

            foreach (var permute in permutes) {
                var alteration = ExpandPermute(permute.Permute, expressionCopier);
                var optionalNewParent = Replace(
                    permute.OptionalParent,
                    permute.Permute,
                    Collections.SingletonList<RowRecogExprNode>(alteration));
                if (optionalNewParent != null) {
                    newParentNode = optionalNewParent;
                }
            }

            // expand atoms
            var atomPairs = visitor.Atoms;
            foreach (var pair in atomPairs) {
                var atom = pair.First;
                var expandedRepeat = ExpandRepeat(atom, atom.OptionalRepeat, atom.Type, ATOM_HANDLER, expressionCopier);
                var optionalNewParent = Replace(pair.Second, pair.First, expandedRepeat);
                if (optionalNewParent != null) {
                    newParentNode = optionalNewParent;
                }
            }

            // expand nested
            var nestedPairs = visitor.Nesteds;
            nestedPairs.SortInPlace(
                (
                    o1,
                    o2) => {
                    if (o1.Level > o2.Level) {
                        return -1;
                    }

                    return o1.Level == o2.Level ? 0 : 1;
                });

            foreach (var pair in nestedPairs) {
                var nested = pair.Nested;
                var expandedRepeat = ExpandRepeat(
                    nested,
                    nested.OptionalRepeat,
                    nested.Type,
                    NESTED_HANDLER,
                    expressionCopier);
                
                var optionalNewParent = Replace(pair.OptionalParent, pair.Nested, expandedRepeat);
                if (optionalNewParent != null) {
                    newParentNode = optionalNewParent;
                }
            }

            return newParentNode;
        }
示例#12
0
        private static IList<RowRecogExprNode> ExpandRepeat(
            RowRecogExprNode node,
            RowRecogExprRepeatDesc repeat,
            RowRecogNFATypeEnum type,
            RowRegexExprNodeCopier copier, 
            ExpressionCopier expressionCopier)
        {
            // handle single-bounds (no ranges)
            IList<RowRecogExprNode> repeated = new List<RowRecogExprNode>();
            if (repeat.Single != null) {
                ValidateExpression(repeat.Single);
                var numRepeated = (int) repeat.Single.Forge.ExprEvaluator.Evaluate(null, true, null);
                ValidateRange(numRepeated, 1, int.MaxValue);
                for (var i = 0; i < numRepeated; i++) {
                    var copy = copier.Copy(node, type, expressionCopier);
                    repeated.Add(copy);
                }

                return repeated;
            }

            // evaluate bounds
            int? lower = null;
            int? upper = null;
            if (repeat.Lower != null) {
                ValidateExpression(repeat.Lower);
                lower = (int?) repeat.Lower.Forge.ExprEvaluator.Evaluate(null, true, null);
            }

            if (repeat.Upper != null) {
                ValidateExpression(repeat.Upper);
                upper = (int?) repeat.Upper.Forge.ExprEvaluator.Evaluate(null, true, null);
            }

            // handle range
            if (lower != null && upper != null) {
                ValidateRange(lower.Value, 1, int.MaxValue);
                ValidateRange(upper.Value, 1, int.MaxValue);
                ValidateRange(lower.Value, 1, upper.Value);
                for (var i = 0; i < lower; i++) {
                    var copy = copier.Copy(node, type, expressionCopier);
                    repeated.Add(copy);
                }

                for (var i = lower.Value; i < upper; i++) {
                    // makeInline type optional
                    var newType = type;
                    if (type == RowRecogNFATypeEnum.SINGLE) {
                        newType = RowRecogNFATypeEnum.ONE_OPTIONAL;
                    }
                    else if (type == RowRecogNFATypeEnum.ONE_TO_MANY) {
                        newType = RowRecogNFATypeEnum.ZERO_TO_MANY;
                    }
                    else if (type == RowRecogNFATypeEnum.ONE_TO_MANY_RELUCTANT) {
                        newType = RowRecogNFATypeEnum.ZERO_TO_MANY_RELUCTANT;
                    }

                    var copy = copier.Copy(node, newType, expressionCopier);
                    repeated.Add(copy);
                }

                return repeated;
            }

            // handle lower-bounds only
            if (upper == null) {
                ValidateRange(lower.Value, 1, int.MaxValue);
                for (var i = 0; i < lower; i++) {
                    repeated.Add(copier.Copy(node, type, expressionCopier));
                }

                // makeInline type optional
                var newType = type;
                if (type == RowRecogNFATypeEnum.SINGLE) {
                    newType = RowRecogNFATypeEnum.ZERO_TO_MANY;
                }
                else if (type == RowRecogNFATypeEnum.ONE_OPTIONAL) {
                    newType = RowRecogNFATypeEnum.ZERO_TO_MANY;
                }
                else if (type == RowRecogNFATypeEnum.ONE_OPTIONAL_RELUCTANT) {
                    newType = RowRecogNFATypeEnum.ZERO_TO_MANY_RELUCTANT;
                }
                else if (type == RowRecogNFATypeEnum.ONE_TO_MANY) {
                    newType = RowRecogNFATypeEnum.ZERO_TO_MANY;
                }
                else if (type == RowRecogNFATypeEnum.ONE_TO_MANY_RELUCTANT) {
                    newType = RowRecogNFATypeEnum.ZERO_TO_MANY_RELUCTANT;
                }

                var copy = copier.Copy(node, newType, expressionCopier);
                repeated.Add(copy);
                return repeated;
            }

            // handle upper-bounds only
            ValidateRange(upper.Value, 1, int.MaxValue);
            for (var i = 0; i < upper; i++) {
                // makeInline type optional
                var newType = type;
                if (type == RowRecogNFATypeEnum.SINGLE) {
                    newType = RowRecogNFATypeEnum.ONE_OPTIONAL;
                }
                else if (type == RowRecogNFATypeEnum.ONE_TO_MANY) {
                    newType = RowRecogNFATypeEnum.ZERO_TO_MANY;
                }
                else if (type == RowRecogNFATypeEnum.ONE_TO_MANY_RELUCTANT) {
                    newType = RowRecogNFATypeEnum.ZERO_TO_MANY_RELUCTANT;
                }

                var copy = copier.Copy(node, newType, expressionCopier);
                repeated.Add(copy);
            }

            return repeated;
        }
示例#13
0
        public static StatementSpecCompiled Compile(
            StatementSpecRaw spec,
            Compilable compilable,
            bool isSubquery,
            bool isOnDemandQuery,
            Attribute[] annotations,
            IList<ExprSubselectNode> subselectNodes,
            IList<ExprTableAccessNode> tableAccessNodes,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices compileTimeServices)
        {
            IList<StreamSpecCompiled> compiledStreams;
            ISet<string> eventTypeReferences = new HashSet<string>();

            if (!isOnDemandQuery && spec.FireAndForgetSpec != null) {
                throw new StatementSpecCompileException(
                    "Provided EPL expression is an on-demand query expression (not a continuous query)",
                    compilable.ToEPL());
            }

            // If not using a join and not specifying a data window, make the where-clause, if present, the filter of the stream
            // if selecting using filter spec, and not subquery in where clause
            if (spec.StreamSpecs.Count == 1 &&
                spec.StreamSpecs[0] is FilterStreamSpecRaw &&
                spec.StreamSpecs[0].ViewSpecs.Length == 0 &&
                spec.WhereClause != null &&
                spec.OnTriggerDesc == null &&
                !isSubquery &&
                !isOnDemandQuery &&
                (tableAccessNodes == null || tableAccessNodes.IsEmpty())) {
                bool disqualified;
                ExprNode whereClause = spec.WhereClause;

                var visitorX = new ExprNodeSubselectDeclaredDotVisitor();
                whereClause.Accept(visitorX);
                disqualified = visitorX.Subselects.Count > 0 ||
                               HintEnum.DISABLE_WHEREEXPR_MOVETO_FILTER.GetHint(annotations) != null;

                if (!disqualified) {
                    var viewResourceVisitor = new ExprNodeViewResourceVisitor();
                    whereClause.Accept(viewResourceVisitor);
                    disqualified = viewResourceVisitor.ExprNodes.Count > 0;
                }

                if (!disqualified) {
                    spec.WhereClause = null;
                    var streamSpec = (FilterStreamSpecRaw) spec.StreamSpecs[0];
                    streamSpec.RawFilterSpec.FilterExpressions.Add(whereClause);
                }
            }

            // compile select-clause
            var selectClauseCompiled = CompileSelectClause(spec.SelectClauseSpec);

            // Determine subselects in filter streams, these may need special handling for locking
            var visitor = new ExprNodeSubselectDeclaredDotVisitor();
            try {
                StatementSpecRawWalkerSubselectAndDeclaredDot.WalkStreamSpecs(spec, visitor);
            }
            catch (ExprValidationException ex) {
                throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL());
            }

            foreach (var subselectNode in visitor.Subselects) {
                subselectNode.IsFilterStreamSubselect = true;
            }

            // Determine subselects for compilation, and lambda-expression shortcut syntax for named windows
            visitor.Reset();
            GroupByClauseExpressions groupByRollupExpressions;
            try {
                StatementSpecRawWalkerSubselectAndDeclaredDot.WalkSubselectAndDeclaredDotExpr(spec, visitor);

                var expressionCopier = new ExpressionCopier(
                    spec,
                    statementRawInfo.OptionalContextDescriptor,
                    compileTimeServices,
                    visitor);
                groupByRollupExpressions = GroupByExpressionHelper.GetGroupByRollupExpressions(
                    spec.GroupByExpressions,
                    spec.SelectClauseSpec,
                    spec.HavingClause,
                    spec.OrderByList,
                    expressionCopier);
            }
            catch (ExprValidationException ex) {
                throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL());
            }

            if (isSubquery && !visitor.Subselects.IsEmpty()) {
                throw new StatementSpecCompileException(
                    "Invalid nested subquery, subquery-within-subquery is not supported",
                    compilable.ToEPL());
            }

            if (isOnDemandQuery && !visitor.Subselects.IsEmpty()) {
                throw new StatementSpecCompileException(
                    "Subqueries are not a supported feature of on-demand queries",
                    compilable.ToEPL());
            }

            foreach (var subselectNode in visitor.Subselects) {
                if (!subselectNodes.Contains(subselectNode)) {
                    subselectNodes.Add(subselectNode);
                }
            }

            // Compile subselects found
            var subselectNumber = 0;
            foreach (var subselect in subselectNodes) {
                StatementSpecRaw raw = subselect.StatementSpecRaw;
                var compiled = Compile(
                    raw,
                    compilable,
                    true,
                    isOnDemandQuery,
                    annotations,
                    Collections.GetEmptyList<ExprSubselectNode>(),
                    Collections.GetEmptyList<ExprTableAccessNode>(),
                    statementRawInfo,
                    compileTimeServices);
                subselect.SetStatementSpecCompiled(compiled, subselectNumber);
                subselectNumber++;
            }

            // Set table-access number
            var tableAccessNumber = 0;
            foreach (var tableAccess in tableAccessNodes) {
                tableAccess.TableAccessNumber = tableAccessNumber;
                tableAccessNumber++;
            }

            // compile each stream used
            try {
                compiledStreams = new List<StreamSpecCompiled>(spec.StreamSpecs.Count);
                var streamNum = 0;
                foreach (var rawSpec in spec.StreamSpecs) {
                    streamNum++;
                    var compiled = StreamSpecCompiler.Compile(
                        rawSpec,
                        eventTypeReferences,
                        spec.InsertIntoDesc != null,
                        spec.StreamSpecs.Count > 1,
                        false,
                        spec.OnTriggerDesc != null,
                        rawSpec.OptionalStreamName,
                        streamNum,
                        statementRawInfo,
                        compileTimeServices);
                    compiledStreams.Add(compiled);
                }
            }
            catch (ExprValidationException ex) {
                if (ex.Message == null) {
                    throw new StatementSpecCompileException(
                        "Unexpected exception compiling statement, please consult the log file and report the exception",
                        ex,
                        compilable.ToEPL());
                }

                throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL());
            }
            catch (EPException ex) {
                throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL());
            }
            catch (Exception ex) {
                var text = "Unexpected error compiling statement";
                Log.Error(text, ex);
                throw new StatementSpecCompileException(
                    text + ": " + ex.GetType().Name + ":" + ex.Message,
                    ex,
                    compilable.ToEPL());
            }

            return new StatementSpecCompiled(
                spec,
                compiledStreams.ToArray(),
                selectClauseCompiled,
                annotations,
                groupByRollupExpressions,
                subselectNodes,
                visitor.DeclaredExpressions,
                tableAccessNodes);
        }
示例#14
0
 public RowRecogExprRepeatDesc CheckedCopy(ExpressionCopier expressionCopier) {
     ExprNode lowerCopy = Lower == null ? null : expressionCopier.Copy(Lower);
     ExprNode upperCopy = Upper == null ? null : expressionCopier.Copy(Upper);
     ExprNode singleCopy = Single == null ? null : expressionCopier.Copy(Single);
     return new RowRecogExprRepeatDesc(lowerCopy, upperCopy, singleCopy);
 }
示例#15
0
 public override RowRecogExprNode CheckedCopySelf(ExpressionCopier expressionCopier)
 {
     return new RowRecogExprNodePermute();
 }