コード例 #1
0
ファイル: QueryGraphValue.cs プロジェクト: ikvm/nesper
        public void AddRelOp(ExprNode propertyKey, QueryGraphRangeEnum op, ExprIdentNode propertyValueIdent, bool isBetweenOrIn)
        {
            // Note: Read as follows:
            // Console.WriteLine("If I have an index on '" + propertyValue + "' I'm evaluating " + propertyKey + " and finding all values of " + propertyValue + " " + op + " then " + propertyKey);

            // Check if there is an opportunity to convert this to a range or remove an earlier specification
            var existing = FindIdentEntry(propertyValueIdent);

            if (existing == null)
            {
                _items.Add(new QueryGraphValueDesc(new ExprNode[] { propertyValueIdent }, new QueryGraphValueEntryRangeRelOp(op, propertyKey, isBetweenOrIn)));
                return;
            }

            if (!(existing.Entry is QueryGraphValueEntryRangeRelOp))
            {
                return; // another comparison exists already, don't add range
            }

            var relOp   = (QueryGraphValueEntryRangeRelOp)existing.Entry;
            var opsDesc = QueryGraphRangeUtil.GetCanConsolidate(op, relOp.RangeType);

            if (opsDesc != null)
            {
                var start = !opsDesc.IsReverse ? relOp.Expression : propertyKey;
                var end   = !opsDesc.IsReverse ?  propertyKey : relOp.Expression;
                _items.Remove(existing);
                AddRange(opsDesc.RangeType, start, end, propertyValueIdent);
            }
        }
コード例 #2
0
 public QueryGraphRangeConsolidateDesc(
     QueryGraphRangeEnum type,
     bool reverse)
 {
     Type = type;
     IsReverse = reverse;
 }
コード例 #3
0
ファイル: QueryGraphRangeUtil.cs プロジェクト: valmac/nesper
 private static void Add(QueryGraphRangeEnum opOne, QueryGraphRangeEnum opTwo, QueryGraphRangeEnum range)
 {
     MultiKeyUntyped keyOne = GetKey(opOne, opTwo);
     OPS_TABLE.Put(keyOne, new QueryGraphRangeConsolidateDesc(range, false));
     MultiKeyUntyped keyRev = GetKey(opTwo, opOne);
     OPS_TABLE.Put(keyRev, new QueryGraphRangeConsolidateDesc(range, true));
 }
コード例 #4
0
        public static string StringOp(this QueryGraphRangeEnum value)
        {
            switch (value)
            {
                case QueryGraphRangeEnum.LESS:
                    return "<";
                case QueryGraphRangeEnum.LESS_OR_EQUAL:
                    return "<=";
                case QueryGraphRangeEnum.GREATER_OR_EQUAL:
                    return ">=";
                case QueryGraphRangeEnum.GREATER:
                    return ">";
                case QueryGraphRangeEnum.RANGE_OPEN:
                    return "(,)";
                case QueryGraphRangeEnum.RANGE_CLOSED:
                    return "[,]";
                case QueryGraphRangeEnum.RANGE_HALF_OPEN:
                    return "[,)";
                case QueryGraphRangeEnum.RANGE_HALF_CLOSED:
                    return "(,]";
                case QueryGraphRangeEnum.NOT_RANGE_OPEN:
                    return "-(,)";
                case QueryGraphRangeEnum.NOT_RANGE_CLOSED:
                    return "-[,]";
                case QueryGraphRangeEnum.NOT_RANGE_HALF_OPEN:
                    return "-[,)";
                case QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED:
                    return "-(,])";
            }

            throw new ArgumentException("invalid value", nameof(value));
        }
コード例 #5
0
 public static bool IsRangeInverted(this QueryGraphRangeEnum value)
 {
     return value.IsRange() &&
            (value == QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED ||
             value == QueryGraphRangeEnum.NOT_RANGE_HALF_OPEN ||
             value == QueryGraphRangeEnum.NOT_RANGE_OPEN ||
             value == QueryGraphRangeEnum.NOT_RANGE_CLOSED);
 }
