* Processes a single join clause with lazy loading optimization. * For LEFT/RIGHT/INNER joins, marks one side as "lazy" (loads on-demand based on join keys).
( pipeline: NamespacedAndKeyedStream, joinClause: JoinClause, sources: Record<string, KeyedStream>, mainCollectionId: string, mainSource: string, allInputs: Record<string, KeyedStream>, cache: QueryCache, queryMapping: QueryMapping, collections: Record<string, Collection>, subscriptions: Record<string, CollectionSubscription>, callbacks: Record<string, LazyCollectionCallbacks>, lazySources: Set<string>, optimizableOrderByCollections: Record<string, OrderByOptimizationInfo>, setWindowFn: (windowFn: (options: WindowOptions) => void) => void, rawQuery: QueryIR, onCompileSubquery: CompileQueryFn, aliasToCollectionId: Record<string, string>, aliasRemapping: Record<string, string>, sourceWhereClauses: Map<string, BasicExpression<boolean>>, )
| 104 | * For LEFT/RIGHT/INNER joins, marks one side as "lazy" (loads on-demand based on join keys). |
| 105 | */ |
| 106 | function processJoin( |
| 107 | pipeline: NamespacedAndKeyedStream, |
| 108 | joinClause: JoinClause, |
| 109 | sources: Record<string, KeyedStream>, |
| 110 | mainCollectionId: string, |
| 111 | mainSource: string, |
| 112 | allInputs: Record<string, KeyedStream>, |
| 113 | cache: QueryCache, |
| 114 | queryMapping: QueryMapping, |
| 115 | collections: Record<string, Collection>, |
| 116 | subscriptions: Record<string, CollectionSubscription>, |
| 117 | callbacks: Record<string, LazyCollectionCallbacks>, |
| 118 | lazySources: Set<string>, |
| 119 | optimizableOrderByCollections: Record<string, OrderByOptimizationInfo>, |
| 120 | setWindowFn: (windowFn: (options: WindowOptions) => void) => void, |
| 121 | rawQuery: QueryIR, |
| 122 | onCompileSubquery: CompileQueryFn, |
| 123 | aliasToCollectionId: Record<string, string>, |
| 124 | aliasRemapping: Record<string, string>, |
| 125 | sourceWhereClauses: Map<string, BasicExpression<boolean>>, |
| 126 | ): NamespacedAndKeyedStream { |
| 127 | const isCollectionRef = joinClause.from.type === `collectionRef` |
| 128 | |
| 129 | // Get the joined source alias and input stream |
| 130 | const { |
| 131 | alias: joinedSource, |
| 132 | input: joinedInput, |
| 133 | collectionId: joinedCollectionId, |
| 134 | } = processJoinSource( |
| 135 | joinClause.from, |
| 136 | allInputs, |
| 137 | collections, |
| 138 | subscriptions, |
| 139 | callbacks, |
| 140 | lazySources, |
| 141 | optimizableOrderByCollections, |
| 142 | setWindowFn, |
| 143 | cache, |
| 144 | queryMapping, |
| 145 | onCompileSubquery, |
| 146 | aliasToCollectionId, |
| 147 | aliasRemapping, |
| 148 | sourceWhereClauses, |
| 149 | ) |
| 150 | |
| 151 | // Add the joined source to the sources map |
| 152 | sources[joinedSource] = joinedInput |
| 153 | if (isCollectionRef) { |
| 154 | // Only direct collection references form new alias bindings. Subquery |
| 155 | // aliases reuse the mapping returned from the recursive compilation above. |
| 156 | aliasToCollectionId[joinedSource] = joinedCollectionId |
| 157 | } |
| 158 | |
| 159 | const mainCollection = collections[mainCollectionId] |
| 160 | const joinedCollection = collections[joinedCollectionId] |
| 161 | |
| 162 | if (!mainCollection) { |
| 163 | throw new JoinCollectionNotFoundError(mainCollectionId) |
no test coverage detected
searching dependent graphs…