Skip to content

Read drivine4j's Postgres stand-ins for NaN and the infinities where a compiled statement says it holds them - #464

Merged
jasperblues merged 1 commit into
mainfrom
port-459-pg-nonfinite
Nov 8, 2026
Merged

jasperblues merged 1 commit into
mainfrom
port-459-pg-nonfinite

Conversation

@jasperblues

Copy link
Copy Markdown
Member

Closes #459. Port of liberation-data/drivine#673 part 2 (TS liberation-data/drivine#676).

Nothing changes under Python's own compiler. Python's compilers set the new flag False on every statement, and the goldens are unchanged. So this can land before Python switches to the shared compiler.

What changes

  • The flag. CompiledCypher gets non_finite: bool = False. None of Python's three compilers sets it.
  • Postgres reading (query and open_cursor, async and sync). Where non_finite is set, the statement's cursor reads json and jsonb, text and binary, with loaders registered on that cursor alone (psycopg.types.json.set_json_loads(..., cursor)).
    • Numbers are read exactly as drivine4j's PostgresCypherCompiler.read reads them:
      • exactly 2e309 + 0.5 is NaN;
      • at or past 1e309 is +inf;
      • at or past -1e309 is -inf;
      • every other number is read as json.loads reads it.
    • The comparison uses the exact decimal (the new module postgres_non_finite.py).
  • No rows field. Python already reads drivine4j's Oracle shape, one row per Cypher row, and has no one-row shape to tell apart.

Tests

  • Unit:
    • the stand-ins and other spellings of them;
    • near misses (2e309, 1e308, 1e400, .4/.6, an exponent past Decimal's range);
    • json.loads parity for every other number;
    • nesting, and a string that holds the stand-in's text;
    • the loaders staying on their cursor;
    • the flag False from every compiler on every store;
    • the flag carried through both connections, async and sync.
  • Integration (Postgres, async and sync):
    • to_jsonb(2e309 + 0.5) and ±(1e309 + 0.5) read as NaN/±inf with the flag on, through query and open_cursor, with and without a prelude;
    • with the flag off, they read as today;
    • the next statement on the connection is unaffected.

Verified

  • 3 review passes. Pass 1 fixed an exponent past Decimal's range raising; passes 2 and 3 were clean.
  • ruff, ruff format, pyright and the unasync check are clean.
  • The full suite with Oracle and Postgres passes.

…a compiled statement says it holds them (#459)

CompiledCypher gets non_finite, False from Python's own compilers, so every
statement reads as before. Where it is set, the statement's cursor reads
json and jsonb with loaders of its own that map drivine4j's stand-ins by
their exact decimal value, as PostgresCypherCompiler.read does: exactly
2e309 + 0.5 is NaN, at or past 1e309 +inf, at or past -1e309 -inf. Every
other number reads as json.loads reads it. Nothing is registered on the
connection or the process. The shared compiler's answers will say it.

Port of liberation-data/drivine#673 part 2 (liberation-data/drivine#676).
@jasperblues
jasperblues merged commit 606ebfd into main Nov 8, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Port of liberation-data/drivine#673 (part 2): read drivine4j's Postgres stand-ins for NaN and the infinities where a statement is nonFinite

1 participant