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
{{ message }}
Repository navigation
objectql having and the per-aggregation filter judge a cross-field reference's comparison class only on an addDays pair, so a plain datetime-vs-date { $field } answers by formula's whole-day reading where the where twin refuses it 400 #21255
Filing gate: ① a defect with a named landing site, finding class (b): a declared rule the face does not enforce. Landing site: packages/objectql/src/having-filter.ts, the class rule in assertConditionIsEvaluable (gated on target.addDays, near :1425 at origin/main4b59a381a) and in assertAggregationFilterReferencesAreDeclared (gated on offset !== undefined).
reach:measured at the engine door that REST POST /api/v1/data/:object/query calls (engine.aggregate, from protocol.ts near :11728), on SqlDriver over better-sqlite3 at 4b59a381a, as a member. It was measured by #21242's dev (os-dev-report on #21242, open_questions[0] and out_of_scope_findings[0]); the HTTP door itself was not driven. No in-repo producer: examples/** at 4b59a381a carries 0 having and 0 { $field }.
Filed by domain:engine#1 (seat post #6367, session_017xfMoEjKUuSh2xYB8sCozp) as the precondition of #21242. Reader who acts: triage grades and routes; packages/objectql is this lane's. ⛔ Not a claim.
What happens
The contract.packages/spec/src/data/filter-cross-field-comparison-class.ts (CROSS_FIELD_COMPARISON_CLASSES) says: "The six comparison classes. Two columns are comparable only within one of them." date and datetime are separate classes.
where applies the class rule to every { $field } comparison, so a datetime column against a date column answers INVALID_FILTER / 400.
having and aggregations[i].filter apply it only when the reference carries addDays. A plain { $field } reference across classes is never judged. It reaches formula's matchesFilterCondition, which answers by lteBound's whole-day reading of the bare-day referent.
Measured:
aggregations: [{ filter: { closed_at: { $lte: { $field: 'due_on' } } } }], with closed_at a datetime and due_on a date, counts 3. The where twin answers 400.
having on max(closed_at)$lte a { $field } day bucket keeps 2 groups.
having and the per-aggregation filter apply the class rule to every { $field } comparison, as where does, with where's envelope and words. An addDays pair keeps its current judgement.
Clause-②: no (narrowing): a cross-class plain reference that answered becomes a 400.
Pins:
the two measured queries refuse 400, matching their where twins;
a same-class plain reference (date against date, datetime against datetime) answers as before (the control);
the addDays pairs are unchanged.
Dedupe
mcp__github__search_issues, repo-scoped, open and closed:
None covers a plain cross-class { $field } at these two positions. This is the family's next member, not a duplicate.
Dedupe words: having cross-class field reference · aggregation filter plain $field class rule · having datetime date field comparison · lteBound caller having
Filing gate: ① a defect with a named landing site, finding class (b): a declared rule the face does not enforce. Landing site:
packages/objectql/src/having-filter.ts, the class rule inassertConditionIsEvaluable(gated ontarget.addDays, near:1425atorigin/main4b59a381a) and inassertAggregationFilterReferencesAreDeclared(gated onoffset !== undefined).reach:measured at the engine door that RESTPOST /api/v1/data/:object/querycalls (engine.aggregate, fromprotocol.tsnear:11728), onSqlDriverover better-sqlite3 at4b59a381a, as a member. It was measured by #21242's dev (os-dev-report on #21242,open_questions[0]andout_of_scope_findings[0]); the HTTP door itself was not driven. No in-repo producer:examples/**at4b59a381acarries 0havingand 0{ $field }.Filed by
domain:engine#1(seat post #6367,session_017xfMoEjKUuSh2xYB8sCozp) as the precondition of #21242. Reader who acts: triage grades and routes;packages/objectqlis this lane's. ⛔ Not a claim.What happens
packages/spec/src/data/filter-cross-field-comparison-class.ts(CROSS_FIELD_COMPARISON_CLASSES) says: "The six comparison classes. Two columns are comparable only within one of them."dateanddatetimeare separate classes.whereapplies the class rule to every{ $field }comparison, so adatetimecolumn against adatecolumn answersINVALID_FILTER/ 400.havingandaggregations[i].filterapply it only when the reference carriesaddDays. A plain{ $field }reference across classes is never judged. It reachesformula'smatchesFilterCondition, which answers bylteBound's whole-day reading of the bare-day referent.aggregations: [{ filter: { closed_at: { $lte: { $field: 'due_on' } } } }], withclosed_atadatetimeanddue_onadate, counts 3. Thewheretwin answers 400.havingonmax(closed_at)$ltea{ $field }day bucket keeps 2 groups.lteBound. WithlteBoundgone, the same two queries answer 1 and 0 groups, silently. That is the midnight-anchored shape dashboard 的日期区间上界打在datetime列上丢失当天数据 —— 默认配置即命中 #3777 removed. So this face is a production caller that still depends on the copy, and formula: retire F7's whole-day copy (lteBound in matches-filter.ts) now that the RLS write check judges the stored form (#21109, PR #21235); its direct-call cases move to the storage-form lowering #21242 stops until this face refuses aswheredoes.Scope for whoever takes it (⛔ not a ruling)
havingand the per-aggregationfilterapply the class rule to every{ $field }comparison, aswheredoes, withwhere's envelope and words. AnaddDayspair keeps its current judgement.Clause-②: no (narrowing): a cross-class plain reference that answered becomes a 400.wheretwins;dateagainstdate,datetimeagainstdatetime) answers as before (the control);addDayspairs are unchanged.Dedupe
mcp__github__search_issues, repo-scoped, open and closed:filterstill lacks four ofwhere's doors — a bad date, anaddDaysnumeric pair, an undeclared{ $field }and an unknown key answer200with every count 0 #20148 (the per-aggregation filter's four missing doors) and objectqlhaving: a{ $field }reference withaddDaysagainst a non-temporal aggregated column answers by epoch-ms coercion, where SQL push-down refuses the same pair onwhere— the aggregated row declares no temporal class to judge it by #20127 (havingaddDaysagainst a non-temporal column).having: a{ $field }reference withaddDaysagainst a non-temporal aggregated column answers by epoch-ms coercion, where SQL push-down refuses the same pair onwhere— the aggregated row declares no temporal class to judge it by #20127 again, and [finding] driver-memory's own reference matcher has no$fieldarm — a cross-field comparand (bare or withaddDays) reaching it is presumably compared as a literal object rather than resolved or refused (grep reading, to be measured) #15104 (driver-memory's reference matcher).filterstill lacks four ofwhere's doors — a bad date, anaddDaysnumeric pair, an undeclared{ $field }and an unknown key answer200with every count 0 #20148, objectql + REST: a per-aggregationfilter(andhaving) compares a temporal comparand type-blind, not by the column's storage rule — an ISO instant on adatefield counts 1 where thewheretwin counts 3 #20176, objectql aggregate positions miss two ofwhere's behaviours:havingresolves no{placeholder}({ $gte: "{not_a_token}" }answers 200 wherewhereanswers 400), and the per-aggregationfiltertemporal refusal names its pathwhere.…#20334, [finding] a per-aggregationfilter$ninon a multi-valued field counts the rows it was asked to exclude, and$incounts none, where the samewhereis refused 400: the aggregation evaluator has no JSON-column equality gate #21007 and [finding] a per-aggregationfilterwith$containson a multiple lookup counts 0 on every driver while the samewherefinds the rows: the engine's aggregation evaluator never matches a stored array #20873.None covers a plain cross-class
{ $field }at these two positions. This is the family's next member, not a duplicate.Dedupe words:
having cross-class field reference·aggregation filter plain $field class rule·having datetime date field comparison·lteBound caller havingGenerated by Claude Code