Exemple #1
0
        /// <summary>
        /// Find a matching index for the property names supplied.
        /// </summary>
        /// <param name="indexProps">property names to search for</param>
        /// <returns>-1 if not found, or offset within indexes if found</returns>
        internal Pair <TableLookupIndexReqKey, int[]> GetIndexNum(string[] indexProps, string[] rangeProps)
        {
            // find an exact match first
            QueryPlanIndexItem proposed = new QueryPlanIndexItem(indexProps, null, rangeProps, null, false);

            foreach (KeyValuePair <TableLookupIndexReqKey, QueryPlanIndexItem> entry in _items)
            {
                if (entry.Value.EqualsCompareSortedProps(proposed))
                {
                    return(new Pair <TableLookupIndexReqKey, int[]>(entry.Key, null));
                }
            }

            // find partial match second, i.e. for unique indexes where the where-clause is overspecific
            foreach (KeyValuePair <TableLookupIndexReqKey, QueryPlanIndexItem> entry in _items)
            {
                if (entry.Value.RangeProps == null || entry.Value.RangeProps.Count == 0)
                {
                    int[] indexes = QueryPlanIndexUniqueHelper.CheckSufficientGetAssignment(entry.Value.IndexProps, indexProps);
                    if (indexes != null && indexes.Length != 0)
                    {
                        return(new Pair <TableLookupIndexReqKey, int[]>(entry.Key, indexes));
                    }
                }
            }

            return(null);
        }
Exemple #2
0
        public void SetUp()
        {
            QueryPlanIndexItem itemOne   = new QueryPlanIndexItem(new String[] { "p01", "p02" }, null, null, null, false);
            QueryPlanIndexItem itemTwo   = new QueryPlanIndexItem(new String[] { "p21" }, new Type[0], null, null, false);
            QueryPlanIndexItem itemThree = new QueryPlanIndexItem(new String[0], new Type[0], null, null, false);

            indexSpec = QueryPlanIndex.MakeIndex(itemOne, itemTwo, itemThree);
        }
Exemple #3
0
        private static void CheckDuplicateOrAdd(QueryPlanIndexItem proposed, IList <QueryPlanIndexItem> indexesSet)
        {
            var found = indexesSet.Any(proposed.EqualsCompareSortedProps);

            if (!found)
            {
                indexesSet.Add(proposed);
            }
        }
Exemple #4
0
        public bool EqualsCompareSortedProps(QueryPlanIndexItem other)
        {
            if (IsUnique != other.IsUnique)
            {
                return(false);
            }

            String[] otherIndexProps = CollectionUtil.CopySortArray(other.IndexProps);
            String[] thisIndexProps  = CollectionUtil.CopySortArray(IndexProps);
            String[] otherRangeProps = CollectionUtil.CopySortArray(other.RangeProps);
            String[] thisRangeProps  = CollectionUtil.CopySortArray(RangeProps);
            return
                (CollectionUtil.Compare(otherIndexProps, thisIndexProps) &&
                 CollectionUtil.Compare(otherRangeProps, thisRangeProps));
        }
