033. Specialize exact mixed-numeric literal thresholds
- Status: Applied
- Date: 2026-10-14
Problem and mechanism
A direct comparison between a native Int or Float column and an opposite-kind numeric literal could use the general mixed Int/Float comparison kernel. The translator now derives an exact direct threshold for eligible pure filter comparisons, without rounding the values being compared:
- For an Int column and a Float literal, Build uses the exact represented
Float value to derive an integer boundary. For example,
i>18.5becomesi>=19;i=18.5is false for every non-null Int, andi!=18.5becomes a non-null test. - For a Float column and an Int literal exactly representable as Float, the
direct Float predicate uses that Float parameter. For an Int that is not
exactly representable, Build uses the neighboring Float boundary that
preserves comparison against the original exact Int. For example,
f>9007199254740993becomesf>=9007199254740994.
The rewrite covers all six comparisons. Nullable-column checks preserve the
existing filter and NOT behavior; only parameters needed by the surviving
thresholds remain, in source order. Existing same-Float comparisons remain on
their direct path. Guarded, dynamic, JSON, and value-context comparisons use
the general lowering. The column must be on the left; permitted literal-left
comparisons inside value expressions retain general lowering. Eligible
identity-derived column expressions use the existing direct path.
Integer-spelled closed number()
conversions may fold to an Int literal; Float-looking text remains on
PostgreSQL's native input path. Conversion failure and NUL checks are
unchanged.
Applicability
| Comparison | Status | Reason |
|---|---|---|
| Native Int column and Float literal in a pure filter comparison | Applied | Derive exact integer thresholds from the represented Float value. |
| Native Float column and Int literal in a pure filter comparison | Applied | Use a direct Float parameter when exact; otherwise use adjacent Float bounds. |
| Same-kind native Float column and Float literal | Already direct | Preserve the existing direct Float predicate path. |
| Guarded, dynamic, JSON, or value-context operands | Not applied | Retain the general lowering and its presence and representation handling. |
Float-looking string conversion to number() |
Not applied | PostgreSQL's native Float input and conversion-failure checks remain in force. |
Reproduction
The baseline is commit
4f32b2e.
The candidate implementation accompanies this record. The temporary shape
fixture used Go 1.27.1 and PostgreSQL 18.6 on aarch64 with
extra_float_digits=1. The bindings were nullable native bigint field i
and nullable native double precision field f. The queries
included both column/literal numeric-type combinations, their compositions
with AND, OR, and NOT, and same-kind Float and Int controls.
The integration suite used 14 Int inputs, 22 Float inputs, 14 Float literals, and
9 Int literals across the six comparisons. It included raw literals and
integer-spelled number() conversions, guards, null inputs, and 14 additional
contexts covering logical composition, identity casts, and fallback paths.
The exact threshold unit matrix contains 3,192 rational comparison
cases. The PostgreSQL/local integration suite passed 22,808 results on both
baseline and candidate at extra_float_digits=1 and 3.
Durable fixtures are the exact rational comparison unit tests,
eligibility and parameter tests,
and PostgreSQL parity tests.
The 17-case SQL-shape generator and raw SQL/plans were temporary files outside
the repository. The shape measurements count generated WHERE bytes and
OFFSET 0 barriers; they are not benchmark results.
The focused checks were:
GOTOOLCHAIN=go1.27.1 go test ./backends/sql -run '^(TestMixedLiteralThresholdsMatchExactRationalOrdering|TestMixedLiteralThresholdsRejectOtherOperations|TestDirectMixedLiteralThresholdParameters|TestMixedLiteralThresholdsKeepValueAndGuardFallback|TestMixedLiteralThresholdsPreserveJSONAndConversionChecks)$' -count=1
HFF_POSTGRES_CONTAINER=<container> GOTOOLCHAIN=go1.27.1 go test -tags=integration ./backends/sql -run '^TestPostgreSQLExactLiteralThresholdsMatchLocal$' -count=1
Results
| Filter | Baseline bytes / barriers | Candidate bytes / barriers | Bound parameter |
|---|---|---|---|
i>18.5 |
886 / 4 | 61 / 0 | Float 18.5 becomes Int 19 |
f>9007199254740993 |
806 / 4 | 71 / 0 | Int becomes Float 9007199254740994 |
i>18.5 f>9007199254740993 |
1,788 / 9 | 139 / 0 | Both thresholds, in source order |
i=18.5 |
886 / 4 | 5 / 0 | Constant false; no parameter |
i!=18.5 |
887 / 4 | 27 / 0 | Non-null predicate; no parameter |
| Same-kind, guarded, value-context, and dynamic controls | unchanged | unchanged | Existing path |
With default planner settings, plain EXPLAIN (COSTS OFF) on the empty shape
fixture changed Nested Loop/Result counts from 3/4 to 0/0 for i>18.5
and from 8/9 to 0/0 for the combined filter. These are plan-shape observations
only.
A separate indexed fixture used SET enable_seqscan=off as a diagnostic
to inspect candidate index conditions. The Int threshold exposed
i IS NOT NULL AND i >= 19; the large-Int Float threshold exposed
f IS NOT NULL AND f >= 9007199254740994. The baseline plans had
Bitmap Index Scans without those index conditions. This forced-plan fixture
shows predicate eligibility, not default planner choice, execution cost, or
speed. No EXPLAIN ANALYZE or timing benchmark was run.
Correctness and tradeoffs
The 22,808 PostgreSQL/local results passed on both the pinned baseline and
candidate. The matrix covers all six operators, Int64 and Float64 boundaries,
fractional thresholds, signed zero, nullable columns, NOT, guards, source
parameter order, and fallback contexts. Unit tests also cover subtype and
parameter selection, retained JSON lowering, NUL and conversion checks, and direct
Float behavior. Full repository tests, go vet, integration-tagged vet, SQL
race checks, and independent review passed.
The SQL is shorter for eligible literal comparisons, but this does not establish lower execution time. The indexed fixture required disabling sequential scans and is not evidence of index selection under ordinary planner settings.
Decision and limits
Use exact Build-time thresholds only for eligible direct filter comparisons between a native Int/Float column and a typed numeric literal. Preserve the general mixed comparison for guarded, dynamic, JSON, and value-context expressions. The implementation does not change HFF numeric semantics or Float literal parsing.