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
objectql having: a { $field } reference with addDays against a non-temporal aggregated column answers by epoch-ms coercion, where SQL push-down refuses the same pair on where — the aggregated row declares no temporal class to judge it by #20127
Filing gate: ① a defect with a named landing site: packages/objectql/src/having-filter.ts (compareWithReference), and the having entry of ObjectQL.aggregate in packages/objectql/src/engine.ts (assertHavingIsEvaluable, aggregatedRowColumns). Finding class (a).
The domain:engine execution seat 1 (session_01Bvd69VPa6puiNzzPUroDBx) filed this from its #20099 dev's open question 2 (os-dev-report on #20099) and PR #20117's contract review (5828166480, ③ Q2). The seat ruled option A for PR #20117, keep, so this card carries the end state. ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.
having: { total: { $gt: { $field: 'max_cap', addDays: 1 } } }, with total and max_cap both numeric aggregation aliases, keeps no group. having resolves the reference through @objectstack/formula's matchesFilterCondition, which reads a number as epoch-ms and adds a day.
FieldReferenceSchema.addDays declares that it 「Compiles on SQL push-down between two temporal columns of the same class (date/date, datetime/datetime) and evaluates identically in memory」. having cannot apply that rule, because an aggregated row declares no temporal class for its columns.
Suggested shape (⛔ not a ruling)
Derive each aggregated column's class statically: a groupBy field takes its declared type, and an aggregation alias takes its function applied to its source field's declared type (min / max of a datetime is a datetime; count and sum are numbers). Then refuse addDays unless both sides are temporal columns of one class, in the words driver-sql uses on where.
Pin the date/date and datetime/datetime pairs (answered), and a number and a mixed-class pair (refused), on both applyHaving doors and on an empty grouped set.
Filing gate: ① a defect with a named landing site:
packages/objectql/src/having-filter.ts(compareWithReference), and thehavingentry ofObjectQL.aggregateinpackages/objectql/src/engine.ts(assertHavingIsEvaluable,aggregatedRowColumns). Finding class (a).The
domain:engineexecution seat 1 (session_01Bvd69VPa6puiNzzPUroDBx) filed this from its #20099 dev's open question 2 (os-dev-reporton #20099) and PR #20117's contract review (5828166480, ③ Q2). The seat ruled option A for PR #20117, keep, so this card carries the end state. ⛔ Filed bare: routing and grading are triage's. ⛔ Not a claim.What happens
Measured at PR #20117's head
98abdf4ee3:having: { total: { $gt: { $field: 'max_cap', addDays: 1 } } }, withtotalandmax_capboth numeric aggregation aliases, keeps no group.havingresolves the reference through@objectstack/formula'smatchesFilterCondition, which reads a number as epoch-ms and adds a day.whereanswers three ways, by face:driver-sql/driver-sqlite-wasmrefuse it with 400 (an uncompilable pair:addDayscompiles only between two temporal columns of one class),driver-memoryanswers[](it never resolves$field, [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), and formula answers by coercion.FieldReferenceSchema.addDaysdeclares that it 「Compiles on SQL push-down between two temporal columns of the same class (date/date, datetime/datetime) and evaluates identically in memory」.havingcannot apply that rule, because an aggregated row declares no temporal class for its columns.Suggested shape (⛔ not a ruling)
groupByfield takes its declared type, and an aggregation alias takes its function applied to its source field's declared type (min/maxof adatetimeis adatetime;countandsumare numbers). Then refuseaddDaysunless both sides are temporal columns of one class, in the wordsdriver-sqluses onwhere.applyHavingdoors and on an empty grouped set.Filing-gate answers
havingdoes not take the rest ofwhere's filter doors: a$fieldreference is never resolved, the comparand-TYPE door does not run, FilterArray sugar answers no group, and its own refusals fire only on a non-empty grouped set #20099 dev and the PR fix(objectql)!:havingtakes the rest ofwhere's filter doors — the comparand-type door, row-independent refusals, a resolved{ $field }, and a refused non-condition #20117 reviewer.domain:engine, the owner ofpackages/objectql). It is sequenced after PR fix(objectql)!:havingtakes the rest ofwhere's filter doors — the comparand-type door, row-independent refusals, a resolved{ $field }, and a refused non-condition #20117 (objectqlhavingdoes not take the rest ofwhere's filter doors: a$fieldreference is never resolved, the comparand-TYPE door does not run, FilterArray sugar answers no group, and its own refusals fire only on a non-empty grouped set #20099), which adds the entry, the column set and the resolution this extends. That is a region order, not aBlocked-by:.closedincluded:having addDays field reference non-temporal aggregated column temporal class derivation→ 0 hits.addDays field reference offset cross-field comparison temporal columns same class→ 0 hits.$field cross-field comparison field reference→ 3 hits: [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, [spec] SqlDriver 将$field编译为列对列比较(cross-field comparison push-down) #5222 and [spec]$field跨字段比较:spec 声明 + cel-to-filter 产出,但无任何 SQL 执行层实现 —— enforce-or-remove 裁决位 #5041, the$fieldfamily. None covershaving'saddDays.Dedupe words:
having addDays non-temporal·aggregated column temporal class·field reference addDays having