Esempio n. 1
0
        /// <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);
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Assigns a proxy predicate to a single-attributed expressions.
        /// </summary>
        private static void AssignSingleAttributesPredicate(ProxyAndPredicate proxyAnd,
                                                            ICollection <IIndex> indexes, IQueryStore queryStore)
        {
            OrderedList <string, ComparisonPredicate> attribExprList = new OrderedList <string, ComparisonPredicate>();

            foreach (var value in proxyAnd.TreePredicates)
            {
                var expression = (ComparisonPredicate)value;
                if (expression.IsBinaryExpression)
                {
                    continue;
                }
                attribExprList.Add(expression.AttributeNames[0], expression);
            }

            if (attribExprList.Count > 0)
            {
                foreach (var attribute in attribExprList.Keys)
                {
                    IIndex lowestIndex = null;
                    foreach (var index in indexes)
                    {
                        if (attribute.Equals(index.Attributes.Name))
                        {
                            if (lowestIndex == null)
                            {
                                lowestIndex = index;
                            }
                            else if (lowestIndex.ValueCount > index.ValueCount)
                            {
                                lowestIndex = index;
                            }
                        }
                    }

                    if (lowestIndex != null)
                    {
                        foreach (var expression in attribExprList[attribute])
                        {
                            proxyAnd.AddChildPredicate(
                                new ProxyPredicate(expression.AssignIndexPredicate(lowestIndex, queryStore), expression));
                            proxyAnd.TreePredicates.Remove(expression);
                        }
                    }
                }

                //For every unassigned expression...
                if (proxyAnd.TreePredicates.Count > 0)
                {
                    ITreePredicate assingedExpression;
                    if (proxyAnd.TreePredicates.Count.Equals(1))
                    {
                        assingedExpression = proxyAnd.TreePredicates[0];
                    }
                    else
                    {
                        AndTreePredicate assingedAnd = new AndTreePredicate();
                        foreach (var expression in proxyAnd.TreePredicates)
                        {
                            assingedAnd.Add(expression);
                        }
                        assingedExpression = assingedAnd;
                    }
                    proxyAnd.AddChildPredicate(new ProxyPredicate(
                                                   new StorePredicate(assingedExpression, queryStore), assingedExpression));
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Tries to assign compound indexes to expressions if applicable...
        /// </summary>
        private static List <ProxyAndPredicate> AssignCompoundIndices(ProxyAndPredicate set,
                                                                      IEnumerable <IIndex> indexes, IQueryStore queryStore)
        {
            var attribExprList  = new OrderedList <string, ComparisonPredicate>();
            var proxyPredicates = new List <ProxyAndPredicate>();

            //For every expression in the set ready for assignment.
            foreach (var expresson in set.TreePredicates)
            {
                var expression = (ComparisonPredicate)expresson;
                if (expression.IsBinaryExpression)
                {
                    continue;
                }
                attribExprList.Add(expression.AttributeNames[0], expression);
            }

            //Each compound index will create a new state of the expression.
            foreach (var index in indexes)
            {
                int matchedNumber  = 0;
                var matchedAttribs = new List <string>();

                //If keys (attributes list) does not contain the first prefix of the index
                //Then the index is not usable.
                if (attribExprList.ContainsKey(index.Attributes.Name))
                {
                    matchedAttribs.Add(index.Attributes.Name);
                    matchedNumber += attribExprList[index.Attributes.Name].Count;
                }


                //if matched attributes are < 2 no need of compound assignment.
                if (matchedAttribs.Count < 2)
                {
                    continue;
                }

                //Assign each of them an index and get them to the predicate, and get the one with the lowest cost.
                ComparisonPredicate cheapestExpression = attribExprList[matchedAttribs[0]][0];
                IPredicate          cheapestPredicate  = cheapestExpression.AssignIndexPredicate(index, queryStore);
                for (int i = 1; i < attribExprList[matchedAttribs[0]].Count; i++)
                {
                    ComparisonPredicate tempExpression = attribExprList[matchedAttribs[0]][i];
                    IPredicate          tempPredicate  = tempExpression.AssignIndexPredicate(index, queryStore);

                    if (tempPredicate.Statistics[Statistic.ExpectedIO] <
                        cheapestPredicate.Statistics[Statistic.ExpectedIO])
                    {
                        cheapestExpression = tempExpression;
                        cheapestPredicate  = tempPredicate;
                    }
                }

                //For filteration and adding rest of expressions to the index.
                ITreePredicate assingedExpression = null;
                if (!matchedNumber.Equals(2))
                {
                    AndTreePredicate assingedAnd = new AndTreePredicate();
                    foreach (var attribute in matchedAttribs)
                    {
                        foreach (var expression in attribExprList[attribute])
                        {
                            if (expression != cheapestExpression)
                            {
                                assingedAnd.Add(expression);
                            }
                        }
                    }
                    assingedExpression = assingedAnd;
                }
                else
                {
                    foreach (var expression in attribExprList[matchedAttribs[1]])
                    {
                        assingedExpression = expression;
                    }
                }

                FilterPredicate filterPredicate = new FilterPredicate(assingedExpression, index);
                filterPredicate.AddChildPredicate(cheapestPredicate);
                ProxyAndPredicate proxyAnd = (ProxyAndPredicate)set.Clone();

                //Removing assigned expressions.
                foreach (var attribute in matchedAttribs)
                {
                    foreach (var expression in attribExprList[attribute])
                    {
                        proxyAnd.TreePredicates.Remove(expression);
                    }
                }

                proxyAnd.AddChildPredicate(new ProxyPredicate(filterPredicate, null));
                proxyPredicates.Add(proxyAnd);
            }

            foreach (var proxyAnd in proxyPredicates)
            {
                //Recursive call for each ProxyAndPredicate.
                if (proxyAnd.TreePredicates.Count > 1)
                {
                    var values = AssignCompoundIndices(proxyAnd, indexes, queryStore);
                    foreach (var value in values)
                    {
                        proxyPredicates.Add(value);
                    }
                }
            }
            return(proxyPredicates);
        }
Esempio n. 4
0
        public IProxyPredicate GetProxyExecutionPredicate(IIndexProvider indexManager, IQueryStore queryStore, IEnumerable <long> rowsEnumerator)
        {
            ProxyAndPredicate proxyPredicate = new ProxyAndPredicate();

            proxyPredicate.AddTreePredicates(_predciates);

            if (!IsTerminal)
            {
                foreach (var predicate in _predciates)
                {
                    proxyPredicate.AddChildPredicate(
                        predicate.GetProxyExecutionPredicate(indexManager, queryStore, rowsEnumerator));
                }
                return(proxyPredicate);
            }

            OrderedList <int, IIndex> indexes = indexManager.OrderedIndexList;
            ArrayList sets = new ArrayList();

            ProxyAndPredicate singleSet = new ProxyAndPredicate();

            foreach (var value in proxyPredicate.TreePredicates)
            {
                ComparisonPredicate predicate = (ComparisonPredicate)value;
                if (predicate.PredicateType.Equals(PredicateType.Constant))
                {
                    //When any constant expression is false in an AND Expression it will be resulting into 0 rowIds.
                    if (!predicate.IsTrue(null))
                    {
                        return(new ProxyPredicate(new EmptyPredicate(), predicate));
                    }
                }
                else if (predicate.PredicateType.Equals(PredicateType.SingleVariable))
                {
                    singleSet.AddTreePredicate(predicate);
                }
                else if (predicate.PredicateType.Equals(PredicateType.MultiVariable))
                {
                    sets.Add(predicate);
                }
                else if (predicate.PredicateType.Equals(PredicateType.AllVariable))
                {
                    proxyPredicate.AddChildPredicate(
                        predicate.GetProxyExecutionPredicate(indexManager, queryStore, rowsEnumerator));
                }
            }

            if (singleSet.TreePredicates.Count > 0)
            {
                sets.Add(singleSet);
            }

            foreach (var set in sets)
            {
                if (set is ITreePredicate)
                {
                    proxyPredicate.AddChildPredicate(
                        GetMultiAttributePredicate((ComparisonPredicate)set, indexes.Values, queryStore));
                }
                else if (set is ProxyAndPredicate)
                {
                    var singleAttributeSet = (ProxyAndPredicate)set;
                    ReduceRecuringRanges(ref singleAttributeSet);

                    List <ProxyAndPredicate> proxyAnds = AssignCompoundIndices(singleAttributeSet, indexes.Values, queryStore);

                    if (proxyAnds.Count == 0)
                    {
                        proxyAnds.Add(singleAttributeSet);
                    }

                    foreach (var proxyAnd in proxyAnds)
                    {
                        if (proxyAnd.TreePredicates.Count == 0)
                        {
                            continue;
                        }
                        AssignSingleAttributesPredicate(proxyAnd, indexes.Values, queryStore);
                    }

                    if (proxyAnds.Count.Equals(1))
                    {
                        foreach (var predicate in proxyAnds[0].Predicates)
                        {
                            proxyPredicate.AddChildPredicate(predicate);
                            proxyPredicate.TreePredicates = _predciates;
                        }
                    }
                    else
                    {
                        //Getting the ProxyANDPredicate with the lowest cost...
                        OrderedList <double, ProxyAndPredicate> orderedPredicates = new OrderedList <double, ProxyAndPredicate>();

                        foreach (var proxyAnd in proxyAnds)
                        {
                            orderedPredicates.Add(proxyAnd.Statistics[Statistic.ExpectedIO], proxyAnd);
                        }

                        foreach (var predicate in orderedPredicates.FirstValues[0].Predicates)
                        {
                            proxyPredicate.AddChildPredicate(predicate);
                            proxyPredicate.TreePredicates = _predciates;
                        }
                        proxyPredicate.TreePredicates = _predciates;
                    }
                }
            }
            return(proxyPredicate);
        }