Skip to content

Conversation

@Newbie012
Copy link
Collaborator

@Newbie012 Newbie012 commented Jan 13, 2026

fixes #441
fixes #440

Previously, array_agg would fail to correctly infer types when the input came from union subqueries or CTEs. This caused type inference to crash.

Summary by CodeRabbit

  • Bug Fixes

    • Corrected type inference for array_agg and scalar subqueries in CTEs and union subqueries, improving element nullability and overall type accuracy.
    • Improved column reference resolution across CTEs and nested subqueries so types propagate more reliably.
  • New Features

    • Enhanced cross-statement resolution flow to derive column descriptions from prior SELECT/CTE sources and inherit previously resolved sources.
  • Tests

    • Added tests covering array_agg and scalar-subquery inference in CTE and union-subquery scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

Previously, array_agg would fail to correctly infer types when the input came from union subqueries or CTEs. This caused type inference to crash.
@changeset-bot
Copy link

changeset-bot bot commented Jan 13, 2026

🦋 Changeset detected

Latest commit: a41e2b1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 17 packages
Name Type
@ts-safeql/generate Patch
@ts-safeql/eslint-plugin Patch
@ts-safeql/shared Patch
@ts-safeql/sql-ast Patch
@ts-safeql-demos/basic-flat-config Patch
@ts-safeql-demos/basic-migrations-raw Patch
@ts-safeql-demos/basic-transform-type Patch
@ts-safeql-demos/basic Patch
@ts-safeql-demos/big-project Patch
@ts-safeql-demos/config-file-flat-config Patch
@ts-safeql-demos/from-config-file Patch
@ts-safeql-demos/multi-connections Patch
@ts-safeql-demos/playground Patch
@ts-safeql-demos/postgresjs-custom-types Patch
@ts-safeql-demos/postgresjs-demo Patch
@ts-safeql-demos/vercel-postgres Patch
@ts-safeql/test-utils Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Jan 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Review Updated (UTC)
safeql Ignored Ignored Preview Jan 13, 2026 11:47am

@coderabbitai
Copy link

coderabbitai bot commented Jan 13, 2026

📝 Walkthrough

Walkthrough

Expose CTE/select sources and thread prior statement sources through AST description; improve column resolution by using select-sourced descriptions for CTEs/subselects; guard array_agg handling for empty subquery results and normalize literal unions; add tests and changelog entry for these fixes.

Changes

Cohort / File(s) Summary
Changelog Entry
\.changeset/large-insects-peel.md
Adds patch changelog noting fix: correct inference for array_agg and scalar subqueries in CTEs.
AST describe / column resolution
packages/generate/src/ast-describe.ts
Thread prevSources and cteSelects through AST description; add getDescribedColumnRefFromSelectSources and getDescribedColumnsFromSelect; fall back from schema resolution to select-sourced resolution for CTEs/subselects; add normalizeLiteralUnion; guard getDescribedArrayAggFunCall for empty described arrays and adjust array element type resolution.
Source discovery / CTE mapping
packages/generate/src/ast-get-sources.ts
Build cteSources from CTEs, merge into overall sources map, short-circuit RangeVar to return CTE sources, and support inheriting subselect/CTE resolvers from prevSources.
Source resolver tests
packages/generate/src/ast-get-sources.test.ts
New test ensuring prevSources/subselect inheritance yields kind "subselect" for CTE/subselect resolvers.
Behavioral tests (array_agg / scalar subqueries)
packages/generate/src/generate.test.ts
Add tests for array_agg over UNION subqueries, coalesce(array_agg(...)), and scalar subquery inference from CTEs (including nullability/union expectations).

Sequence Diagram(s)

sequenceDiagram
    participant Client as AST Describer
    participant Resolver as Sources Resolver
    participant Schema as Schema Lookup
    participant Select as Select/CTE Analyzer

    Client->>Resolver: request resolve columnRef (with prevSources / cteSelects)
    Resolver->>Resolver: check sources map (tables, cteSources, prevSources)
    alt source found (table/cte/subselect)
        Resolver-->>Client: return source-derived column descriptions
    else not found in sources
        Resolver->>Schema: lookup by schema/table
        Schema-->>Resolver: column definitions or not found
        alt schema found
            Resolver-->>Client: return schema-derived descriptions
        else schema not found
            Client->>Select: inspect referenced CTEs / subselects (cteSelects)
            Select->>Resolver: build select-sourced column descriptions
            Resolver-->>Client: return select-sourced descriptions (array/scalar handling)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐇
