Skip to content

Conversation

@Newbie012
Copy link
Collaborator

@Newbie012 Newbie012 commented Sep 26, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Correctly infers nullable types for JSONB operators (->>, #>>) when paths depend on column values.
    • Ensures literal-path extraction returns non-null strings.
    • Improves nullability handling for jsonb_build_object with mixed column/literal inputs.
  • Tests

    • Expanded test coverage for JSONB extraction and nullability scenarios.
  • Chores

    • Added changeset to publish a patch release of @ts-safeql/generate.

@vercel
Copy link

vercel bot commented Sep 26, 2025

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

1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
safeql Ignored Ignored Sep 26, 2025 1:37pm

@changeset-bot
Copy link

changeset-bot bot commented Sep 26, 2025

🦋 Changeset detected

Latest commit: cf14451

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

@coderabbitai
Copy link

coderabbitai bot commented Sep 26, 2025

Walkthrough

Patch release prep for @ts-safeql/generate adds a changeset entry and updates AST typing logic to infer nullability for jsonb operators (->>, #>>) when operands include column references. New helper scans ASTs for column refs. Tests expanded to cover jsonb extraction/build scenarios and nullability outcomes.

Changes

Cohort / File(s) Summary
Release metadata
\.changeset/clever-rockets-act.md
Adds a changeset for a patch release describing a fix to nullable inference for jsonb operators with column references.
AST typing and nullability
packages/generate/src/ast-describe.ts
Introduces hasColumnReference for recursive AST analysis; adds getNullable for AExpr-driven nullability; updates getType to use getNullable; extends object literal handling to jsonb; enforces nullable rules for ->> and #>> when LHS contains column refs; includes duplicated hasColumnReference implementation.
Tests for jsonb operators
packages/generate/src/generate.test.ts
Adds tests covering ->> and #>> nullability and types across literals, subselects, and jsonb_build_object cases; includes a duplicated assertion for ->> returning string | null.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Test/Query
  participant Type as getType()
  participant Null as getNullable()
  participant Scan as hasColumnReference()

  Dev->>Type: Describe AExpr (jsonb ->> / #>>)
  Type->>Null: Compute nullability
  Null->>Scan: Check AST for ColumnRef
  alt LHS has column reference
    Note over Null,Type: Enforce nullable for ->>, #>>
  else No column reference
    Note over Null: Use literal/object rules and column flags
  end
  Type-->>Dev: Type with updated nullability (e.g., string \| null)

  Note over Type: Object literals in AExpr resolved as jsonb
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I nibble through JSON, hop by hop,
Keys go “->>” and strings plop-pop.
If columns hide, then null may sprout;
My whiskers twitch to figure it out.
Patch squeaks in, tests thump along—
Safe queries hum a rabbit song. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “fix jsonb operator nullability inference” accurately and succinctly summarizes the primary change in the pull request, which updates how the →> and #>> operators infer nullable types. It is clear, specific, and directly related to the modifications made in the code and tests. This phrasing avoids unnecessary detail while conveying the core purpose of the patch. Teammates scanning the history will immediately understand the intent of this change.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-json-operators-inference

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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 (3)
packages/generate/src/generate.test.ts (1)

2044-2061: Avoid asserting unknownColumns to reduce test fragility.

unknownColumns depends on generator internals and can change unrelated to behavior. Recommend not asserting it here.

Apply this diff:

 test(`jsonb subselect ->> key => string | null`, async () => {
   await testQuery({
     query: `SELECT (SELECT data FROM employee LIMIT 1) ->> 'myKey' as extracted_value`,
     expected: [
       [
         "extracted_value",
         {
           kind: "union",
           value: [
             { kind: "type", value: "string", type: "text" },
             { kind: "type", value: "null", type: "null" },
           ],
         },
       ],
     ],
-    unknownColumns: ["extracted_value"],
   });
 });
packages/generate/src/ast-describe.ts (2)

355-369: Targeted nullable inference for ->> and #>> is appropriate.

  • Honors explicit non-null markers and operand nullability.
  • Adds operator-aware nullability when LHS includes a column reference.

Consider extending later to other JSON extraction operators if needed.


1108-1171: Extract and harden hasColumnReference

  • Move this helper into ast-describe.utils for reuse and testing
  • Add handling for ParamRef and RelabelType:
 function hasColumnReference(node: LibPgQueryAST.Node | undefined): boolean {
   if (node === undefined) {
     return false;
   }

   if (node.ColumnRef !== undefined) {
     return true;
   }
+  if (node.ParamRef !== undefined) {
+    return true;
+  }

   if (node.A_Const !== undefined) {
     return false;
   }

   if (node.TypeCast !== undefined) {
     return hasColumnReference(node.TypeCast.arg);
   }
+  if (node.RelabelType !== undefined) {
+    return hasColumnReference(node.RelabelType.arg);
+  }

   // …
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee808b4 and cf14451.

📒 Files selected for processing (3)
  • .changeset/clever-rockets-act.md (1 hunks)
  • packages/generate/src/ast-describe.ts (3 hunks)
  • packages/generate/src/generate.test.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/generate/src/ast-describe.ts (4)
packages/ast-types/src/index.ts (1)
  • Node (14-253)
packages/generate/src/utils/get-nonnullable-columns.ts (1)
  • isColumnNonNullable (79-201)
packages/generate/src/ast-get-sources.ts (1)
  • resolveColumn (426-436)
packages/generate/src/ast-decribe.utils.ts (2)
  • isColumnUnknownRef (15-19)
  • isColumnStarRef (3-7)
⏰ 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). (1)
  • GitHub Check: check (ubuntu-latest, 20)
🔇 Additional comments (7)
.changeset/clever-rockets-act.md (1)

5-5: Good, concise changeset entry.

Accurately reflects the behavior change for ->> and #>> nullability.

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

2037-2042: Nice coverage for jsonb #>> with literal path.

Validates non-nullable string result for constant jsonb and path.


2063-2079: Good: jsonb_build_object with column ->> key yields string | null.

Matches nullable inference when LHS includes a column reference.


2081-2086: Good: jsonb_build_object without column ->> key yields string.

Confirms non-null for fully-constant LHS.


2369-2385: Solid direct operator coverage on column jsonb ->> key.

Ensures the common case returns string | null.

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

311-313: Correctly treats object-typed expressions as jsonb for operator resolution.

This enables downcasting for jsonb_build_object(...) on the LHS of operators.


370-401: Using computed nullable in resolveType is the right integration point.

Keeps type mapping separate from nullability policy.

@Newbie012 Newbie012 merged commit bd0f64b into main Sep 26, 2025
4 checks passed
@Newbie012 Newbie012 deleted the fix-json-operators-inference branch September 26, 2025 13:47
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