public static QueryPlanIndex MakeIndexTableAccess(TableLookupIndexReqKey indexName) { IDictionary <TableLookupIndexReqKey, QueryPlanIndexItem> indexMap = new Dictionary <TableLookupIndexReqKey, QueryPlanIndexItem>(); indexMap.Put(indexName, null); return(new QueryPlanIndex(indexMap)); }
/// <summary>Ctor. </summary> /// <param name="lookupStream">stream that generates event to look up for</param> /// <param name="indexedStream">stream to index table lookup</param> /// <param name="indexNum">index number for the table containing the full unindexed contents</param> /// <param name="expressions"></param> public InKeywordTableLookupPlanSingleIdx( int lookupStream, int indexedStream, TableLookupIndexReqKey indexNum, IList <ExprNode> expressions) : base(lookupStream, indexedStream, new TableLookupIndexReqKey[] { indexNum }) { _expressions = expressions; }
/// <summary>Ctor. </summary> /// <param name="lookupStream">stream that generates event to look up for</param> /// <param name="indexedStream">stream to index table lookup</param> /// <param name="indexNum">index number for the table containing the full unindexed contents</param> /// <param name="keyProperties">properties to use in lookup event to access index</param> public IndexedTableLookupPlanMulti(int lookupStream, int indexedStream, TableLookupIndexReqKey indexNum, IList <QueryGraphValueEntryHashKeyed> keyProperties) : base(lookupStream, indexedStream, new TableLookupIndexReqKey[] { indexNum }) { _keyProperties = keyProperties; }
/// <summary>Ctor. </summary> /// <param name="lookupStream">stream that generates event to look up for</param> /// <param name="indexedStream">stream to full table scan</param> /// <param name="indexNum">index number for the table containing the full unindexed contents</param> public FullTableScanLookupPlan(int lookupStream, int indexedStream, TableLookupIndexReqKey indexNum) : base(lookupStream, indexedStream, new TableLookupIndexReqKey[] { indexNum }) { }
/// <summary> /// Ctor. /// </summary> /// <param name="lookupStream">stream that generates event to look up for</param> /// <param name="indexedStream">stream to index table lookup</param> /// <param name="indexNum">index number for the table containing the full unindexed contents</param> /// <param name="rangeKeyPair">The range key pair.</param> public SortedTableLookupPlan(int lookupStream, int indexedStream, TableLookupIndexReqKey indexNum, QueryGraphValueEntryRange rangeKeyPair) : base(lookupStream, indexedStream, new TableLookupIndexReqKey[] { indexNum }) { _rangeKeyPair = rangeKeyPair; _lookupStream = lookupStream; }
private static TableLookupPlan GetFullTableScanTable(int lookupStream, int indexedStream, TableMetadata indexedStreamTableMeta) { var indexName = new TableLookupIndexReqKey(indexedStreamTableMeta.TableName, indexedStreamTableMeta.TableName); return(new FullTableScanUniquePerKeyLookupPlan(lookupStream, indexedStream, indexName)); }
/// <summary> /// Create the table lookup plan for a from-stream to look up in an indexed stream /// using the columns supplied in the query graph and looking at the actual indexes available /// and their index number. /// </summary> /// <param name="queryGraph">contains properties joining the 2 streams</param> /// <param name="currentLookupStream">stream to use key values from</param> /// <param name="indexedStream">stream to look up in</param> /// <param name="indexSpecs">index specification defining indexes to be created for stream</param> /// <param name="typesPerStream">event types for each stream</param> /// <returns>plan for performing a lookup in a given table using one of the indexes supplied</returns> public static TableLookupPlan CreateLookupPlan(QueryGraph queryGraph, int currentLookupStream, int indexedStream, QueryPlanIndex indexSpecs, EventType[] typesPerStream, TableMetadata indexedStreamTableMeta) { var queryGraphValue = queryGraph.GetGraphValue(currentLookupStream, indexedStream); var hashKeyProps = queryGraphValue.HashKeyProps; var hashPropsKeys = hashKeyProps.Keys; var hashIndexProps = hashKeyProps.Indexed.ToArray(); var rangeProps = queryGraphValue.RangeProps; var rangePropsKeys = rangeProps.Keys; var rangeIndexProps = rangeProps.Indexed.ToArray(); var pairIndexHashRewrite = indexSpecs.GetIndexNum(hashIndexProps, rangeIndexProps); var indexNum = pairIndexHashRewrite == null ? null : pairIndexHashRewrite.First; // handle index redirection towards unique index if (pairIndexHashRewrite != null && pairIndexHashRewrite.Second != null) { var indexes = pairIndexHashRewrite.Second; var newHashIndexProps = new string[indexes.Length]; IList <QueryGraphValueEntryHashKeyed> newHashKeys = new List <QueryGraphValueEntryHashKeyed>(); for (var i = 0; i < indexes.Length; i++) { newHashIndexProps[i] = hashIndexProps[indexes[i]]; newHashKeys.Add(hashPropsKeys[indexes[i]]); } hashIndexProps = newHashIndexProps; hashPropsKeys = newHashKeys; rangeIndexProps = new string[0]; rangePropsKeys = Collections.GetEmptyList <QueryGraphValueEntryRange>(); } // no direct hash or range lookups if (hashIndexProps.Length == 0 && rangeIndexProps.Length == 0) { // handle single-direction 'in' keyword var singles = queryGraphValue.InKeywordSingles; if (!singles.Key.IsEmpty()) { QueryGraphValueEntryInKeywordSingleIdx single = null; indexNum = null; if (indexedStreamTableMeta != null) { var indexes = singles.Indexed; var count = 0; foreach (var index in indexes) { Pair <IndexMultiKey, EventTableIndexEntryBase> indexPairFound = EventTableIndexUtil.FindIndexBestAvailable( indexedStreamTableMeta.EventTableIndexMetadataRepo.Indexes, Collections.SingletonSet(index), Collections.GetEmptySet <string>(), null); if (indexPairFound != null) { indexNum = new TableLookupIndexReqKey(indexPairFound.Second.OptionalIndexName, indexedStreamTableMeta.TableName); single = singles.Key[count]; } count++; } } else { single = singles.Key[0]; var pairIndex = indexSpecs.GetIndexNum(new string[] { singles.Indexed[0] }, null); indexNum = pairIndex.First; } if (indexNum != null) { return(new InKeywordTableLookupPlanSingleIdx(currentLookupStream, indexedStream, indexNum, single.KeyExprs)); } } // handle multi-direction 'in' keyword var multis = queryGraphValue.InKeywordMulti; if (!multis.IsEmpty()) { if (indexedStreamTableMeta != null) { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } QueryGraphValuePairInKWMultiIdx multi = multis[0]; var indexNameArray = new TableLookupIndexReqKey[multi.Indexed.Length]; var foundAll = true; for (var i = 0; i < multi.Indexed.Length; i++) { var identNode = (ExprIdentNode)multi.Indexed[i]; var pairIndex = indexSpecs.GetIndexNum(new string[] { identNode.ResolvedPropertyName }, null); if (pairIndex == null) { foundAll = false; } else { indexNameArray[i] = pairIndex.First; } } if (foundAll) { return(new InKeywordTableLookupPlanMultiIdx(currentLookupStream, indexedStream, indexNameArray, multi.Key.KeyExpr)); } } // We don't use a keyed index but use the full stream set as the stream does not have any indexes // If no such full set index exists yet, add to specs if (indexedStreamTableMeta != null) { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } if (indexNum == null) { indexNum = new TableLookupIndexReqKey(indexSpecs.AddIndex(null, null)); } return(new FullTableScanLookupPlan(currentLookupStream, indexedStream, indexNum)); } if (indexNum == null) { throw new IllegalStateException("Failed to query plan as index for " + hashIndexProps.Render() + " and " + rangeIndexProps.Render() + " in the index specification"); } if (indexedStreamTableMeta != null) { var indexPairFound = EventTableIndexUtil.FindIndexBestAvailable(indexedStreamTableMeta.EventTableIndexMetadataRepo.Indexes, ToSet(hashIndexProps), ToSet(rangeIndexProps), null); if (indexPairFound != null) { var indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(indexPairFound.First, hashIndexProps, GetHashKeyFuncsAsSubProp(hashPropsKeys), rangeIndexProps, GetRangeFuncsAsSubProp(rangePropsKeys)); if (indexKeyInfo.OrderedKeyCoercionTypes.IsCoerce || indexKeyInfo.OrderedRangeCoercionTypes.IsCoerce) { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } hashPropsKeys = ToHashKeyFuncs(indexKeyInfo.OrderedHashDesc); hashIndexProps = IndexedPropDesc.GetIndexProperties(indexPairFound.First.HashIndexedProps); rangePropsKeys = ToRangeKeyFuncs(indexKeyInfo.OrderedRangeDesc); rangeIndexProps = IndexedPropDesc.GetIndexProperties(indexPairFound.First.RangeIndexedProps); indexNum = new TableLookupIndexReqKey(indexPairFound.Second.OptionalIndexName, indexedStreamTableMeta.TableName); // the plan will be created below if (hashIndexProps.Length == 0 && rangeIndexProps.Length == 0) { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } } else { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } } // straight keyed-index lookup if (hashIndexProps.Length > 0 && rangeIndexProps.Length == 0) { TableLookupPlan tableLookupPlan; if (hashPropsKeys.Count == 1) { tableLookupPlan = new IndexedTableLookupPlanSingle(currentLookupStream, indexedStream, indexNum, hashPropsKeys[0]); } else { tableLookupPlan = new IndexedTableLookupPlanMulti(currentLookupStream, indexedStream, indexNum, hashPropsKeys); } // Determine coercion required var coercionTypes = CoercionUtil.GetCoercionTypesHash(typesPerStream, currentLookupStream, indexedStream, hashPropsKeys, hashIndexProps); if (coercionTypes.IsCoerce) { // check if there already are coercion types for this index var existCoercionTypes = indexSpecs.GetCoercionTypes(hashIndexProps); if (existCoercionTypes != null) { for (var i = 0; i < existCoercionTypes.Length; i++) { coercionTypes.CoercionTypes[i] = TypeHelper.GetCompareToCoercionType(existCoercionTypes[i], coercionTypes.CoercionTypes[i]); } } indexSpecs.SetCoercionTypes(hashIndexProps, coercionTypes.CoercionTypes); } return(tableLookupPlan); } // sorted index lookup if (hashIndexProps.Length == 0 && rangeIndexProps.Length == 1) { QueryGraphValueEntryRange range = rangePropsKeys[0]; return(new SortedTableLookupPlan(currentLookupStream, indexedStream, indexNum, range)); } // composite range and index lookup else { return(new CompositeTableLookupPlan(currentLookupStream, indexedStream, indexNum, hashPropsKeys, rangePropsKeys)); } }
/// <summary> /// Ctor. /// </summary> /// <param name="lookupStream">stream that generates event to look up for</param> /// <param name="indexedStream">stream to index table lookup</param> /// <param name="indexNum">index number for the table containing the full unindexed contents</param> /// <param name="hashKeys">The hash keys.</param> /// <param name="rangeKeyPairs">The range key pairs.</param> public CompositeTableLookupPlan(int lookupStream, int indexedStream, TableLookupIndexReqKey indexNum, IList <QueryGraphValueEntryHashKeyed> hashKeys, IList <QueryGraphValueEntryRange> rangeKeyPairs) : base(lookupStream, indexedStream, new TableLookupIndexReqKey[] { indexNum }) { _hashKeys = hashKeys; _rangeKeyPairs = rangeKeyPairs; }
/// <summary>Ctor. </summary> /// <param name="lookupStream">stream that generates event to look up for</param> /// <param name="indexedStream">stream to index table lookup</param> /// <param name="indexNum">index number for the table containing the full unindexed contents</param> /// <param name="hashKey">properties to use in lookup event to access index</param> public IndexedTableLookupPlanSingle(int lookupStream, int indexedStream, TableLookupIndexReqKey indexNum, QueryGraphValueEntryHashKeyed hashKey) : base(lookupStream, indexedStream, new TableLookupIndexReqKey[] { indexNum }) { _hashKey = hashKey; }