I hopped through CTEs with whiskers bright,
Found unions hidden in the night,
I guarded empty arrays with care,
Merged literal hues from here to there,
Now types return home and tests delight. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: correcting array_agg type inference for union subselects and CTEs, which aligns with the primary objectives of issues #441 and #440.
Linked Issues check ✅ Passed The PR fully addresses both linked issues: [#441] fixes the TypeError in getDescribedArrayAggFunCall with an empty-array check returning unknown types, and [#440] enables scalar subqueries from CTEs to infer correct column types through enhanced CTE/select-sourced resolution.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the PR objectives: ast-describe.ts and ast-get-sources.ts implement CTE/subquery handling, test files validate the fixes, and the changelog documents the fix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link

greptile-apps bot commented Jan 13, 2026

Greptile Overview

Greptile Summary

This PR fixes a critical bug where array_agg would crash when inferring types from union subqueries or CTEs. The fix implements three key improvements:

  1. Early return for empty descriptions: Adds handling in getDescribedArrayAggFunCall when column resolution returns empty results, returning unknown[] instead of crashing
  2. Enhanced context resolution: Updates getContextForColumnRef to properly resolve CTE and subselect contexts by updating the select property in the context, enabling proper type inference for nested queries
  3. Fallback resolution mechanism: Introduces getDescribedColumnRefFromSelectSources as a fallback when schema-based lookup fails, recursively parsing CTEs and subselects to find column definitions
  4. Literal union normalization: Adds normalizeLiteralUnion to convert union types containing literal values (like 'a' | 'b') to their base types (like string) before wrapping in arrays, preventing type system issues

The implementation follows existing patterns in the codebase, reusing the recursive getASTDescription call pattern already established in getDescribedSelectStmt. Two comprehensive test cases validate the fix for both direct union subqueries and nested CTE scenarios with coalesce.

The changes are well-structured and maintain backward compatibility while extending functionality to handle previously unsupported query patterns.

Confidence Score: 4/5

  • This PR is safe to merge with minor risk from the added complexity
  • The fix addresses a real crash bug with a well-structured solution that follows existing patterns. The recursive getASTDescription call is already used elsewhere in the codebase, so the approach is proven. Two comprehensive tests validate the core scenarios. Score is 4/5 (not 5/5) due to: (1) the high complexity of the type inference logic making it difficult to reason about all edge cases, (2) potential performance implications of recursive parsing for deeply nested queries, and (3) the fallback mechanism in getDescribedColumnRef could potentially mask other issues if it catches cases it shouldn't
  • packages/generate/src/ast-describe.ts - pay attention to the new fallback resolution logic and ensure it doesn't inadvertently resolve columns from unintended scopes in complex multi-CTE queries

Important Files Changed

File Analysis

Filename Score Overview
.changeset/large-insects-peel.md 5/5 Standard changeset file following conventional format, correctly describes the fix as a patch-level change
packages/generate/src/ast-describe.ts 4/5 Core fix for array_agg type inference - adds early return for empty described arrays, context updates for CTEs/subselects, new fallback resolution function, and literal union normalization. Logic appears sound but high complexity warrants careful testing
packages/generate/src/generate.test.ts 5/5 Two comprehensive test cases added covering union subquery and CTE scenarios with array_agg and coalesce. Tests properly validate the expected type structures

Sequence Diagram

sequenceDiagram
    participant Query as SQL Query (array_agg from union/CTE)
    participant GAD as getASTDescription
    participant GAAF as getDescribedArrayAggFunCall
    participant GCR as getDescribedColumnRef
    participant GCFS as getDescribedColumnRefFromSelectSources
    participant GCFSS as getDescribedColumnsFromSelect
    participant NLU as normalizeLiteralUnion
    
    Query->>GAD: Process query with array_agg
    GAD->>GAAF: Handle array_agg function call
    GAAF->>GCR: Resolve column reference from arg
    
    alt Column from union subquery/CTE
        GCR->>GCFS: Schema lookup fails, try select sources
        GCFS->>GCFSS: Get columns from CTE/subselect
        GCFSS->>GAD: Recursively parse subselect
        GAD-->>GCFSS: Return described columns
        GCFSS-->>GCFS: Return matching column
        GCFS-->>GCR: Return column description
    end
    
    GCR-->>GAAF: Return described column (may be union with literals)
    GAAF->>NLU: Normalize literal unions to base types
    NLU-->>GAAF: Return normalized type
    GAAF-->>GAD: Return array type with correct element type
Loading

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a206eae069

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @packages/generate/src/ast-get-sources.ts:
- Around line 143-147: The early-return only handles inheritedSource?.kind ===
"cte" but must also treat "subselect" the same; locate the logic that sets
inheritedSource using prevSources?.get(node.RangeVar.relname) (and where
combinedPrevSources merges kind: "subselect" entries) and change the condition
to check for inheritedSource?.kind === "cte" || inheritedSource?.kind ===
"subselect" so that when a RangeVar.relname matches a previously recorded
subselect it is returned immediately just like a CTE.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a206eae and 29d44ce.

📒 Files selected for processing (4)
  • .changeset/large-insects-peel.md
  • packages/generate/src/ast-describe.ts
  • packages/generate/src/ast-get-sources.ts
  • packages/generate/src/generate.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/large-insects-peel.md
🧰 Additional context used
🧬 Code graph analysis (1)
packages/generate/src/ast-describe.ts (3)
packages/generate/src/ast-get-sources.ts (1)
  • SourcesResolver (6-6)
packages/ast-types/src/index.ts (3)
  • ColumnRef (1701-1704)
  • SelectStmt (887-908)
  • ParseResult (4-7)
packages/generate/src/ast-decribe.utils.ts (1)
  • isColumnUnknownRef (15-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: check (17)
  • GitHub Check: check (16)
🔇 Additional comments (12)
packages/generate/src/ast-get-sources.ts (2)

109-114: LGTM!

The cteSources mapping correctly transforms CTE entries into CteSubselectSource objects with kind: "cte", making them available for subsequent resolution.


216-220: Verify source merge order for potential shadowing.

The merge order places cteSources last, meaning CTE sources will override any conflicting names from prevSources or fromClause. This is likely intentional to allow CTEs to shadow outer scopes, but worth confirming this matches PostgreSQL's scoping semantics.

packages/generate/src/ast-describe.ts (7)

30-31: LGTM!

Adding prevSources as an optional parameter to ASTDescriptionOptions enables threading source context through nested descriptions, which is essential for resolving columns in CTEs and subselects.


916-927: Core fix for issue #441 - correctly handles empty described arrays.

This guard prevents the TypeError: Cannot read properties of undefined (reading 'type') by checking if firstArg.described.length === 0 and returning an array type with unknown elements. This matches the approach used for json_agg handling at lines 965-967.


943-943: Normalize literal unions for consistent array element types.

Using normalizeLiteralUnion here ensures that when the first argument's type is a union of literals (e.g., from UNION subqueries), they are collapsed to their base types. This prevents overly specific literal types in the resulting array.


1091-1114: Extended context resolution for CTE and subselect sources.

The updated getContextForColumnRef now properly sets the resolver and select context when the source is a CTE or subselect, enabling accurate column description resolution from nested queries.


1134-1140: Two-phase resolution strategy for column references.

The updated flow tries schema-based resolution first, then falls back to select-sources resolution. This is a sensible approach that maintains backward compatibility while enabling resolution from CTEs and subselects.


1197-1252: New select-sourced resolution functions.

getDescribedColumnRefFromSelectSources and getDescribedColumnsFromSelect enable column resolution from CTE and subselect sources by re-describing the nested SELECT statement. The implementation correctly:

  1. Only handles unknown column references (single-field ColumnRef)
  2. Collects selects from CTEs and subselects
  3. Uses getASTDescription to get column descriptions
  4. Filters by matching column name

One note: getDescribedColumnsFromSelect may compute descriptions multiple times for the same select if called repeatedly. Consider memoization if performance becomes a concern.


1461-1474: LGTM!

normalizeLiteralUnion correctly collapses unions containing literal types to their base types using getBaseType and mergeDescribedColumnTypes. This ensures consistent type inference for array elements from UNION queries.

packages/generate/src/generate.test.ts (3)

924-949: Good test coverage for the core issue.

This test validates array_agg over a UNION subquery, which was one of the crash scenarios. The expected type { kind: "array", value: { kind: "type", value: "string", type: "text" } } correctly reflects that literal unions are normalized to their base types.


951-974: Excellent - this test covers the exact scenario from issue #441.

The test combines:

  1. CTE with UNION subquery
  2. array_agg on the UNION result
  3. coalesce wrapping the nullable array result

This directly validates the fix prevents the TypeError and produces correct type inference.


2393-2409: Validates CTE scalar subquery type inference.

This test confirms that a scalar subquery referencing a CTE correctly infers the column type (string for TEXT NOT NULL). The non-nullable result is expected since the CTE's name column is NOT NULL.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @packages/generate/src/generate.test.ts:
- Around line 2422-2438: The test "scalar subquery from CTE should infer correct
type" is wrong because scalar subqueries can return null; update the expected
result to a union of string and null (matching the other scalar subquery test),
and in the implementation change the call that handles EXPR_SUBLINK so it passes
nullable: true to resolveType (look for EXPR_SUBLINK handling where
resolveType(...) is invoked, and set nullable flag to true) so scalar subqueries
always include null in their inferred type.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29d44ce and 7c3f2ea.

📒 Files selected for processing (2)
  • packages/generate/src/ast-describe.ts
  • packages/generate/src/generate.test.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/generate/src/ast-describe.ts (2)
packages/generate/src/ast-get-sources.ts (1)
  • getSources (42-483)
packages/generate/src/ast-decribe.utils.ts (1)
  • isColumnUnknownRef (15-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: check (16)
  • GitHub Check: check (17)
🔇 Additional comments (12)
packages/generate/src/ast-describe.ts (9)

30-31: LGTM! Well-designed optional parameters for CTE context propagation.

The addition of prevSources and cteSelects as optional parameters cleanly extends the API without breaking existing callers.


96-102: LGTM! Correct CTE collection with proper defensive checks.

The logic correctly merges inherited CTEs from params.cteSelects with CTEs from the current SELECT statement's WITH clause. The null checks on ctequery?.SelectStmt and ctename ensure robustness.


618-619: LGTM! Proper context threading for nested resolution.

Passing context.resolver.sources as prevSources and context.cteSelects enables nested SELECT statements to resolve columns from parent CTEs and subqueries correctly.


927-938: LGTM! Core fix for Issue #441 - empty-array guard prevents TypeError.

This guard correctly handles the case where array_agg() is applied to UNION subqueries or CTEs that result in an empty described array. Returning an array of unknown elements mirrors the approach in getDescribedJsonAggFunCall and prevents the TypeError when accessing firstArg.described[0].type.


1484-1496: LGTM! Clean normalization of literal unions to base types.

This helper correctly collapses unions like 'a' | 'b' into their base type string, ensuring array_agg over literal-valued UNION branches infers string[] rather than a union of literal types. The implementation properly short-circuits for non-unions and unions without literals.


1102-1128: LGTM! Correct context switching for CTE and subselect sources.

The enhanced logic properly retrieves the SelectStmt for both CTE and subselect sources, enabling column references like cte.column to be resolved against the correct resolver context. The fallback to context.select when the select is not found is a reasonable defensive measure.


1145-1151: LGTM! Proper fallback chain for column resolution.

The refactored getDescribedColumnRef correctly prioritizes schema-based resolution and only falls back to select-sourced resolution when needed. This enables columns from CTEs and subqueries to be resolved without polluting the main resolution path.


1208-1246: LGTM! Comprehensive select-sourced column resolution.

The helper correctly handles three source types:

  1. RangeSubselect - inline subqueries
  2. RangeVar - CTE references via cteSelects lookup
  3. JoinExpr - recursively processes both sides

The flat-map over all matching columns enables proper type inference when multiple sources might provide the same column name.


1248-1274: LGTM! Clean helper for re-describing a SELECT statement.

The function correctly wraps a SelectStmt in a synthetic ParseResult and threads all necessary context (including prevSources and cteSelects) to the recursive getASTDescription call. This enables proper type inference for columns from nested selects and CTEs.

packages/generate/src/generate.test.ts (3)

924-949: LGTM! Good regression test for Issue #441.

This test directly validates the fix for the TypeError that occurred when array_agg() was applied to UNION subqueries. The expected type string[] | null is correct.


951-978: LGTM! Important test for CTE type isolation.

This test ensures that only the referenced CTE (foo) influences type inference, and the unused CTE (bar with integer type) doesn't leak into the result. This validates the fix mentioned in the commit message.


980-1003: LGTM! Good edge case test for coalesce with array_agg.

This test validates that coalesce(array_agg(...), ARRAY[]::TEXT[]) correctly infers a non-nullable string[] type, combining CTE resolution with nullability handling.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/generate/src/ast-get-sources.test.ts (1)

1-45: Test validates subselect inheritance correctly.

The test appropriately covers the new prevSources inheritance behavior for RangeVar lookups. The setup is clean and the assertion validates the core fix for issue #440.

Consider adding edge case coverage:

  1. A test for CTE source inheritance (kind: "cte")
  2. A test verifying column resolution through inherited subselects
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c3f2ea and a41e2b1.

📒 Files selected for processing (4)
  • packages/generate/src/ast-describe.ts
  • packages/generate/src/ast-get-sources.test.ts
  • packages/generate/src/ast-get-sources.ts
  • packages/generate/src/generate.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/generate/src/generate.test.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/generate/src/ast-get-sources.test.ts (3)
packages/generate/src/generate.ts (1)
  • PgColRow (650-661)
packages/generate/src/utils/get-relations-with-joins.ts (1)
  • FlattenedRelationWithJoins (74-79)
packages/generate/src/ast-get-sources.ts (1)
  • getSources (42-483)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: check (16)
  • GitHub Check: check (17)
🔇 Additional comments (14)
packages/generate/src/ast-get-sources.ts (3)

109-114: CTE sources map construction is correct.

The transformation from the ctes resolver map to cteSources with the { kind: "cte", name, sources } shape is properly implemented and aligns with the CteSubselectSource type definition.


143-147: Inherited source lookup correctly prioritizes CTE/subselect propagation.

The early return for inherited CTE and subselect sources enables proper type propagation for scalar subqueries referencing CTEs, addressing issue #440. The conditional correctly excludes table sources, which should be resolved fresh from schema metadata.


216-220: Source merging order correctly prioritizes local CTEs.

The merge order ensures CTEs defined in the current WITH clause take precedence over inherited sources and from-clause sources, which matches PostgreSQL's scoping semantics where CTEs shadow tables of the same name.

packages/generate/src/ast-describe.ts (11)

30-31: New optional parameters correctly typed.

The prevSources and cteSelects parameters are appropriately optional to maintain backward compatibility while enabling context propagation for nested CTE/subselect resolution.


104-116: Context initialization correctly threads CTE and source information.

The cteSelects and prevSources are properly wired into the context and resolver, enabling the nested resolution features.


589-595: Correct nullability handling for scalar subqueries.

Scalar subqueries (EXPR_SUBLINK) can return NULL when no rows match, so marking them as nullable is accurate. EXISTS sublinks always return a boolean, so they correctly remain non-nullable.


618-619: Proper context threading for nested SELECT descriptions.

Passing context.resolver.sources and context.cteSelects to nested getASTDescription calls enables correct type resolution for CTEs and subselects referenced in nested queries.


927-938: Core fix for issue #441: prevents crash on empty described array.

This guard correctly handles the case when array_agg() receives input from UNION subqueries or CTEs where firstArg.described is empty. Returning an array of unknown is an appropriate fallback that prevents the TypeError while maintaining type safety.


954-954: Normalizing literal unions improves type inference accuracy.

Applying normalizeLiteralUnion prevents overly specific literal types (e.g., Array<1 | 2>) and instead produces the expected base type (e.g., Array<number>), which is the correct inference for aggregated values.


1102-1125: Context switching for CTE and subselect column resolution is well-implemented.

The code correctly updates both the resolver and select properties when resolving columns from CTE or subselect sources. The fallback to context.select when the SelectStmt isn't found prevents crashes while maintaining reasonable behavior.


1145-1151: Fallback to select-sourced resolution enables CTE column inference.

The two-phase approach—schema-based resolution first, then select-sourced resolution—correctly handles columns from CTEs and subselects that aren't present in the database schema.


1208-1274: New select-sourced resolution functions correctly handle CTE and subselect columns.

The implementation properly:

  1. Extracts SelectStmt from various source types (RangeSubselect, RangeVar via cteSelects, JoinExpr recursively)
  2. Recursively describes nested selects with proper context threading
  3. Filters columns by name matching

Note: If multiple sources define a column with the same name, all matching columns are returned via flatMap. This is acceptable since PostgreSQL would require qualification in such ambiguous cases, but be aware this could return multiple results.


1483-1496: normalizeLiteralUnion correctly collapses literal unions to base types.

The function properly detects unions containing literals and merges them to their base types, which is essential for producing sensible array element types from array_agg over union subqueries.


96-102: No fix needed. The code correctly handles undefined values.

new Map(undefined) does not throw a TypeError—it returns an empty Map(0) {}, which is the correct behavior. Since cteSelects is defined as an optional property in the type signature, passing undefined to the Map constructor is the intended pattern and works as expected.

Likely an incorrect or invalid review comment.

@Newbie012 Newbie012 merged commit 58fcf59 into main Jan 13, 2026
5 checks passed
@Newbie012 Newbie012 deleted the fix-array-agg-inference branch January 13, 2026 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants