public SubordinateQueryIndexSuggest( SubordinateQueryIndexDescForge forge, IList<StmtClassForgeableFactory> multiKeyForgeables) { Forge = forge; MultiKeyForgeables = multiKeyForgeables; }
public static SubordinateQueryPlan PlanSubquery( EventType[] outerStreams, SubordPropPlan joinDesc, bool isNWOnTrigger, bool forceTableScan, IndexHint optionalIndexHint, bool indexShare, int subqueryNumber, bool isVirtualDataWindow, EventTableIndexMetadata indexMetadata, ISet<string> optionalUniqueKeyProps, bool onlyUseExistingIndexes, EventType eventTypeIndexed, StatementRawInfo statementRawInfo, StatementCompileTimeServices services) { if (isVirtualDataWindow) { var indexProps = GetIndexPropDesc(joinDesc.HashProps, joinDesc.RangeProps); var lookupStrategyFactoryX = new SubordTableLookupStrategyFactoryForgeVDW( statementRawInfo.StatementName, statementRawInfo.Annotations, outerStreams, indexProps.HashJoinedProps, new CoercionDesc(false, indexProps.HashIndexCoercionType), indexProps.RangeJoinedProps, new CoercionDesc(false, indexProps.RangeIndexCoercionType), isNWOnTrigger, joinDesc, forceTableScan, indexProps.ListPair); var forge = new SubordinateQueryPlanDescForge(lookupStrategyFactoryX, null); return new SubordinateQueryPlan(forge, EmptyList<StmtClassForgeableFactory>.Instance); } if (joinDesc.CustomIndexOps != null && !joinDesc.CustomIndexOps.IsEmpty()) { foreach (var op in joinDesc.CustomIndexOps) { foreach (var index in indexMetadata.Indexes) { if (IsCustomIndexMatch(index, op)) { var provisionDesc = index.Value.OptionalQueryPlanIndexItem.AdvancedIndexProvisionDesc; var lookupStrategyFactoryX = provisionDesc.Factory.Forge.GetSubordinateLookupStrategy( op.Key.OperationName, op.Value.PositionalExpressions, isNWOnTrigger, outerStreams.Length); var provisionCompileTime = provisionDesc.ToCompileTime(eventTypeIndexed, statementRawInfo, services); var indexItemForge = new QueryPlanIndexItemForge( new string[0], new Type[0], new string[0], new Type[0], false, provisionCompileTime, eventTypeIndexed); var indexDesc = new SubordinateQueryIndexDescForge( null, index.Value.OptionalIndexName, index.Value.OptionalIndexModuleName, index.Key, indexItemForge); var forge = new SubordinateQueryPlanDescForge(lookupStrategyFactoryX, new SubordinateQueryIndexDescForge[]{indexDesc}); return new SubordinateQueryPlan(forge, EmptyList<StmtClassForgeableFactory>.Instance); } } } } var hashKeys = Collections.GetEmptyList<SubordPropHashKeyForge>(); CoercionDesc hashKeyCoercionTypes = null; var rangeKeys = Collections.GetEmptyList<SubordPropRangeKeyForge>(); CoercionDesc rangeKeyCoercionTypes = null; IList<ExprNode> inKeywordSingleIdxKeys = null; ExprNode inKeywordMultiIdxKey = null; SubordinateQueryIndexDescForge[] indexDescs; var additionalForgeables = new List<StmtClassForgeableFactory>(); MultiKeyClassRef multiKeyClasses = null; if (joinDesc.InKeywordSingleIndex != null) { var single = joinDesc.InKeywordSingleIndex; var keyInfo = new SubordPropHashKeyForge( new QueryGraphValueEntryHashKeyedForgeExpr(single.Expressions[0], false), null, single.CoercionType); var index = FindOrSuggestIndex( Collections.SingletonMap(single.IndexedProp, keyInfo), EmptyDictionary<string, SubordPropRangeKeyForge>.Instance, optionalIndexHint, indexShare, subqueryNumber, indexMetadata, optionalUniqueKeyProps, onlyUseExistingIndexes, eventTypeIndexed, statementRawInfo, services); if (index == null) { return null; } var indexDesc = index.Forge; var desc = new SubordinateQueryIndexDescForge( indexDesc.OptionalIndexKeyInfo, indexDesc.IndexName, indexDesc.IndexModuleName, indexDesc.IndexMultiKey, indexDesc.OptionalQueryPlanIndexItem); indexDescs = new[] {desc}; inKeywordSingleIdxKeys = single.Expressions; additionalForgeables.AddAll(index.MultiKeyForgeables); } else if (joinDesc.InKeywordMultiIndex != null) { var multi = joinDesc.InKeywordMultiIndex; indexDescs = new SubordinateQueryIndexDescForge[multi.IndexedProp.Length]; for (var i = 0; i < multi.IndexedProp.Length; i++) { var keyInfo = new SubordPropHashKeyForge( new QueryGraphValueEntryHashKeyedForgeExpr(multi.Expression, false), null, multi.CoercionType); var index = FindOrSuggestIndex( Collections.SingletonMap(multi.IndexedProp[i], keyInfo), EmptyDictionary<string, SubordPropRangeKeyForge>.Instance, optionalIndexHint, indexShare, subqueryNumber, indexMetadata, optionalUniqueKeyProps, onlyUseExistingIndexes, eventTypeIndexed, statementRawInfo, services); var indexDesc = index.Forge; additionalForgeables.AddAll(index.MultiKeyForgeables); if (indexDesc == null) { return null; } indexDescs[i] = indexDesc; } inKeywordMultiIdxKey = multi.Expression; } else { var index = FindOrSuggestIndex( joinDesc.HashProps, joinDesc.RangeProps, optionalIndexHint, false, subqueryNumber, indexMetadata, optionalUniqueKeyProps, onlyUseExistingIndexes, eventTypeIndexed, statementRawInfo, services); if (index == null) { return null; } var indexDesc = index.Forge; additionalForgeables.AddRange(index.MultiKeyForgeables); var indexKeyInfo = indexDesc.OptionalIndexKeyInfo; hashKeys = indexKeyInfo.OrderedHashDesc; hashKeyCoercionTypes = indexKeyInfo.OrderedKeyCoercionTypes; rangeKeys = indexKeyInfo.OrderedRangeDesc; rangeKeyCoercionTypes = indexKeyInfo.OrderedRangeCoercionTypes; var desc = new SubordinateQueryIndexDescForge( indexDesc.OptionalIndexKeyInfo, indexDesc.IndexName, indexDesc.IndexModuleName, indexDesc.IndexMultiKey, indexDesc.OptionalQueryPlanIndexItem); indexDescs = new[] {desc}; if (indexDesc.OptionalQueryPlanIndexItem == null) { var multiKeyPlan = MultiKeyPlanner.PlanMultiKey(hashKeyCoercionTypes.CoercionTypes, true, statementRawInfo, services.SerdeResolver); multiKeyClasses = multiKeyPlan.ClassRef; additionalForgeables.AddRange(multiKeyPlan.MultiKeyForgeables); } else { multiKeyClasses = indexDesc.OptionalQueryPlanIndexItem.HashMultiKeyClasses; } } if (forceTableScan) { return null; } var lookupStrategyFactory = SubordinateTableLookupStrategyUtil.GetLookupStrategy( outerStreams, hashKeys, hashKeyCoercionTypes, multiKeyClasses, rangeKeys, rangeKeyCoercionTypes, inKeywordSingleIdxKeys, inKeywordMultiIdxKey, isNWOnTrigger); var forgeX = new SubordinateQueryPlanDescForge(lookupStrategyFactory, indexDescs); return new SubordinateQueryPlan(forgeX, additionalForgeables); }
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); }