コード例 #6
0
 public static bool IsRangeInverted(this QueryGraphRangeEnum @enum)
 {
     return(IsRange(@enum) &&
            (@enum == QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED ||
             @enum == QueryGraphRangeEnum.NOT_RANGE_HALF_OPEN ||
             @enum == QueryGraphRangeEnum.NOT_RANGE_OPEN ||
             @enum == QueryGraphRangeEnum.NOT_RANGE_CLOSED));
 }
コード例 #7
0
        private static void Add(QueryGraphRangeEnum opOne, QueryGraphRangeEnum opTwo, QueryGraphRangeEnum range)
        {
            MultiKeyUntyped keyOne = GetKey(opOne, opTwo);

            opsTable[keyOne] = new QueryGraphRangeConsolidateDesc(range, false);
            MultiKeyUntyped keyRev = GetKey(opTwo, opOne);

            opsTable[keyRev] = new QueryGraphRangeConsolidateDesc(range, true);
        }
コード例 #8
0
 public RangeIndexLookupValueRange(
     object value,
     QueryGraphRangeEnum @operator,
     bool allowRangeReverse)
     : base(value)
 {
     _operator = @operator;
     _isAllowRangeReverse = allowRangeReverse;
 }
コード例 #9
0
ファイル: QueryGraphRangeUtil.cs プロジェクト: valmac/nesper
 private static MultiKeyUntyped GetKey(QueryGraphRangeEnum op1, QueryGraphRangeEnum op2)
 {
     return new MultiKeyUntyped(
         new Object[]
         {
             op1,
             op2
         });
 }
コード例 #10
0
 public QueryGraphValueEntryRangeRelOp(QueryGraphRangeEnum type, ExprNode expression, bool isBetweenPart)
     : base(type)
 {
     if (type.IsRange())
     {
         throw new ArgumentException("Invalid ctor for use with ranges");
     }
     Expression    = expression;
     IsBetweenPart = isBetweenPart;
 }
コード例 #11
0
 public QueryGraphValueEntryRangeIn(QueryGraphRangeEnum rangeType, ExprNode exprStart, ExprNode exprEnd, bool allowRangeReversal)
     : base(rangeType)
 {
     if (!rangeType.IsRange())
     {
         throw new ArgumentException("Range type expected but received " + rangeType.GetName());
     }
     ExprStart            = exprStart;
     ExprEnd              = exprEnd;
     IsAllowRangeReversal = allowRangeReversal;
 }
コード例 #12
0
 public static bool IsIncludeEnd(this QueryGraphRangeEnum @enum)
 {
     if ([email protected]())
     {
         throw new UnsupportedOperationException("Cannot determine endpoint-end included for op " + @enum);
     }
     return(@enum == QueryGraphRangeEnum.RANGE_HALF_CLOSED ||
            @enum == QueryGraphRangeEnum.RANGE_CLOSED ||
            @enum == QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED ||
            @enum == QueryGraphRangeEnum.NOT_RANGE_CLOSED);
 }
コード例 #13
0
        public static bool IsIncludeEnd(this QueryGraphRangeEnum value)
        {
            if (!value.IsRange())
            {
                throw new UnsupportedOperationException("Cannot determine endpoint-end included for op " + value);
            }

            return value == QueryGraphRangeEnum.RANGE_HALF_CLOSED ||
                   value == QueryGraphRangeEnum.RANGE_CLOSED ||
                   value == QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED ||
                   value == QueryGraphRangeEnum.NOT_RANGE_CLOSED;
        }
コード例 #14
0
ファイル: QueryGraph.cs プロジェクト: ikvm/nesper
 private void InternalAddRange(int streamKey, int streamValue, QueryGraphRangeEnum rangeOp, ExprNode propertyStartExpr, ExprNode propertyEndExpr, ExprIdentNode propertyValueExpr)
 {
     if (_nToZeroAnalysis && streamValue != 0)
     {
         return;
     }
     if (_optionalHint != null && _optionalHint.Filter(streamKey, streamValue, ExcludePlanFilterOperatorType.RELOP))
     {
         return;
     }
     var valueLeft = GetCreateValue(streamKey, streamValue);
     valueLeft.AddRange(rangeOp, propertyStartExpr, propertyEndExpr, propertyValueExpr);
 }
