Repository navigation
fix(postgres): type a window aggregate over the current row as not null - #113
Merged
Merged
Conversation
Contributor
|
No configured credential can serve this run. Your Claude Pro/Max subscription has hit its usage limit, which resets at 2026-10-26 08:00 UTC. Re-trigger after it resets, or add an API key for this provider, which Pullfrog falls back to automatically. The providers' responses
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

An aggregate used as a window function was typed nullable whatever its frame. Such an aggregate (
sum,avg,min,max,bit_and,bit_or,bool_and,bool_or,every,string_agg,array_aggand the JSON aggregates) is NULL only when no non-null input reaches it, and a frame that always holds the current row has that row's input. So now, as under a plainGROUP BY, it follows its argument there: non-null when the argument is (array_aggand the JSON aggregates are non-null outright).sum(count(*)) over (order by date_trunc('month', published_at)), grouped by the monthsum(p.id) over (order by p.id),over (),over (partition by p.user_id)max(p.title) over (partition by p.user_id)sum(p.id) over wwithwindow w as (partition by p.user_id order by p.id)sum(p.id) over (order by p.id rows between 1 following and 2 following)sum(p.id) filter (where …) over ()sum(p.id)with nogroup byFrames that hold the current row. No frame clause (
RANGE UNBOUNDED PRECEDING, through the current row's last peer, or the whole partition withoutORDER BY), and anyROWS,RANGEorGROUPSframe that starts atUNBOUNDED PRECEDING,n PRECEDINGorCURRENT ROWand ends atCURRENT ROW,n FOLLOWINGorUNBOUNDED FOLLOWING, withEXCLUDE TIESorEXCLUDE NO OTHERS. An offset must be non-null and non-negative or the statement fails, and inRANGEmode the current row is no distance from itself, NULL, NaN and the infinities included (measured on PostgreSQL 18 overfloat8,numericandtimestamptz, and checked by the oracle's edge values).Frames that can leave it out, which stay nullable: a start
n FOLLOWING, an endn PRECEDING,EXCLUDE CURRENT ROWandEXCLUDE GROUP, and any aggregate with aFILTER.Named windows.
OVER wtakes the frame ofwin the statement'sWINDOWclause (nothing is claimed when no such window is there);OVER (w …)andAS (w …)use their own frame clause, since the server refuses to copy a window that has one.The rule is
frame_holds_current_rowinengine/postgres/src/infer.rs, read from the parser's frame option bits, andjsonshape.rsuses it too, so a JSON aggregate over such a window is a non-null JSON array.oracle/cases/window_aggregates: 20 statements over every frame above, with NULL, NaN and infinite ordering values. No other case'sexpected.txtchanged.Checks:
cargo build --workspace --all-targetswith no warning,cargo testof every crate, the whole oracle with--strict-coverage(131 cases, 0 failed),engine/build.sh(only the Postgres artifact changes),nub run typecheck,nub run testwith both databases (254 passed, 0 skipped),nub run build, and the site's capture and build.