* Validates the structure of a query and its subqueries. * Checks that subqueries don't reuse collection aliases from parent queries. * This must be called on the RAW query before optimization.
( query: QueryIR, parentCollectionAliases: Set<string> = new Set(), )
| 986 | * This must be called on the RAW query before optimization. |
| 987 | */ |
| 988 | function validateQueryStructure( |
| 989 | query: QueryIR, |
| 990 | parentCollectionAliases: Set<string> = new Set(), |
| 991 | ): void { |
| 992 | // Collect direct collection aliases from this query level |
| 993 | const currentLevelAliases = collectDirectCollectionAliases(query) |
| 994 | |
| 995 | // Check if any current alias conflicts with parent aliases |
| 996 | for (const alias of currentLevelAliases) { |
| 997 | if (parentCollectionAliases.has(alias)) { |
| 998 | throw new DuplicateAliasInSubqueryError( |
| 999 | alias, |
| 1000 | Array.from(parentCollectionAliases), |
| 1001 | ) |
| 1002 | } |
| 1003 | } |
| 1004 | |
| 1005 | // Combine parent and current aliases for checking nested subqueries |
| 1006 | const combinedAliases = new Set([ |
| 1007 | ...parentCollectionAliases, |
| 1008 | ...currentLevelAliases, |
| 1009 | ]) |
| 1010 | |
| 1011 | // Recursively validate FROM subqueries |
| 1012 | if (query.from.type === `unionAll`) { |
| 1013 | for (const branch of query.from.queries) { |
| 1014 | validateQueryStructure(branch, combinedAliases) |
| 1015 | } |
| 1016 | } else { |
| 1017 | for (const source of getFromSources(query.from)) { |
| 1018 | if (source.type === `queryRef`) { |
| 1019 | validateQueryStructure(source.query, combinedAliases) |
| 1020 | } |
| 1021 | } |
| 1022 | } |
| 1023 | |
| 1024 | // Recursively validate JOIN subqueries |
| 1025 | if (query.join) { |
| 1026 | for (const joinClause of query.join) { |
| 1027 | if (joinClause.from.type === `queryRef`) { |
| 1028 | validateQueryStructure(joinClause.from.query, combinedAliases) |
| 1029 | } |
| 1030 | } |
| 1031 | } |
| 1032 | } |
| 1033 | |
| 1034 | /** |
| 1035 | * Processes the FROM clause, handling direct collection references and subqueries. |
no test coverage detected