Summary
impl ToSqlParam for Numeric (added in #65) only supports scale = 0
(whole numbers). Scaled decimals (scale > 0) are rejected because Hyper
cannot read PG-binary NUMERIC parameters that require scale reconciliation.
This issue tracks lifting that limitation.
Background — why scaled Numeric params don't work today
query_params sends all parameters over the PostgreSQL extended-query
binary bind path (format code 1, hardcoded in
connection.rs:517-519).
For NUMERIC, the binary form is the PostgreSQL nbase-10000 packed-digit
wire format.
Empirically (probed against hyperd 0.0.25080):
| Param |
Result |
Numeric scale 0 (e.g. 42) |
✅ accepted |
Numeric scale > 0 (e.g. 12345.6700) |
❌ ERROR: Hyper cannot handle truncation when reading numerics. (0A000) |
same, with explicit CAST($1 AS numeric(38,4)) |
❌ same error |
The error is SQLSTATE 0A000 (feature_not_supported) and fires
regardless of the encoded dscale/weight or an explicit target type —
so it's a Hyper server limitation on reading binary NUMERIC params,
not a client-side encoding bug.
To avoid shipping something that looks supported but breaks on real
decimal data, #65 made Numeric::encode_param return an error (or the
impl rejects) when scale() > 0, failing fast with a clear message
instead of the cryptic server error.
Possible paths to full support
- Text-format bind for Numeric. Allow per-parameter format codes so
a Numeric param can travel as text (format code 0) instead of
binary. Hyper parses '12345.6700'::numeric fine from text. This
requires plumbing per-parameter format codes through
start_execute_prepared / frontend::bind (currently
param_formats is a uniform vec![1; n]). This is the most likely
fix and is self-contained to the core client.
- Upstream Hyper fix. If/when hyperd learns to read scaled binary
NUMERIC params, the existing binary encoder can be extended to emit
the full nbase-10000 format and the scale guard removed.
- Hybrid. Keep binary for scale=0 (fast path) and fall back to text
for scale>0.
Recommended: option 1 (per-parameter text format), since it also unlocks
clean text binding for any future type Hyper can't read in binary.
Acceptance criteria
Related
Summary
impl ToSqlParam for Numeric(added in #65) only supports scale = 0(whole numbers). Scaled decimals (scale > 0) are rejected because Hyper
cannot read PG-binary NUMERIC parameters that require scale reconciliation.
This issue tracks lifting that limitation.
Background — why scaled Numeric params don't work today
query_paramssends all parameters over the PostgreSQL extended-querybinary bind path (format code
1, hardcoded inconnection.rs:517-519).For NUMERIC, the binary form is the PostgreSQL nbase-10000 packed-digit
wire format.
Empirically (probed against hyperd 0.0.25080):
Numericscale 0 (e.g.42)Numericscale > 0 (e.g.12345.6700)ERROR: Hyper cannot handle truncation when reading numerics. (0A000)CAST($1 AS numeric(38,4))The error is SQLSTATE
0A000(feature_not_supported) and firesregardless of the encoded
dscale/weightor an explicit target type —so it's a Hyper server limitation on reading binary NUMERIC params,
not a client-side encoding bug.
To avoid shipping something that looks supported but breaks on real
decimal data, #65 made
Numeric::encode_paramreturn an error (or theimpl rejects) when
scale() > 0, failing fast with a clear messageinstead of the cryptic server error.
Possible paths to full support
a
Numericparam can travel as text (format code0) instead ofbinary. Hyper parses
'12345.6700'::numericfine from text. Thisrequires plumbing per-parameter format codes through
start_execute_prepared/frontend::bind(currentlyparam_formatsis a uniformvec![1; n]). This is the most likelyfix and is self-contained to the core client.
NUMERIC params, the existing binary encoder can be extended to emit
the full nbase-10000 format and the scale guard removed.
for scale>0.
Recommended: option 1 (per-parameter text format), since it also unlocks
clean text binding for any future type Hyper can't read in binary.
Acceptance criteria
Numericwith scale > 0 can be bound viaquery_paramsandround-trips correctly (e.g.
12345.6700in →12345.6700out).Related
scale>0 guard this issue removes.