Exemple #5
0
        /// <summary>
        /// Build index specification from navigability info.
        /// <para/>
        /// Looks at each stream and determines which properties in the stream must be indexed
        /// in order for other streams to look up into the stream. Determines the unique set of
        /// properties to avoid building duplicate indexes on the same set of properties.
        /// </summary>
        /// <param name="queryGraph">navigability info</param>
        /// <param name="typePerStream">The type per stream.</param>
        /// <param name="indexedStreamsUniqueProps">The indexed streams unique props.</param>
        /// <returns>query index specs for each stream</returns>
        public static QueryPlanIndex[] BuildIndexSpec(QueryGraph queryGraph, EventType[] typePerStream, String[][][] indexedStreamsUniqueProps)
        {
            var numStreams = queryGraph.NumStreams;
            var indexSpecs = new QueryPlanIndex[numStreams];

            // For each stream compile a list of index property sets.
            for (int streamIndexed = 0; streamIndexed < numStreams; streamIndexed++)
            {
                var indexesSet = new List <QueryPlanIndexItem>();

                // Look at the index from the viewpoint of the stream looking up in the index
                for (int streamLookup = 0; streamLookup < numStreams; streamLookup++)
                {
                    if (streamIndexed == streamLookup)
                    {
                        continue;
                    }

                    var value = queryGraph.GetGraphValue(streamLookup, streamIndexed);
                    var hashKeyAndIndexProps = value.HashKeyProps;

                    // Sort index properties, but use the sorted properties only to eliminate duplicates
                    var hashIndexProps      = hashKeyAndIndexProps.Indexed;
                    var hashKeyProps        = hashKeyAndIndexProps.Keys;
                    var indexCoercionTypes  = CoercionUtil.GetCoercionTypesHash(typePerStream, streamLookup, streamIndexed, hashKeyProps, hashIndexProps);
                    var hashCoercionTypeArr = indexCoercionTypes.CoercionTypes;

                    var rangeAndIndexProps   = value.RangeProps;
                    var rangeIndexProps      = rangeAndIndexProps.Indexed;
                    var rangeKeyProps        = rangeAndIndexProps.Keys;
                    var rangeCoercionTypes   = CoercionUtil.GetCoercionTypesRange(typePerStream, streamIndexed, rangeIndexProps, rangeKeyProps);
                    var rangeCoercionTypeArr = rangeCoercionTypes.CoercionTypes;

                    if (hashIndexProps.Count == 0 && rangeIndexProps.Count == 0)
                    {
                        QueryGraphValuePairInKWSingleIdx singles = value.InKeywordSingles;
                        if (!singles.Key.IsEmpty())
                        {
                            String             indexedProp = singles.Indexed[0];
                            QueryPlanIndexItem indexItem   = new QueryPlanIndexItem(new String[] { indexedProp }, null, null, null, false);
                            CheckDuplicateOrAdd(indexItem, indexesSet);
                        }

                        IList <QueryGraphValuePairInKWMultiIdx> multis = value.InKeywordMulti;
                        if (!multis.IsEmpty())
                        {
                            QueryGraphValuePairInKWMultiIdx multi = multis[0];
                            foreach (ExprNode propIndexed in multi.Indexed)
                            {
                                ExprIdentNode      identNode = (ExprIdentNode)propIndexed;
                                QueryPlanIndexItem indexItem = new QueryPlanIndexItem(new String[] { identNode.ResolvedPropertyName }, null, null, null, false);
                                CheckDuplicateOrAdd(indexItem, indexesSet);
                            }
                        }

                        continue;
                    }

                    // reduce to any unique index if applicable
                    var unique  = false;
                    var reduced = QueryPlanIndexUniqueHelper.ReduceToUniqueIfPossible(hashIndexProps, hashCoercionTypeArr, hashKeyProps, indexedStreamsUniqueProps[streamIndexed]);
                    if (reduced != null)
                    {
                        hashIndexProps      = reduced.PropertyNames;
                        hashCoercionTypeArr = reduced.CoercionTypes;
                        unique               = true;
                        rangeIndexProps      = new String[0];
                        rangeCoercionTypeArr = new Type[0];
                    }

                    var proposed = new QueryPlanIndexItem(hashIndexProps, hashCoercionTypeArr, rangeIndexProps, rangeCoercionTypeArr, unique);
                    CheckDuplicateOrAdd(proposed, indexesSet);
                }

                // create full-table-scan
                if (indexesSet.IsEmpty())
                {
                    indexesSet.Add(new QueryPlanIndexItem(null, null, null, null, false));
                }

                indexSpecs[streamIndexed] = QueryPlanIndex.MakeIndex(indexesSet);
            }

            return(indexSpecs);
        }