Skip to content

Conversation

@Newbie012
Copy link
Collaborator

@Newbie012 Newbie012 commented Dec 22, 2025

Summary by CodeRabbit

New Features

  • UNNEST function now provides proper type inference when expanding arrays into rows, with support for standard arrays, multidimensional arrays, enum arrays, and nullable array types.

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

@changeset-bot
Copy link

changeset-bot bot commented Dec 22, 2025

🦋 Changeset detected

Latest commit: 7fc74d9

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 Minor
@ts-safeql/eslint-plugin Minor
@ts-safeql/shared Minor
@ts-safeql/sql-ast Minor
@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 Dec 22, 2025

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

1 Skipped Deployment
Project Deployment Review Updated (UTC)
safeql Ignored Ignored Dec 22, 2025 9:10am

@coderabbitai
Copy link

coderabbitai bot commented Dec 22, 2025

Walkthrough

Adds support for the unnest function in type inference by introducing a new handler in ast-describe.ts that unwraps nested array types and simplifies union types, accompanied by comprehensive test coverage validating unnest behavior across arrays, enums, and multidimensional structures.

Changes

Cohort / File(s) Change Summary
Changeset
.changeset/slimy-walls-prove.md
Documents minor version bump for @ts-safeql/generate with note on unnest function support for correct typing of expanded arrays.
UNNEST Handler Implementation
packages/generate/src/ast-describe.ts
Adds getDescribedUnnestFunCall function that handles unnest calls by unwrapping nested array types and simplifying unions; integrates into getDescribedFuncCall routing. Includes recursive unwrap helper for flattening arrays, removing nulls from unions, and stripping underscore prefixes.
Test Coverage
packages/generate/src/generate.test.ts
Introduces five new test cases validating unnest behavior: text arrays, enum arrays, multidimensional arrays, nullable arrays, and nullable arrays with NULL elements.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • ast-describe.ts: The recursive unwrap logic and union-type handling require careful verification to ensure edge cases (null handling, underscore stripping) work as intended across different type structures.
  • generate.test.ts: Review test assertions against expected type outputs, particularly enum union formation and multidimensional array unwrapping.
  • Interaction: Verify that the unnest handler integrates seamlessly with existing type-inference pipeline and doesn't cause regressions.

Possibly related PRs

Poem

🐰 An array so deep, we help it unnest,
Peeling back layers, we know what is best,
Enums and ints now sing in their rows,
From multidimensional depths, clarity flows! 🌱

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding support for the unnest function to enable proper type inference for array expansion, which is exactly what the changeset implements.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-unnest-support

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.

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-describe.ts (1)

810-851: Solid implementation with correct unnest semantics.

The unwrap helper correctly handles:

  • Recursive array unwrapping for multidimensional arrays
  • Union type simplification (removing outer null from nullable arrays while preserving inner nulls)
  • PostgreSQL array type name normalization (stripping underscore prefix)

The null filtering logic on Line 837 is particularly well-designed: !hasArray || !(t.kind === "type" && t.value === "null") ensures that date[] | null unwraps to Date (outer null removed), while ARRAY[1, NULL] unwraps to 1 | null (inner null preserved).

💡 Optional: Add explanatory comment for null filtering logic

Consider adding a brief comment above Line 837 to document the intentional behavior:

      const unwrapped = type.value
+       // Remove outer null (array itself being null) but preserve inner nulls (null elements within array)
        .filter((t) => !hasArray || !(t.kind === "type" && t.value === "null"))
        .map(unwrap);

This would help future maintainers understand the distinction between outer and inner nullability.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3770f8a and 7fc74d9.

📒 Files selected for processing (3)
  • .changeset/slimy-walls-prove.md
  • 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 (1)
packages/ast-types/src/index.ts (1)
  • FuncCall (1711-1723)
⏰ 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 (3)
.changeset/slimy-walls-prove.md (1)

1-5: LGTM! Changeset documentation is clear and accurate.

The changeset appropriately documents the new unnest function support with a minor version bump, and clearly describes the feature including multidimensional arrays and enums.

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

803-804: LGTM! Unnest function properly integrated.

The new case correctly delegates to the dedicated handler, following the existing pattern for other special functions like array_agg and jsonb_agg.

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

2512-2585: Excellent test coverage for unnest functionality!

The test suite comprehensively validates unnest behavior across critical scenarios:

  • Text arrays → unwrapped to base type
  • Enum arrays → union of enum values preserved
  • Multidimensional arrays → fully flattened to union of all elements
  • Nullable arrays (date[] | null) → outer null correctly removed
  • Arrays with null elements (ARRAY[1, NULL]) → inner null correctly preserved

The test cases align perfectly with PostgreSQL unnest semantics and confirm the implementation handles the nuanced difference between outer (array-level) and inner (element-level) nullability.

@Newbie012 Newbie012 merged commit f05d9f4 into main Dec 22, 2025
5 checks passed
@Newbie012 Newbie012 deleted the feat-unnest-support branch December 22, 2025 09:15
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.

ℹ️ 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".

Comment on lines +818 to +820
const firstArg = node.args?.at(0);
if (firstArg === undefined) {
return [{ name, type: context.toTypeScriptType({ name: "unknown" }) }];

Choose a reason for hiding this comment

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

P1 Badge Infer columns for all UNNEST arguments

getDescribedUnnestFunCall only inspects node.args?.at(0) and builds a single column from that one argument, so calls like SELECT * FROM unnest(arr1, arr2) or unnest(... ) WITH ORDINALITY will drop the additional returned columns in the inferred schema. That produces an incorrect column count and types for valid UNNEST usages involving multiple arrays, which will make the generated typings diverge from the actual query results.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants