Skip to content

SQL: lower DISTINCT ON with ordered first-row-per-group semantics #289

Open

Description

@zzylol

Context

Split from #111. Every other item in that mixed SQL-gap issue is resolved or deliberately rejected:

The only unresolved item is PostgreSQL-style DISTINCT ON:

SELECT DISTINCT ON (service)
       service, ts, latency
FROM metrics
ORDER BY service, ts DESC;

DISTINCT ON (keys) keeps the first row in each key group according to the query ordering. It is not equivalent to ordinary full-row DISTINCT, and its result is nondeterministic when the ordering does not fully select a row among peers.

Required semantics

  • Preserve the DISTINCT ON key expressions separately from ordinary DISTINCT columns.
  • Preserve the ordering that determines the selected row.
  • Define behavior when no ORDER BY is present or when its leading expressions do not match the DISTINCT ON expressions, matching the selected SQL dialect/DataFusion contract.
  • Do not lower it to a plain Dedup, because Dedup does not encode which ordered row survives.

Possible canonical representation

Prefer expressing it through existing relational operators if semantics remain lossless, for example a per-partition row-number/top-1 shape:

Window(row_number, partition_by = distinct_on_keys, order_by = query_order)
  -> Filter(row_number = 1)
  -> Project(original output)

If the existing canonical TopK/Limit representation can express this exactly, reuse that representation rather than adding a PostgreSQL-specific node. The chosen representation must retain deterministic tie/order semantics.

Scope

  • Lower DataFusion/PostgreSQL DISTINCT ON into lossless canonical pre-ASAP IR.
  • Preserve schema, nullability, ordering, and key identity.
  • Thread the shape through resolution, CSE, DAG export, and existing canonicalization.
  • Add positive and negative SQL lowering tests.

Acceptance criteria

  • A representative DISTINCT ON (service) ... ORDER BY service, ts DESC query lowers successfully.
  • Multiple keys and qualified columns lower correctly.
  • Ordinary SELECT DISTINCT behavior is unchanged.
  • The chosen row follows ordering semantics and is not modeled as unordered deduplication.
  • Invalid or unsupported ordering/dialect combinations return an explicit diagnostic.
  • Serialization/CSE and DAG export preserve the partition keys and ordering.

Related

Activity

  1. added
    enhancementNew feature or request
    sqlSQL front-end lowering (DataFusion → L2)
    irPre-ASAP or post-ASAP intermediate representation
    testingCorpus, regression, differential, or benchmark tests
    on Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestirPre-ASAP or post-ASAP intermediate representationsqlSQL front-end lowering (DataFusion → L2)testingCorpus, regression, differential, or benchmark tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions