Skip to content

A min/max over a text / select / lookup field is still described as type: "number" in the analytics response #16098

Description

@os-warren

Filed unassigned by the os-dev seat working #15768 (session https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y). Not graded, no domain:* — routing and priority are the triage seat's. This is the sibling population of that card, deliberately left out of its PR rather than absorbed.

The rule, and the half that landed

min and max return a value of the aggregated field's own type. #15768's services half implements exactly that for the TEMPORAL family: a min/max over a date / datetime / time field is now described as time in AnalyticsResult.fields[].type instead of number (measureResultType in packages/services/service-analytics/src/measure-result-type.ts, applied in queryDataset's ADR-0021 enrichment).

The rule is not temporal-specific. The same aggregate over a string-valued column also returns a string:

  • min / max over a text / textarea / email / url field
  • min / max over a select / radio field (the stored option value)
  • min / max over a lookup / user field (the stored id)

Every one of those columns is still described as type: "number" today. That is the same defect the card records — column metadata contradicting the value beside it — over a different set of field types.

Why it was scoped out rather than folded in

Two reasons, both stated in #15768's PR:

  1. The card and its triage ruled on the temporal population. The measured evidence is a min over a Field.datetime, and the triage seat's ruling is about that response. Widening the fix's behavioural surface past the population that was measured is a scope decision, not the card's.
  2. Some members of the wider population have a genuinely uncertain answer, and one guess would ship as a declaration. min over an autonumber depends on whether the value is stored as an integer or a formatted string; min/max over a boolean has no min at all on Postgres (see the closed driver-sql (PG): sum/avg/min/max over a boolean column throw the raw PostgreSQL 42883 with no ADR-0112 envelope (status undefined) #11455) while SQLite answers 0/1; formula and summary resolve to whatever they compute. A correction table covering those would be inventing answers, which is precisely what A dataset measure over a datetime is typed number in the analytics response, and a metric tile ignores the format style it is handed — measured on 17.3.0 #15768's dispatch ruled against.

So the honest shape is: land the population that is certain, and file this one so the uncertain members get decided rather than guessed.

What deciding it needs

An enumerated verdict per FieldType member for min/max — the same treatment AggregationFunction got in #15768 — pinned by a test that walks the enum so a new field type cannot fall through silently. measureResultType already has the shape for it: it answers undefined for "no correction", so widening it is adding rows to one table, not a second mechanism.

Note the wire vocabulary for this position is DimensionType (string / number / boolean / time / geo), not FieldType — a text-valued measure column would be string, the same word a string dimension column already carries.

Related

#15768 (the temporal half, where this rule and its one home were introduced) · #11455 (the driver-level envelope for sum/avg/min/max over a boolean column, closed).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions