You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
assertSortFieldsExist's dotted-path SORT hint also prescribes an unmaterializable "formula or rollup" denormalization — same defect class as #6673, different axis #6924
#6673 fixed two packages/lint hints that told authors to mirror a related record's value onto a formula field for searchableFields — a fix that can't work because a formula field is virtual (no driver materializes a column for it) and CEL only reads the record's own fields.
While re-verifying #6673's third named target (protocol.ts:4780, claimed to be inside assertSearchFieldsAreSearchable), I found that text actually lives in a different function: assertSortFieldsExist (packages/metadata-protocol/src/protocol.ts:4745), guarding the SORT axis (#4226/#4256), not searchableFields/#4254 at all.
The text, and why it may be the same defect
protocol.ts:4780 (in assertSortFieldsExist, for a dotted-path orderBy like ?sort=account.company_name):
hint: ` Denormalise the value onto '${object}' (a formula or rollup field that`
+ ' copies it into a real column) and sort by that.',
This claims a formula/rollup(summary) field "copies it into a real column". By the same argument #6673 already established for formula: it's virtual, no driver materializes a column for it (packages/objectql/src/engine.ts:568-573 computes it post-query, in-memory; driver-sql/src/schema-drift.ts; driver-turso/src/remote-transport.ts). summary/rollup fields are likewise excluded from real-column treatment elsewhere in this same file (the clone copy-exclusion at protocol.ts:5941, "computed formula/summary fields"). So ORDER BY <formula-or-rollup-field> looks structurally like it should hit the exact same silent-degradation path #3821's backstop already covers for other unknown-column ORDER BYs: query succeeds, rows are all there, order is arbitrary — the very failure mode #4226/#4256 exist to stop.
Not independently reproduced — I didn't run a live repro (formula field named directly, non-dotted, in orderBy) proving the driver silently drops the sort; this is inferred from the codebase architecture (post-query formula evaluation, the #3821 backstop, the summary/rollup copy-exclusion), not measured. Flagging for someone to verify before dispatch.
Why this is not simply "the same fix"
It's a different function and axis (assertSortFieldsExist, SORT, not assertSearchFieldsAreSearchable, SEARCH).
Its pinned test lives in a third package, packages/objectql/src/query-expression-conformance.test.ts:455 (.rejects.toThrow(/follows the relationship 'project_id'[\s\S]*formula or rollup/)), crossing into domain:engine-core territory (per the domain:metadata seat's own scope note: "ObjectQL 编译/查询执行、formula、core runtime 归 domain:engine-core").
Scope if promoted
Needs a decision first, not just a rewording: is "denormalise onto formula/rollup and sort by that" actually broken (verify with a real repro — plain non-dotted orderBy naming a formula-typed field, check whether it silently drops the sort or throws), and if so, what's the right prescription (a stored/mirrored field, same as #6673's fix) — touching protocol.ts (assertSortFieldsExist), its pinned test in packages/objectql, and the still-current doc at query-syntax.mdx:533-534 together, so code and docs move in the same PR this time.
Split out of #6673 while verifying its premise (comment: #6673 (comment)). Recorded, not claimed.
What #6673 actually found vs. what this is
#6673 fixed two
packages/linthints that told authors to mirror a related record's value onto a formula field forsearchableFields— a fix that can't work because aformulafield is virtual (no driver materializes a column for it) and CEL only reads the record's own fields.While re-verifying #6673's third named target (
protocol.ts:4780, claimed to be insideassertSearchFieldsAreSearchable), I found that text actually lives in a different function:assertSortFieldsExist(packages/metadata-protocol/src/protocol.ts:4745), guarding the SORT axis (#4226/#4256), notsearchableFields/#4254at all.The text, and why it may be the same defect
protocol.ts:4780(inassertSortFieldsExist, for a dotted-pathorderBylike?sort=account.company_name):This claims a
formula/rollup(summary) field "copies it into a real column". By the same argument #6673 already established forformula: it's virtual, no driver materializes a column for it (packages/objectql/src/engine.ts:568-573computes it post-query, in-memory;driver-sql/src/schema-drift.ts;driver-turso/src/remote-transport.ts).summary/rollupfields are likewise excluded from real-column treatment elsewhere in this same file (the clone copy-exclusion atprotocol.ts:5941, "computed formula/summary fields"). SoORDER BY <formula-or-rollup-field>looks structurally like it should hit the exact same silent-degradation path#3821's backstop already covers for other unknown-column ORDER BYs: query succeeds, rows are all there, order is arbitrary — the very failure mode#4226/#4256exist to stop.Not independently reproduced — I didn't run a live repro (formula field named directly, non-dotted, in
orderBy) proving the driver silently drops the sort; this is inferred from the codebase architecture (post-query formula evaluation, the#3821backstop, thesummary/rollupcopy-exclusion), not measured. Flagging for someone to verify before dispatch.Why this is not simply "the same fix"
assertSortFieldsExist, SORT, notassertSearchFieldsAreSearchable, SEARCH).#4256(same filer as The searchable-fields hints prescribe a "text/formula" mirror — the formula half never works, so the tool output now contradicts the docs that quote it #6673,os-zhuang, closedcompleted) explicitly proposed and got this exact wording as its chosen remedy for dotted-path sort.content/docs/protocol/objectql/query-syntax.mdx:533-534, the "Sorting on Related Fields" callout) still says the same thing today — code and docs currently agree, unlike thesearchableFieldscase The searchable-fields hints prescribe a "text/formula" mirror — the formula half never works, so the tool output now contradicts the docs that quote it #6673 fixed where docs had already moved to "stored" and the tool hadn't. Fixing this without also revisiting that doc would just move the contradiction rather than remove it.packages/objectql/src/query-expression-conformance.test.ts:455(.rejects.toThrow(/follows the relationship 'project_id'[\s\S]*formula or rollup/)), crossing intodomain:engine-coreterritory (per thedomain:metadataseat's own scope note: "ObjectQL 编译/查询执行、formula、core runtime 归 domain:engine-core").Scope if promoted
Needs a decision first, not just a rewording: is "denormalise onto formula/rollup and sort by that" actually broken (verify with a real repro — plain non-dotted
orderBynaming aformula-typed field, check whether it silently drops the sort or throws), and if so, what's the right prescription (a stored/mirrored field, same as #6673's fix) — touchingprotocol.ts(assertSortFieldsExist), its pinned test inpackages/objectql, and the still-current doc atquery-syntax.mdx:533-534together, so code and docs move in the same PR this time.Refs: #6673, #4256 (the SORT-axis dotted-path decision, closed), #4226, #3821.