private static SubordinateQueryIndexDesc FindOrSuggestIndex( IDictionary <String, SubordPropHashKey> hashProps, IDictionary <String, SubordPropRangeKey> rangeProps, IndexHint optionalIndexHint, bool isIndexShare, int subqueryNumber, EventTableIndexMetadata indexMetadata, ICollection <string> optionalUniqueKeyProps, bool onlyUseExistingIndexes) { var indexProps = GetIndexPropDesc(hashProps, rangeProps); var hashedAndBtreeProps = indexProps.ListPair; // Get or create the table for this index (exact match or property names, type of index and coercion type is expected) IndexKeyInfo indexKeyInfo; // how needs all of IndexKeyInfo+QueryPlanIndexItem+IndexMultiKey IndexMultiKey indexMultiKey; string indexName = null; QueryPlanIndexItem planIndexItem = null; if (hashedAndBtreeProps.HashedProps.IsEmpty() && hashedAndBtreeProps.BtreeProps.IsEmpty()) { return(null); } Pair <IndexMultiKey, string> existing = null; Pair <QueryPlanIndexItem, IndexMultiKey> planned = null; // consider index hints IList <IndexHintInstruction> optionalIndexHintInstructions = null; if (optionalIndexHint != null) { optionalIndexHintInstructions = optionalIndexHint.GetInstructionsSubquery(subqueryNumber); } var indexFoundPair = EventTableIndexUtil.FindIndexConsiderTyping(indexMetadata.Indexes, hashedAndBtreeProps.HashedProps, hashedAndBtreeProps.BtreeProps, optionalIndexHintInstructions); if (indexFoundPair != null) { var hintIndex = indexMetadata.Indexes.Get(indexFoundPair); existing = new Pair <IndexMultiKey, string>(indexFoundPair, hintIndex.OptionalIndexName); } // nothing found: plan one if (existing == null && !onlyUseExistingIndexes) { // not found, see if the item is declared unique var proposedHashedProps = hashedAndBtreeProps.HashedProps; var proposedBtreeProps = hashedAndBtreeProps.BtreeProps; // match against unique-key properties when suggesting an index var unique = false; var coerce = !isIndexShare; if (optionalUniqueKeyProps != null && !optionalUniqueKeyProps.IsEmpty()) { IList <IndexedPropDesc> newHashProps = new List <IndexedPropDesc>(); foreach (var uniqueKey in optionalUniqueKeyProps) { var found = false; foreach (var hashProp in hashedAndBtreeProps.HashedProps) { if (hashProp.IndexPropName.Equals(uniqueKey)) { newHashProps.Add(hashProp); found = true; break; } } if (!found) { newHashProps = null; break; } } if (newHashProps != null) { proposedHashedProps = newHashProps; proposedBtreeProps = Collections.GetEmptyList <IndexedPropDesc>(); unique = true; coerce = false; } } planned = PlanIndex(unique, proposedHashedProps, proposedBtreeProps, coerce); } // compile index information if (existing == null && planned == null) { return(null); } // handle existing if (existing != null) { indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(existing.First, indexProps.HashIndexPropsProvided, indexProps.HashJoinedProps, indexProps.RangeIndexPropsProvided, indexProps.RangeJoinedProps); indexName = existing.Second; indexMultiKey = existing.First; } // handle planned else { indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(planned.Second, indexProps.HashIndexPropsProvided, indexProps.HashJoinedProps, indexProps.RangeIndexPropsProvided, indexProps.RangeJoinedProps); indexMultiKey = planned.Second; planIndexItem = planned.First; } return(new SubordinateQueryIndexDesc(indexKeyInfo, indexName, indexMultiKey, planIndexItem)); }
private static SubordinateQueryIndexSuggest FindOrSuggestIndex( IDictionary<string, SubordPropHashKeyForge> hashProps, IDictionary<string, SubordPropRangeKeyForge> rangeProps, IndexHint optionalIndexHint, bool isIndexShare, int subqueryNumber, EventTableIndexMetadata indexMetadata, ISet<string> optionalUniqueKeyProps, bool onlyUseExistingIndexes, EventType eventTypeIndexed, StatementRawInfo raw, StatementCompileTimeServices services) { var indexProps = GetIndexPropDesc(hashProps, rangeProps); var hashedAndBtreeProps = indexProps.ListPair; // Get or create the table for this index (exact match or property names, type of index and coercion type is expected) IndexKeyInfo indexKeyInfo; // how needs all of IndexKeyInfo+QueryPlanIndexItem+IndexMultiKey IndexMultiKey indexMultiKey; string indexName = null; string indexModuleName = null; QueryPlanIndexItemForge planIndexItem = null; if (hashedAndBtreeProps.HashedProps.IsEmpty() && hashedAndBtreeProps.BtreeProps.IsEmpty()) { return null; } Pair<IndexMultiKey, NameAndModule> existing = null; SubordinateQueryIndexPlan planned = null; // consider index hints IList<IndexHintInstruction> optionalIndexHintInstructions = null; if (optionalIndexHint != null) { optionalIndexHintInstructions = optionalIndexHint.GetInstructionsSubquery(subqueryNumber); } var indexFoundPair = EventTableIndexUtil.FindIndexConsiderTyping( indexMetadata.Indexes, hashedAndBtreeProps.HashedProps, hashedAndBtreeProps.BtreeProps, optionalIndexHintInstructions); if (indexFoundPair != null) { var hintIndex = indexMetadata.Indexes.Get(indexFoundPair); existing = new Pair<IndexMultiKey, NameAndModule>( indexFoundPair, new NameAndModule(hintIndex.OptionalIndexName, hintIndex.OptionalIndexModuleName)); } // nothing found: plan one if (existing == null && !onlyUseExistingIndexes) { // not found, see if the item is declared unique var proposedHashedProps = hashedAndBtreeProps.HashedProps; var proposedBtreeProps = hashedAndBtreeProps.BtreeProps; // match against unique-key properties when suggesting an index var unique = false; var coerce = !isIndexShare; if (optionalUniqueKeyProps != null && !optionalUniqueKeyProps.IsEmpty()) { IList<IndexedPropDesc> newHashProps = new List<IndexedPropDesc>(); foreach (var uniqueKey in optionalUniqueKeyProps) { var found = false; foreach (var hashProp in hashedAndBtreeProps.HashedProps) { if (hashProp.IndexPropName.Equals(uniqueKey)) { newHashProps.Add(hashProp); found = true; break; } } if (!found) { newHashProps = null; break; } } if (newHashProps != null) { proposedHashedProps = newHashProps; proposedBtreeProps = new EmptyList<IndexedPropDesc>(); unique = true; coerce = false; } } planned = PlanIndex(unique, proposedHashedProps, proposedBtreeProps, eventTypeIndexed, raw, services); } // compile index information if (existing == null && planned == null) { return null; } // handle existing IList<StmtClassForgeableFactory> multiKeyForgeables; if (existing != null) { indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo( existing.First, indexProps.HashIndexPropsProvided, indexProps.HashJoinedProps, indexProps.RangeIndexPropsProvided, indexProps.RangeJoinedProps); indexName = existing.Second.Name; indexModuleName = existing.Second.ModuleName; indexMultiKey = existing.First; multiKeyForgeables = EmptyList<StmtClassForgeableFactory>.Instance; } else { // handle planned indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo( planned.IndexPropKey, indexProps.HashIndexPropsProvided, indexProps.HashJoinedProps, indexProps.RangeIndexPropsProvided, indexProps.RangeJoinedProps); indexMultiKey = planned.IndexPropKey; planIndexItem = planned.IndexItem; multiKeyForgeables = planned.MultiKeyForgeables; } var forge = new SubordinateQueryIndexDescForge(indexKeyInfo, indexName, indexModuleName, indexMultiKey, planIndexItem); return new SubordinateQueryIndexSuggest(forge, multiKeyForgeables); }