コード例 #15
0
        internal void AddRangeStrict(
            int streamNumStart, ExprIdentNode propertyStartExpr,
            int streamNumEnd, ExprIdentNode propertyEndExpr,
            int streamNumValue, ExprIdentNode propertyValueExpr,
            QueryGraphRangeEnum rangeOp)
        {
            Check(streamNumStart, streamNumValue);
            Check(streamNumEnd, streamNumValue);

            // add as a range if the endpoints are from the same stream
            if (streamNumStart == streamNumEnd && streamNumStart != streamNumValue)
            {
                InternalAddRange(
                    streamNumStart, streamNumValue, rangeOp, propertyStartExpr, propertyEndExpr,
                    propertyValueExpr);
                InternalAddRelOp(
                    streamNumValue, streamNumStart, propertyValueExpr,
                    QueryGraphRangeEnum.GREATER_OR_EQUAL, propertyEndExpr, false);
                InternalAddRelOp(
                    streamNumValue, streamNumStart, propertyValueExpr, QueryGraphRangeEnum.LESS_OR_EQUAL,
                    propertyStartExpr, false);
            }
            else
            {
                // endpoints from a different stream, add individually
                if (streamNumValue != streamNumStart)
                {
                    // read propertyValue >= propertyStart
                    InternalAddRelOp(
                        streamNumStart, streamNumValue, propertyStartExpr,
                        QueryGraphRangeEnum.GREATER_OR_EQUAL, propertyValueExpr, true);
                    // read propertyStart <= propertyValue
                    InternalAddRelOp(
                        streamNumValue, streamNumStart, propertyValueExpr,
                        QueryGraphRangeEnum.LESS_OR_EQUAL, propertyStartExpr, true);
                }

                if (streamNumValue != streamNumEnd)
                {
                    // read propertyValue <= propertyEnd
                    InternalAddRelOp(
                        streamNumEnd, streamNumValue, propertyEndExpr, QueryGraphRangeEnum.LESS_OR_EQUAL,
                        propertyValueExpr, true);
                    // read propertyEnd >= propertyValue
                    InternalAddRelOp(
                        streamNumValue, streamNumEnd, propertyValueExpr,
                        QueryGraphRangeEnum.GREATER_OR_EQUAL, propertyEndExpr, true);
                }
            }
        }
コード例 #16
0
        private static RangeIndexLookupValue[] CompileRangeLookupValues(string[] rangeIndexProps, FilterSpecParam[] parameters, AgentInstanceContext agentInstanceContext)
        {
            var result = new RangeIndexLookupValue[rangeIndexProps.Length];

            for (var rangeIndex = 0; rangeIndex < rangeIndexProps.Length; rangeIndex++)
            {
                foreach (var param in parameters)
                {
                    if (!(param.Lookupable.Expression.Equals(rangeIndexProps[rangeIndex])))
                    {
                        continue;
                    }

                    if (param.FilterOperator == FilterOperator.EQUAL || param.FilterOperator == FilterOperator.IS)
                    {
                        result[rangeIndex] = new RangeIndexLookupValueEquals(param.GetFilterValue(null, agentInstanceContext));
                    }
                    else if (param.FilterOperator.IsRangeOperator() || param.FilterOperator.IsInvertedRangeOperator())
                    {
                        QueryGraphRangeEnum opAdd = param.FilterOperator.MapFrom();
                        result[rangeIndex] = new RangeIndexLookupValueRange(param.GetFilterValue(null, agentInstanceContext), opAdd, true);
                    }
                    else if (param.FilterOperator.IsComparisonOperator())
                    {
                        var existing = result[rangeIndex];
                        QueryGraphRangeEnum opAdd = param.FilterOperator.MapFrom();
                        if (existing == null)
                        {
                            result[rangeIndex] = new RangeIndexLookupValueRange(param.GetFilterValue(null, agentInstanceContext), opAdd, true);
                        }
                        else
                        {
                            if (!(existing is RangeIndexLookupValueRange))
                            {
                                continue;
                            }
                            var existingRange = (RangeIndexLookupValueRange)existing;
                            var opExist       = existingRange.Operator;
                            var desc          = QueryGraphRangeUtil.GetCanConsolidate(opExist, opAdd);
                            if (desc != null)
                            {
                                var doubleRange = GetDoubleRange(desc.IsReverse, existing.Value, param.GetFilterValue(null, agentInstanceContext));
                                result[rangeIndex] = new RangeIndexLookupValueRange(doubleRange, desc.RangeType, false);
                            }
                        }
                    }
                }
            }
            return(result);
        }
