Phixsura commented on PR #38698:
URL: https://github.com/apache/shardingsphere/pull/38698#issuecomment-4605595388

   Pushed `fc325eed` on top of current master.
   
   For the `char` / `character` no-typmod cell (P1.A): `castToText` now splits 
the TEXT family into three sub-targets. `text` / `varchar` / `bpchar` keep 
identity, naked `char` / `character` truncate to the first Unicode codepoint 
via `String#offsetByCodePoints`, and `name` truncates to 63 UTF-8 bytes 
(preserving multi-byte boundaries). `'ab'::char` therefore routes by `'a'` and 
`repeat('中', 70)::name` routes by the 21-char prefix (63 bytes). 
Counterexamples in INSERT and WHERE production paths.
   
   For the Java `Float` / `Double` to integer cell (P1.B): the evaluator was 
rebuilt around an explicit (source category, target category) dispatch instead 
of the previous `toBigDecimal`-flattened single path. Java `BigDecimal` / 
`BigInteger` route through `numeric_int4` (PostgreSQL's `numeric.c`, 
round-away-from-zero, Java `HALF_UP`), while Java `Float` / `Double` route 
through `dtoi4` / `ftoi4` (PostgreSQL's `float.c`, `rint()`, Java `Math#rint` = 
HALF_EVEN). `2.5::numeric::int4` returns `3`, `2.5::float8::int4` returns `2`, 
matching PostgreSQL 16.
   
   While restructuring the matrix I cross-checked the rest of `pg_cast` against 
PostgreSQL 16 via `postgres:16-alpine` for the full set of (source, target) 
cells and added counterexamples that PG itself rejects: `bool::numeric`, 
`numeric::bool`, `float8::bool`, `'1.5'::int4`, `'1.0'::int4`, `'1e0'::int4` 
all return empty. `Boolean::text` correctly emits `"true"`/`"false"` for `text` 
/ `varchar` / `bpchar` and `"t"`/`"f"` for `name` (the latter via PG's 
`boolout` path). `Float`/`Double` to `numeric` strips trailing zeros and rounds 
to 15 significant digits to match PostgreSQL's `%.15g` formatting.
   
   openGauss verification: rather than spinning up a container I 
cross-referenced `pg_cast.h` from `opengauss-mirror/openGauss-server`. The 
integer / float / numeric / bpchar / namein cast function OIDs (`1740` / `317` 
/ `319` / `3192` / `19`) match PostgreSQL byte-for-byte. The one substantive 
divergence is that openGauss adds `bool ↔ numeric` cast functions `6433` / 
`6434` that PostgreSQL does not have; the evaluator deliberately stays aligned 
with PostgreSQL and rejects those, which on openGauss is a conservative 
narrowing (broadcast instead of routing by 0 / 1). This is documented inline on 
the class and pinned by two explicit unit tests.
   
   Scope check on the broadened routing surface: `PostgreSQLCastEvaluator` is 
only reachable through `ConditionValue` (WHERE / IN / BETWEEN / UPDATE / 
DELETE) and `InsertClauseShardingConditionEngine` (INSERT VALUES). 
`TypeCastExpression` itself is only emitted by the PostgreSQL and openGauss 
statement visitors; MySQL / Oracle / SQL Server `CAST(...)` syntax becomes a 
`FunctionSegment` and bypasses this evaluator entirely, so the broadened cast 
handling cannot leak into other dialects.
   
   E2E: 4 additional `e2e-dml-insert.xml` cases drive the new cells through 
actual PostgreSQL and openGauss containers — `?::int4` with `2.5:double` and 
`2.5:float` (routes shard 2 via `Float`/`Double` HALF_EVEN), 
`2.5::numeric::int4` (routes shard 3 via numeric HALF_UP), `2.5::float8::int4` 
(routes shard 2). All reuse existing `insert_for_order_2.xml` / 
`insert_for_order_3.xml`. Both PG and openGauss must agree that the casted row 
lands in the expected shard for the assertion to pass.
   
   `./mvnw test -pl features/sharding/core` is 1014/1014 (+93 new); spotless 
and checkstyle clean.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to