/// <summary> /// Returns two pins (smaller and greater)... both will be null if there is no intersecting range between the expressions. /// Unhandled cases: /// IN, NotIn, NotEquals, NotLike, NotBetween. /// </summary> private static void ReduceRecuringRanges(ref ProxyAndPredicate singleAttributeSet) { var repeatedAttributes = PredicateHelper.GetRepeatedAttributes(singleAttributeSet.TreePredicates); foreach (var attribute in repeatedAttributes) { var repeatedExpressions = new List <ComparisonPredicate>(); foreach (var value in singleAttributeSet.TreePredicates) { var expression = (ComparisonPredicate)value; if (attribute.ToString().Equals(expression.AttributeNames[0]) && ReducableExpression(expression)) { repeatedExpressions.Add(expression); } } if (repeatedExpressions.Count > 0) { //Ranges could be between, <, >, =, Not equals to Null... //Constants could be: Null, Bool, Number, String, DateTime, -not Array, -not JSONObject. Tuple <IJsonValue, IJsonValue> tuple = GetJSONValueRange(repeatedExpressions); if (tuple != null) { if (!(tuple.Item1 is NullValue) && !(tuple.Item2 is ObjectJsonValue)) { singleAttributeSet.TreePredicates.Add( new ComparisonPredicate(attribute, Condition.Between, PredicateHelper.GetConstant(tuple.Item1), PredicateHelper.GetConstant(tuple.Item2))); } else if (tuple.Item2 is ObjectJsonValue) { //Greater than/greater and equals to. singleAttributeSet.TreePredicates.Add( new ComparisonPredicate(attribute, Condition.GreaterThan, PredicateHelper.GetConstant(tuple.Item1))); } else { //Lesser than/lesser than and equals to. singleAttributeSet.TreePredicates.Add( new ComparisonPredicate(attribute, Condition.LesserThan, PredicateHelper.GetConstant(tuple.Item1))); } } else { singleAttributeSet.AddChildPredicate(new ProxyPredicate(new EmptyPredicate(), null)); } foreach (var expression in repeatedExpressions) { singleAttributeSet.TreePredicates.Remove(expression); } } } }
public IProxyPredicate GetProxyExecutionPredicate(IIndexProvider indexManager, IQueryStore queryStore, IEnumerable <long> rowsEnumerator) { //Get reducable terminal expressions in the ORExpression... List <ComparisonPredicate> terminalPreds = new List <ComparisonPredicate>(); foreach (var predciate in _predciates) { ComparisonPredicate comparePred = predciate as ComparisonPredicate; if (comparePred != null && comparePred.PredicateType.Equals(PredicateType.SingleVariable)) { terminalPreds.Add(comparePred); } } IEnumerable <Attribute> repAttributes = new List <Attribute>(); List <ITreePredicate> compPreds = new List <ITreePredicate>(); foreach (var predciate in _predciates) { if (predciate is ComparisonPredicate) { compPreds.Add(predciate); } } if (terminalPreds.Count > 0 && compPreds.Count > 0) { repAttributes = PredicateHelper.GetRepeatedAttributes(compPreds); } foreach (var attribute in repAttributes) { Dictionary <int, ComparisonPredicate> reducablePreds = new Dictionary <int, ComparisonPredicate>(); for (int i = 0; i < _predciates.Count; i++) { if (_predciates[i] is ComparisonPredicate) { ComparisonPredicate comparePred = _predciates[i] as ComparisonPredicate; if (ReducablePredicate(comparePred) && comparePred.Attributes[0] == attribute) { reducablePreds.Add(i, comparePred); } } } if (reducablePreds.Count < 2) { continue; } ValueList values = new ValueList(); foreach (var pair in reducablePreds) { values.Add(PredicateHelper.GetConstant(pair.Value.ConstantValues[0])); } ComparisonPredicate reducedPred = new ComparisonPredicate(attribute, Condition.In, values); for (int i = 0; i < _predciates.Count; i++) { if (reducablePreds.Keys.Contains(i)) { _predciates.RemoveAt(i); } } _predciates.Add(reducedPred); } var predicate = new ProxyOrPredicate(); foreach (var predciate in _predciates) { predicate.AddExpression(predciate); predicate.AddChildPredicate(predciate.GetProxyExecutionPredicate(indexManager, queryStore, rowsEnumerator)); } return(predicate); }