コード例 #17
0
ファイル: QueryGraphValue.cs プロジェクト: ikvm/nesper
        public void AddRange(QueryGraphRangeEnum rangeType, ExprNode propertyStart, ExprNode propertyEnd, ExprIdentNode propertyValueIdent)
        {
            if (!rangeType.IsRange())
            {
                throw new ArgumentException("Expected range type, received " + rangeType);
            }

            // duplicate can be removed right away
            if (FindIdentEntry(propertyValueIdent) != null)
            {
                return;
            }

            _items.Add(new QueryGraphValueDesc(new ExprNode[] { propertyValueIdent }, new QueryGraphValueEntryRangeIn(rangeType, propertyStart, propertyEnd, true)));
        }
コード例 #18
0
        private void TryAdd(string propertyKeyOne, QueryGraphRangeEnum opOne, ExprIdentNode valueOne,
                            string propertyKeyTwo, QueryGraphRangeEnum opTwo, ExprIdentNode valueTwo,
                            object[][] expected)
        {
            var value = new QueryGraphValue();

            value.AddRelOp(MakeIdent(propertyKeyOne), opOne, valueOne, true);
            value.AddRelOp(MakeIdent(propertyKeyTwo), opTwo, valueTwo, true);
            AssertRanges(expected, value);

            value = new QueryGraphValue();
            value.AddRelOp(MakeIdent(propertyKeyTwo), opTwo, valueTwo, true);
            value.AddRelOp(MakeIdent(propertyKeyOne), opOne, valueOne, true);
            AssertRanges(expected, value);
        }
コード例 #19
0
        public static string GetStringOp(this QueryGraphRangeEnum @enum)
        {
            switch (@enum)
            {
            case QueryGraphRangeEnum.LESS:
                return("<");

            case QueryGraphRangeEnum.LESS_OR_EQUAL:
                return("<=");

            case QueryGraphRangeEnum.GREATER_OR_EQUAL:
                return(">=");

            case QueryGraphRangeEnum.GREATER:
                return(">");

            case QueryGraphRangeEnum.RANGE_OPEN:
                return("(,)");

            case QueryGraphRangeEnum.RANGE_CLOSED:
                return("[,]");

            case QueryGraphRangeEnum.RANGE_HALF_OPEN:
                return("[,)");

            case QueryGraphRangeEnum.RANGE_HALF_CLOSED:
                return("(,]");

            case QueryGraphRangeEnum.NOT_RANGE_OPEN:
                return("-(,)");

            case QueryGraphRangeEnum.NOT_RANGE_CLOSED:
                return("-[,]");

            case QueryGraphRangeEnum.NOT_RANGE_HALF_OPEN:
                return("-[,)");

            case QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED:
                return("-(,])");

            default:
                throw new ArgumentException("invalid value", "enum");
            }
        }
コード例 #20
0
        public static bool IsRange(this QueryGraphRangeEnum @enum)
        {
            switch (@enum)
            {
            case QueryGraphRangeEnum.LESS:
                return(false);

            case QueryGraphRangeEnum.LESS_OR_EQUAL:
                return(false);

            case QueryGraphRangeEnum.GREATER_OR_EQUAL:
                return(false);

            case QueryGraphRangeEnum.GREATER:
                return(false);

            case QueryGraphRangeEnum.RANGE_OPEN:
                return(true);

            case QueryGraphRangeEnum.RANGE_CLOSED:
                return(true);

            case QueryGraphRangeEnum.RANGE_HALF_OPEN:
                return(true);

            case QueryGraphRangeEnum.RANGE_HALF_CLOSED:
                return(true);

            case QueryGraphRangeEnum.NOT_RANGE_OPEN:
                return(true);

            case QueryGraphRangeEnum.NOT_RANGE_CLOSED:
                return(true);

            case QueryGraphRangeEnum.NOT_RANGE_HALF_OPEN:
                return(true);

            case QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED:
                return(true);

            default:
                throw new ArgumentException("invalid value", "enum");
            }
        }
