Add PostgREST query parsing as an opt-in dialect - #88
Open
kriszyp wants to merge 11 commits into
Open
Conversation
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
dawsontoth
reviewed
Sep 2, 2026
kriszyp
marked this pull request as ready for review
September 2, 2026 14:32
Read the file from its entry point down: parsePostgREST, then the query-parameter dispatch, then the per-parameter parsers, then operand and lexical helpers, under the section banners parser.ts already uses. No behavior change — the moved blocks are byte-identical. Rename the exported parser and options interface to match PostgREST's own capitalization, which the file's prose and the spec already use. Co-Authored-By: Claude Opus <noreply@anthropic.com>
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.
Summary
Add
parsePostgREST()as a zero-dependencyrql/postgrestpackage subpath that maps PostgREST query parameters into the same canonicalParseResultmodel as Core. The rootrqlexport remains Core-only.The operator mapping implements the Appendix E.2 rows for scalar
eq/gt/gte/lt/lte/neq/in/not, recursiveand/or/notlogic,any/all, arraycs/cd/ov,is.null/is.true/is.false, extension comparators including configured FTS, JSON-arrow paths,select,order,limit, andoffset.Unsupported-feature vectors fail loudly with
UnsupportedFeatureby default. Aliases, casts, null placement, aggregates, embedding and hints, related-resource ordering, structured or multidimensional containment, and empty-list operations without a canonical representation are intentionally unsupported.onUnsupported: "drop"is limited to projection aliases/casts and null-placement decoration where the remaining query retains its filtering and pagination meaning.Builds on #86.
For the human reviewer
Framing-Verdict: chosen-approach-sound. The separate subpath preserves the explicit dialect choice and leaves the normative Core surface unchanged.src/dialects/postgrest.tsnow reads trunk-first —parsePostgREST,syntaxViolation,parseInto, then the per-parameter parsers and finally the operand and lexical helpers — under the same// ── section ──bannerssrc/parser.tsalready uses. Function hoisting makes the forward calls valid; every moved block is byte-identical, which the independent reviewer verified block-by-block.src/parser.tsitself is still bottom-up, so the two files now disagree on direction — worth settling as a repo convention, but out of scope here.parsePostgRESTandPostgRESTOptions, matching PostgREST's own capitalization and the casing the file's prose and Appendix E already use. Therql/postgrestsubpath is unchanged. Nothing outside this unreleased alpha consumes either name, so reverting the rename costs onesed.meta.like=eq.5is a dotted top-level path, whileor=(meta.like.eq.5,b.eq.1)means fieldmeta, comparatorlike, operandeq.5; quoting permits operator-named path segments. This is the main spec ambiguity and is deliberately pinned for review before the dialect becomes stable.neqhas RQL set-complement behavior around absent values;is.nullcannot distinguish SQL null from absence; schema-free dotted embedded filters inherit RQL's join behavior;->and->>collapse to canonical paths; FTS configuration is folded into the opaque comparator name; non-finite spellings remain strings.cs.{}and non-collapsible emptyany/allexpansions. JSON/range containment, multidimensional arrays, aggregates, embeddings, and related ordering also fail closed instead of silently changing results.parseQuery('not(tags[=not_in=(red,blue)])')rejects Appendix E.2's stated canonical spelling, preventing a directcdequivalence assertion.Verification
npm test— 251 passing tests across 38 suites, including the unchanged 111-test Core suitenpm run typechecknpm pack --dry-run --json— includes built JavaScript and declarations fordist/dialects/postgrestrg -n "postgrest|parsePostgREST" src/index.ts test/v2— no matchesmediumeffort: LGTM, no findings, with the move verified as byte-identical across all 26 functions. Gemini coverage was unavailable because its local CLI is not authenticated. Two later attempts to re-review the assembled 1,253-line diff in a single pass both exhausted their run budget (Codex atxhighand again atmedium, with Cursor/Grok timing out alongside it), so independent coverage on this branch is per-commit — each commit reviewed as the delta that introduced it — rather than one pass over the finished file.Complexity: complicated
Generated by GPT-5 Codex; review-feedback round by Claude Opus.
Review-Coverage: authored=claude; ran=codex; declined=gemini,cursor-grok,cursor-composer,domain; rounds=1 @ ab9462f
Human-Review-Need: 2 @ ab9462f