8000 feat(postgres): type json a with query or derived table builds by colinhacks · Pull Request #3 · colinhacks/reylo · GitHub
[go: up one dir, main page]

Skip to content

feat(postgres): type json a with query or derived table builds - #3

Merged
colinhacks merged 3 commits into
mainfrom
json-shapes-through-items
Oct 22, 2026
Merged

colinhacks merged 3 commits into
mainfrom
json-shapes-through-items

Conversation

@colinhacks
Copy link
Copy Markdown
Owner

On Postgres, JSON a statement builds with jsonb_build_object, jsonb_agg or to_jsonb is typed from its arguments, but only where the statement builds it. JSON built inside a with query or a derived table and selected from outside it was unknown. Now such a column has the type of the JSON that query's own statement builds:

  • read as it is in the select list;
  • read inside JSON the outer statement builds (jsonb_build_object('posts', ps.posts), jsonb_agg(s.post));
  • under coalesce(ps.posts, '[]'), for an array, which is then never NULL;
  • through a chain of with queries, four deep at most.

The column is as nullable as the query's own result and the joins over it make it, which is how its nullability was already settled.

Statement Before After
with s as (select jsonb_build_object('id', id, 'title', title) as post from posts) select post from s post: json post: { id: int8, title: text }
with ps as (select user_id, jsonb_agg(jsonb_build_object('id', id)) as posts from posts group by user_id) select u.name, ps.posts from users u left join ps on ps.user_id = u.id posts: json? posts: [{ id: int8 }]?
the same with coalesce(ps.posts, '[]') as posts posts: json posts: [{ id: int8 }]
select jsonb_build_object('stats', s.stats) from (select jsonb_build_object('count', count(*)) as stats from posts) s { stats: unknown } { stats: { count: int8 } }

What stays unknown: a column of a union inside the query, a lateral subquery, a * over the query, and coalesce of an object with '[]'. Under coalesce(…, '[]') inside a constructor the array keeps its type but stays nullable.

Tests:

  • oracle/cases/json_item_shapes: 19 statements, sound over the seeded edge values.
  • A unit test for the coalesce(c, '[]') read.
  • Run locally: the Rust build and tests, the artifact fingerprint, the oracle with --strict-coverage, the loader's typecheck and tests, the package build, and the basic and JSON Schema labs.

Copilot AI balanced review requested due to automatic review settings October 22, 2026 15:59
@vercel
vercel Bot commented Oct 22, 2026 •
Copy link
Copy Markdown

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

Project Deployment Actions Updated
reylo Ready Ready Preview Oct 22, 2026 6:46pm UTC

Request Review

@pullfrog
pullfrog Bot commented Oct 22, 2026 •
Copy link
Copy Markdown
Contributor

No configured credential can serve this run. Your Claude Pro/Max subscription was rejected. Sign in again by running pullfrog auth claude in a terminal.

The providers' responses
CLAUDE_CODE_OAUTH_TOKEN: 401: OAuth access token has been revoked.

Pick another model →

Pullfrog  | Rerun failed job ➔ | View workflow run | via Pullfrog | Using claude-opus-5-5

Copilot AI left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@pullfrog
pullfrog Bot commented Oct 22, 2026
Copy link
Copy Markdown
Contributor

Warning

Your Claude Pro/Max subscription token is revoked, so every run stops before the agent starts.

Every Pullfrog run on colinhacks has failed since October 21 (5 runs, no successes), so this review did not happen.

Anthropic returns "OAuth access token has been revoked" for the CLAUDE_CODE_OAUTH_TOKEN stored on your account, which means your Claude subscription authorization has expired or been revoked. The repo is set to anthropic/claude-opus, which requires a valid Claude subscription or an Anthropic API key, and no other credential is configured to serve that model.

To fix it:

  1. Reauthorize your Claude subscription by running npx pullfrog auth claude in the reylo repo — the setup docs have the details.
  2. If you prefer to use an API key instead, add an ANTHROPIC_API_KEY on the BYOK tab of your Billing card.

@colinhacks
colinhacks force-pushed the json-shapes-through-items branch from b6b18bc to d3029e9 Compare October 22, 2026 16:33
@pullfrog
pullfrog Bot commented Oct 22, 2026
Copy link
Copy Markdown
Contributor

No configured credential can serve this run. Your Claude Pro/Max subscription was rejected. Sign in again by running pullfrog auth claude in a terminal.

The providers' responses
CLAUDE_CODE_OAUTH_TOKEN: 401: OAuth access token has been revoked.

Pick another model →

Pullfrog  | Rerun failed job ➔ | View workflow run | via Pullfrog | Using claude-opus-5-5

@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ No critical issues. Typing JSON through items looks sound, and there are two minor suggestions inline.

Reviewed changes

The branch was force-pushed to a single commit, and no earlier Pullfrog review exists, so this review covers the whole PR.

  • Typed JSON through items: A JSON column read straight from a with query or a derived table now resolves to the type the item's own constructors build. This works in the select list and inside outer constructors, through Engine::built / Engine::item_built, at most MAX_ITEM_DEPTH = 4 levels deep.
  • Added ItemRead::Defaulted: coalesce(c, '[]') of such a column is recognized and, for an array, typed as never NULL. item_columns treats it as no settled read, which matches the old behavior.
  • Carried built JSON through probes: jsonshape::Outcome.built lets a Shape::Column inside a constructor use the item's built type. Nullability still comes from the probe column, and inner unresolved paths are rejoined under the outer path.
  • Extracted Engine::shapes and Engine::stored_checks: The probe loop and the stored-row CHECK lookup can now run once per item level.
  • Added the json_item_shapes oracle case and docs: 19 statements cover objects, aggregates, renames, chains, parameters, outer joins and the shapes that stay unknown.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread engine/postgres/src/jsonshape.rs Resolved
Comment thread engine/postgres/src/postgres.rs Resolved
@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found. Both earlier findings are fixed, and each fix is pinned by a test.

Reviewed changes

This review covers the two commits since the last Pullfrog review (d3029e9).

  • Fixed unresolv 8000 ed array paths under an outer key: Shape::Column now appends an item's unresolved path that starts with [] straight onto the outer path. That gives posts[].tags instead of posts.[].tags. The new resolver test checks [].tags, [] and the whole value.
  • Described all probes before following items: Engine::shapes now describes every probe in plan.probes first. It follows their items in a second pass. Item traces can therefore only use the MAX_PROBES budget the statement's own probes leave, so a statement near the budget keeps the typing it already had. with_probe_budget.sql pins this: b1–b6 stay typed, and a gets its item's keys with unknown leaves.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

A JSON column read from a WITH query or a derived table was unknown,
whatever that query built. It now has the type of the JSON the query's
own statement builds, read as it is, inside JSON the statement builds,
or under coalesce(..., '[]') for an array.
Following the items one probe reads before describing the next probe
could spend the probe budget a later probe needed, leaving JSON the
statement itself builds unknown.
@colinhacks
colinhacks force-pushed the json-shapes-through-items branch from e4908d4 to 6e1dc17 Compare October 22, 2026 18:44
@colinhacks
colinhacks merged commit 2d07055 into main Oct 22, 2026
4 checks passed
@colinhacks
colinhacks deleted the json-shapes-through-items branch October 22, 2026 18: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

0