コード例 #21
0
        public void AddRangeExpr(
            int indexedStream,
            ExprIdentNode indexedProp,
            ExprNode startNode, int?optionalStartStreamNum,
            ExprNode endNode, int?optionalEndStreamNum,
            QueryGraphRangeEnum rangeOp)
        {
            if (optionalStartStreamNum == null && optionalEndStreamNum == null)
            {
                if (NumStreams > 1)
                {
                    for (var i = 0; i < NumStreams; i++)
                    {
                        if (i == indexedStream)
                        {
                            continue;
                        }

                        InternalAddRange(i, indexedStream, rangeOp, startNode, endNode, indexedProp);
                    }
                }
                else
                {
                    InternalAddRange(SELF_STREAM, indexedStream, rangeOp, startNode, endNode, indexedProp);
                }

                return;
            }

            optionalStartStreamNum = optionalStartStreamNum ?? -1;
            optionalEndStreamNum   = optionalEndStreamNum ?? -1;

            // add for a specific stream only
            if (optionalStartStreamNum.Equals(optionalEndStreamNum) || optionalEndStreamNum.Equals(-1))
            {
                InternalAddRange(optionalStartStreamNum.Value, indexedStream, rangeOp, startNode, endNode, indexedProp);
            }

            if (optionalStartStreamNum.Equals(-1))
            {
                InternalAddRange(optionalEndStreamNum.Value, indexedStream, rangeOp, startNode, endNode, indexedProp);
            }
        }
コード例 #22
0
        private void InternalAddRelOp(
            int streamKey, int streamValue,
            ExprNode keyExpr, QueryGraphRangeEnum rangeEnum,
            ExprIdentNode valueExpr, bool isBetweenOrIn)
        {
            if (_nToZeroAnalysis && streamValue != 0)
            {
                return;
            }

            if (_optionalHint != null &&
                _optionalHint.Filter(streamKey, streamValue, ExcludePlanFilterOperatorType.RELOP))
            {
                return;
            }

            var value = GetCreateValue(streamKey, streamValue);

            value.AddRelOp(keyExpr, rangeEnum, valueExpr, isBetweenOrIn);
        }
コード例 #23
0
        public static bool IsRange(this QueryGraphRangeEnum value)
        {
            switch (value)
            {
                case QueryGraphRangeEnum.LESS:
                case QueryGraphRangeEnum.LESS_OR_EQUAL:
                case QueryGraphRangeEnum.GREATER_OR_EQUAL:
                case QueryGraphRangeEnum.GREATER:
                    return false;
                case QueryGraphRangeEnum.RANGE_OPEN:
                case QueryGraphRangeEnum.RANGE_CLOSED:
                case QueryGraphRangeEnum.RANGE_HALF_OPEN:
                case QueryGraphRangeEnum.RANGE_HALF_CLOSED:
                case QueryGraphRangeEnum.NOT_RANGE_OPEN:
                case QueryGraphRangeEnum.NOT_RANGE_CLOSED:
                case QueryGraphRangeEnum.NOT_RANGE_HALF_OPEN:
                case QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED:
                    return true;
            }

            throw new ArgumentException("invalid value", nameof(value));
        }
コード例 #24
0
 protected QueryGraphValueEntryRange(QueryGraphRangeEnum type)
 {
     _type = type;
 }
コード例 #25
0
 protected QueryGraphValueEntryRangeForge(QueryGraphRangeEnum type)
 {
     this.type = type;
 }
コード例 #26
0
ファイル: QueryGraphRangeUtil.cs プロジェクト: valmac/nesper
 public static QueryGraphRangeConsolidateDesc GetCanConsolidate(QueryGraphRangeEnum op1, QueryGraphRangeEnum op2)
 {
     return OPS_TABLE.Get(GetKey(op1, op2));
 }
コード例 #27
0
ファイル: QueryGraphRangeUtil.cs プロジェクト: lanicon/nesper
 private static UniformPair<QueryGraphRangeEnum> GetKey(
     QueryGraphRangeEnum op1,
     QueryGraphRangeEnum op2)
 {
     return new UniformPair<QueryGraphRangeEnum>(op1, op2);
 }
コード例 #28
0
 public static QueryGraphRangeConsolidateDesc GetCanConsolidate(QueryGraphRangeEnum op1, QueryGraphRangeEnum op2)
 {
     return(opsTable.Get(GetKey(op1, op2)));
 }