Skip to content

NULL-aware after() #394

Description

@0x054

Parent

Part of #372 (ADR-0018).

What to build

after() understands nullable order keys and empty position slots. Crossing from a non-NULL leading key into the NULL bucket (the pinned-first conversation list) is one query. None is legal in every non-PK slot; the PK slot still cannot be empty. Column nullability is not consulted — a left_join'd NOT NULL related column may still be NULL when the relation is missing.

Lifts the nullable-order-key refusal from #393.

Acceptance criteria

  • after((None, id)) continues through the NULL bucket of a leading nullable key (nulls="last" DESC — the Pinch shape).
  • after on a non-NULL position includes the later NULL-bucket rows when null placement puts NULLs after the cursor.
  • None in a non-PK slot is legal; None in the PK slot is a build-time error.
  • left_join + None for a NOT NULL related column is a legal position (when traversal is in scope this is tested there; the expansion must already allow it).
  • One expansion function renders the IS NULL tree from each order key's direction and null placement. Both dialects consume it. native resolves at render, not in Python.
  • Backend-matrix result sets pin the bucket crossing. Rust unit tests pin the expansion combinatorics (direction × placement × after × NULL).

Blocked by

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions