@@ -8,11 +8,12 @@ import {
88import {
99 CollectionInputNotFoundError ,
1010 InvalidJoinCondition ,
11- InvalidJoinConditionLeftTableError ,
12- InvalidJoinConditionRightTableError ,
13- InvalidJoinConditionSameTableError ,
14- InvalidJoinConditionTableMismatchError ,
11+ InvalidJoinConditionLeftSourceError ,
12+ InvalidJoinConditionRightSourceError ,
13+ InvalidJoinConditionSameSourceError ,
14+ InvalidJoinConditionSourceMismatchError ,
1515 JoinCollectionNotFoundError ,
16+ SubscriptionNotFoundError ,
1617 UnsupportedJoinSourceTypeError ,
1718 UnsupportedJoinTypeError ,
1819} from "../../errors.js"
@@ -179,7 +180,7 @@ function processJoin(
179180 // Prepare the main pipeline for joining
180181 let mainPipeline = pipeline . pipe (
181182 map ( ( [ currentKey , namespacedRow ] ) => {
182- // Extract the join key from the main table expression
183+ // Extract the join key from the main source expression
183184 const mainKey = compiledMainExpr ( namespacedRow )
184185
185186 // Return [joinKey, [originalKey, namespacedRow]]
@@ -196,7 +197,7 @@ function processJoin(
196197 // Wrap the row in a namespaced structure
197198 const namespacedRow : NamespacedRow = { [ joinedSource ] : row }
198199
199- // Extract the join key from the joined table expression
200+ // Extract the join key from the joined source expression
200201 const joinedKey = compiledJoinedExpr ( namespacedRow )
201202
202203 // Return [joinKey, [originalKey, namespacedRow]]
@@ -269,8 +270,8 @@ function processJoin(
269270 > = activePipeline . pipe (
270271 tap ( ( data ) => {
271272 // For outer joins (LEFT/RIGHT), the driving side determines which alias's
272- // subscription we consult for lazy loading. The main table drives LEFT joins,
273- // joined table drives RIGHT joins.
273+ // subscription we consult for lazy loading. The main source drives LEFT joins,
274+ // joined source drives RIGHT joins.
274275 const lazyAliasCandidate =
275276 activeSource === `main` ? joinedSource : mainSource
276277
@@ -284,8 +285,11 @@ function processJoin(
284285 const lazySourceSubscription = subscriptions [ resolvedAlias ]
285286
286287 if ( ! lazySourceSubscription ) {
287- throw new Error (
288- `Internal error: subscription for alias '${ resolvedAlias } ' (remapped from '${ lazyAliasCandidate } ', collection '${ lazySource . id } ') is missing in join pipeline. Available aliases: ${ Object . keys ( subscriptions ) . join ( `, ` ) } . This indicates a bug in alias tracking.`
288+ throw new SubscriptionNotFoundError (
289+ resolvedAlias ,
290+ lazyAliasCandidate ,
291+ lazySource . id ,
292+ Object . keys ( subscriptions )
289293 )
290294 }
291295
@@ -324,90 +328,89 @@ function processJoin(
324328}
325329
326330/**
327- * Analyzes join expressions to determine which refers to which table
328- * and returns them in the correct order (available table expression first, joined table expression second)
331+ * Analyzes join expressions to determine which refers to which source
332+ * and returns them in the correct order (available source expression first, joined source expression second)
329333 */
330334function analyzeJoinExpressions (
331335 left : BasicExpression ,
332336 right : BasicExpression ,
333- allAvailableTableAliases : Array < string > ,
337+ allAvailableSourceAliases : Array < string > ,
334338 joinedSource : string
335339) : { mainExpr : BasicExpression ; joinedExpr : BasicExpression } {
336- // Filter out the joined table alias from the available table aliases
337- const availableSources = allAvailableTableAliases . filter (
340+ // Filter out the joined source alias from the available source aliases
341+ const availableSources = allAvailableSourceAliases . filter (
338342 ( alias ) => alias !== joinedSource
339343 )
340344
341- const leftTableAlias = getTableAliasFromExpression ( left )
342- const rightTableAlias = getTableAliasFromExpression ( right )
345+ const leftSourceAlias = getSourceAliasFromExpression ( left )
346+ const rightSourceAlias = getSourceAliasFromExpression ( right )
343347
344- // If left expression refers to an available table and right refers to joined table , keep as is
348+ // If left expression refers to an available source and right refers to joined source , keep as is
345349 if (
346- leftTableAlias &&
347- availableSources . includes ( leftTableAlias ) &&
348- rightTableAlias === joinedSource
350+ leftSourceAlias &&
351+ availableSources . includes ( leftSourceAlias ) &&
352+ rightSourceAlias === joinedSource
349353 ) {
350354 return { mainExpr : left , joinedExpr : right }
351355 }
352356
353- // If left expression refers to joined table and right refers to an available table , swap them
357+ // If left expression refers to joined source and right refers to an available source , swap them
354358 if (
355- leftTableAlias === joinedSource &&
356- rightTableAlias &&
357- availableSources . includes ( rightTableAlias )
359+ leftSourceAlias === joinedSource &&
360+ rightSourceAlias &&
361+ availableSources . includes ( rightSourceAlias )
358362 ) {
359363 return { mainExpr : right , joinedExpr : left }
360364 }
361365
362- // If one expression doesn't refer to any table, this is an invalid join
363- if ( ! leftTableAlias || ! rightTableAlias ) {
364- // For backward compatibility, use the first available table alias in error message
365- throw new InvalidJoinConditionTableMismatchError ( )
366+ // If one expression doesn't refer to any source, this is an invalid join
367+ if ( ! leftSourceAlias || ! rightSourceAlias ) {
368+ throw new InvalidJoinConditionSourceMismatchError ( )
366369 }
367370
368371 // If both expressions refer to the same alias, this is an invalid join
369- if ( leftTableAlias === rightTableAlias ) {
370- throw new InvalidJoinConditionSameTableError ( leftTableAlias )
372+ if ( leftSourceAlias === rightSourceAlias ) {
373+ throw new InvalidJoinConditionSameSourceError ( leftSourceAlias )
371374 }
372375
373- // Left side must refer to an available table
376+ // Left side must refer to an available source
374377 // This cannot happen with the query builder as there is no way to build a ref
375- // to an unavailable table , but just in case, but could happen with the IR
376- if ( ! availableSources . includes ( leftTableAlias ) ) {
377- throw new InvalidJoinConditionLeftTableError ( leftTableAlias )
378+ // to an unavailable source , but just in case, but could happen with the IR
379+ if ( ! availableSources . includes ( leftSourceAlias ) ) {
380+ throw new InvalidJoinConditionLeftSourceError ( leftSourceAlias )
378381 }
379382
380- // Right side must refer to the joined table
381- if ( rightTableAlias !== joinedSource ) {
382- throw new InvalidJoinConditionRightTableError ( joinedSource )
383+ // Right side must refer to the joined source
384+ if ( rightSourceAlias !== joinedSource ) {
385+ throw new InvalidJoinConditionRightSourceError ( joinedSource )
383386 }
384387
385388 // This should not be reachable given the logic above, but just in case
386389 throw new InvalidJoinCondition ( )
387390}
388391
389392/**
390- * Extracts the table alias from a join expression
393+ * Extracts the source alias from a join expression
391394 */
392- function getTableAliasFromExpression ( expr : BasicExpression ) : string | null {
395+ function getSourceAliasFromExpression ( expr : BasicExpression ) : string | null {
393396 switch ( expr . type ) {
394397 case `ref` :
395- // PropRef path has the table alias as the first element
398+ // PropRef path has the source alias as the first element
396399 return expr . path [ 0 ] || null
397400 case `func` : {
398- // For function expressions, we need to check if all arguments refer to the same table
399- const tableAliases = new Set < string > ( )
401+ // For function expressions, we need to check if all arguments refer to the same source
402+ const sourceAliases = new Set < string > ( )
400403 for ( const arg of expr . args ) {
401- const alias = getTableAliasFromExpression ( arg )
404+ const alias = getSourceAliasFromExpression ( arg )
402405 if ( alias ) {
403- tableAliases . add ( alias )
406+ sourceAliases . add ( alias )
404407 }
405408 }
406- // If all arguments refer to the same table , return that table alias
407- return tableAliases . size === 1 ? Array . from ( tableAliases ) [ 0 ] ! : null
409+ // If all arguments refer to the same source , return that source alias
410+ return sourceAliases . size === 1 ? Array . from ( sourceAliases ) [ 0 ] ! : null
408411 }
409412 default :
410- // Values (type='val') don't reference any table
413+ // Values (type='val') don't reference any source
411414 return null
412415 }
413416}
@@ -567,7 +570,7 @@ function processJoinResults(joinType: string) {
567570/**
568571 * Returns the active and lazy collections for a join clause.
569572 * The active collection is the one that we need to fully iterate over
570- * and it can be the main table (i.e. left collection) or the joined table (i.e. right collection).
573+ * and it can be the main source (i.e. left collection) or the joined source (i.e. right collection).
571574 * The lazy collection is the one that we should join-in lazily based on matches in the active collection.
572575 * @param joinClause - The join clause to analyze
573576 * @param leftCollection - The left collection
0 commit comments