terrymanu commented on issue #34972:
URL: 
https://github.com/apache/shardingsphere/issues/34972#issuecomment-3642247010

   ##  Understanding
     In openGauss 7.0 + psycopg, running select … order by %s::int limit %s via 
Proxy (extended query, prepare=False/binary=False) triggers 
java.lang.ClassCastException: java.lang.Short cannot be cast to 
java.lang.Integer. You’re checking whether Proxy mishandles int2
     parameters.
   
   ##  Root Cause
     For LIMIT/OFFSET params, PaginationContext#getValue assumes Integer/Long; 
when the client marks the param as int2 (OID 21), 
PostgreSQLInt2BinaryProtocolValue returns a Short, and the subsequent (int) obj 
cast throws CCE. The client usage is valid per PostgreSQL/
     OpenGauss protocol; the incompatibility is on Proxy’s side for small 
integer params.
   
   ##  Analysis
   
     - Protocol: PostgreSQL int2 binary encoding is a signed 2-byte integer 
(official doc: 
https://www.postgresql.org/docs/current/protocol-message-types.html). Switching 
to payload.readInt2() would read as unsigned, breaking negative smallints, so 
that isn’t a correct fix.
     - Current code: PaginationContext#getValue only handles Long/Integer and 
otherwise does (int) obj, so Short and other Number subtypes fail.
     - Trigger: Any binary-bound param declared as int2 (or other non-int4 
numeric) for LIMIT/ORDER BY becomes Short and hits the cast.
     - Workaround: Explicitly cast the placeholder to ::int4 or send params as 
text/INT4 to avoid the CCE temporarily; the server-side compatibility still 
needs a fix.
   
   ##  Conclusion
     This is a Proxy compatibility gap for small integer pagination params, not 
a misuse. A safer server-side fix is to accept any Number and widen it, while 
keeping PostgreSQLInt2BinaryProtocolValue using readShort() to preserve signed 
semantics. Example direction
     (illustrative):
   
   ```java
     // PaginationContext#getValue
     if (paginationValueSegment instanceof 
ParameterMarkerPaginationValueSegment) {
         Object obj = params == null || params.isEmpty() ? 0L : 
params.get(((ParameterMarkerPaginationValueSegment) 
paginationValueSegment).getParameterIndex());
         if (obj == null) {
             return null;
         }
         if (obj instanceof Number) {
             return ((Number) obj).longValue(); // unify Short/Integer/Long, 
etc.
         }
         throw new IllegalArgumentException("Unsupported pagination param type: 
" + obj.getClass());
     }
   ```
   
     We warmly welcome community contributors to submit a PR with this 
compatibility fix and add tests covering int2 pagination parameters—thanks!


-- 
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