Uh oh!
There was an error while loading. Please reload this page.
docs: fix invalid DISTINCT ON SQL in the s-strings book page - #6248
Conversation
prql-bot
left a comment
There was a problem hiding this comment.
The SQL correction is right, and it's the only from s"..." full-table example in the book, so there's nothing else carrying the same defect. Two notes, neither blocking.
The description's column list doesn't match the snapshot. The body says the compiler "recovers first_name, id, age", but the regenerated snapshot emits table_0.id, table_0.age, table_0.first_name. The set is recovered; the order isn't the s-string's. Worth rewording so a reader comparing the two doesn't stall on it.
Where that order comes from. In try_extract_sql_columns (prqlc/prqlc/src/semantic/lowering.rs), the extracted names are collected as .collect::<BTreeSet<String>>() under the comment // deduplicate extracted columns, but preserve their order — a BTreeSet sorts, so the comment and the type disagree. The emitted order is the already-inferred column (id, from the (==id) join) followed by the alphabetically sorted extraction (age, first_name), which reproduces the snapshot exactly. That's pre-existing and out of scope for a docs fix — swapping in an order-preserving set would move snapshots across the repo — but it's the reason the book now shows an output order that looks arbitrary, and it's worth a separate look.
Verification notes
- Confirmed the inference path is real, not incidental:
pl::ExprKind::SStringlowering callstry_extract_sql_columns, which parses the s-string withsqlparser'sGenericDialectand bails to the original (wildcard) columns on a parse error — so the previously invalid text is exactly why the old snapshot emittedtable_0.*. SELECT * FROM salariesstill hits thehas_wildcardbranch, which is whytable_1.*is unchanged.- Line length on the lengthened markdown line is not a lint concern:
MD013is disabled in.markdownlint-cli2.yaml, and prettier doesn't reflow inside code fences. - I did not rebuild the book snapshot locally;
test-rust (x86_64-unknown-linux-gnu, …, default,test-dbs-external,lsp)covers it and was still running when this was written.
prql-bot
commented
Aug 29, 2026
Reworded the description — it now says the column set is recovered and gives the emitted order verbatim ( On the The verification gap the review flagged is closed: |
The "we can also use s-strings to produce a full table" example in the s-strings reference page embeds SQL that no database accepts. PostgreSQL's grammar is
SELECT DISTINCT ON ( expression [, ...] ) select_list, so the parenthesised expression list is required; the example writesSELECT DISTINCT ON first_name, id, age, which is a syntax error. It also needsORDER BYto start with theDISTINCT ONexpressions. This corrects both, keeping the example's dialect-specific escape-hatch flavour intact.Verified against DuckDB (which implements PostgreSQL's
DISTINCT ON): the current text fails withParser Error: syntax error at or near "first_name", the corrected text parses.A nice side effect: the invalid SQL was also degrading PRQL's own inference.
prqlcreads column names out of an s-string relation, and the unparseable text made it give up and emittable_0.*. With valid SQL it recovers the column set, so the book's compiled output now enumerates the columns astable_0.id, table_0.age, table_0.first_name— that snapshot change is the compiler behaving better, not a regression. The emitted order isn't the s-string's:idleads as the already-inferred join column, and the extracted names follow alphabetically becausetry_extract_sql_columnscollects them into aBTreeSet. That ordering is pre-existing and untouched here.No regression test beyond the snapshot: the book examples are themselves compiled and snapshotted by
web/book/tests/documentation/book.rs, so the updated.snapis the test. Validity of the embedded SQL isn't something the test suite can check, since an s-string is opaque passthrough by design.Verification
Snapshot regenerated with
INSTA_UPDATE=always cargo test -p mdbook-prql --test documentation, then re-checked with a plaincargo test -p mdbook-prql --test documentation— 7 passed. That second run is a real assertion rather than a rewrite:CIis set in this environment, so insta's defaultautoresolves toNoUpdate. Onlydocumentation__book__reference__syntax__s-strings__3.snapis included. Three other snapshots have staleexpression:headers that a forced update also rewrites — those are unrelated pre-existing drift and are deliberately left out of this PR.