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); } }
public QueryGraphRangeConsolidateDesc( QueryGraphRangeEnum type, bool reverse) { Type = type; IsReverse = reverse; }
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)); }
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)); }
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); }
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)); }
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); }
public RangeIndexLookupValueRange( object value, QueryGraphRangeEnum @operator, bool allowRangeReverse) : base(value) { _operator = @operator; _isAllowRangeReverse = allowRangeReverse; }
private static MultiKeyUntyped GetKey(QueryGraphRangeEnum op1, QueryGraphRangeEnum op2) { return new MultiKeyUntyped( new Object[] { op1, op2 }); }
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; }
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; }
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); }
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; }
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); }
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); } } }
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); }
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))); }
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); }
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"); } }
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"); } }
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); } }
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); }
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)); }
protected QueryGraphValueEntryRange(QueryGraphRangeEnum type) { _type = type; }
protected QueryGraphValueEntryRangeForge(QueryGraphRangeEnum type) { this.type = type; }
public static QueryGraphRangeConsolidateDesc GetCanConsolidate(QueryGraphRangeEnum op1, QueryGraphRangeEnum op2) { return OPS_TABLE.Get(GetKey(op1, op2)); }
private static UniformPair<QueryGraphRangeEnum> GetKey( QueryGraphRangeEnum op1, QueryGraphRangeEnum op2) { return new UniformPair<QueryGraphRangeEnum>(op1, op2); }
public static QueryGraphRangeConsolidateDesc GetCanConsolidate(QueryGraphRangeEnum op1, QueryGraphRangeEnum op2) { return(opsTable.Get(GetKey(op1, op2))); }