github-actions[bot] commented on code in PR #69987:
URL: https://github.com/apache/doris/pull/69987#discussion_r4441065272
##########
fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/JdbcQueryBuilder.java:
##########
@@ -840,10 +853,9 @@ private String literalToSql(ConnectorLiteral lit) {
return formatBooleanLiteral((Boolean) val);
} else if (val instanceof Double) {
double d = (Double) val;
- if (d == Math.floor(d) && !Double.isInfinite(d)) {
- return Long.toString((long) d);
- }
- return val.toString();
+ // Narrowing integral-looking doubles to long corrupts values
outside the long range.
+ // Non-finite literals have no portable SQL spelling; evaluate
their predicates locally.
+ return Double.isFinite(d) ? Double.toString(d) : null;
Review Comment:
[P1] Preserve exact integer spelling for in-range doubles
With default JDBC CAST pushdown, a PostgreSQL BIGINT row
`id=9223372036854774784` matches `CAST(id AS DOUBLE) =
CAST('9223372036854774784' AS DOUBLE)`. The converter strips the column CAST,
and this line now emits `"id" = 9.2233720368547748E18`. PostgreSQL treats the
exponent literal as exact NUMERIC value `9223372036854774800` and compares the
BIGINT exactly, so it discards the matching row before Doris can evaluate its
residual. The previous long rendering emitted the actual integer
`9223372036854774784`. Preserve exact in-range integer text, use appropriate
typed floating SQL, or keep this predicate local; the new Java
`Double.parseDouble` round-trip test cannot catch this. See PostgreSQL's
[numeric constant
typing](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-NUMERIC)
and [operator
resolution](https://www.postgresql.org/docs/current/typeconv-oper.html).
##########
fe/fe-connector/fe-connector-jdbc/src/main/java/org/apache/doris/connector/jdbc/JdbcQueryBuilder.java:
##########
@@ -840,10 +853,9 @@ private String literalToSql(ConnectorLiteral lit) {
return formatBooleanLiteral((Boolean) val);
} else if (val instanceof Double) {
double d = (Double) val;
- if (d == Math.floor(d) && !Double.isInfinite(d)) {
- return Long.toString((long) d);
- }
- return val.toString();
+ // Narrowing integral-looking doubles to long corrupts values
outside the long range.
+ // Non-finite literals have no portable SQL spelling; evaluate
their predicates locally.
+ return Double.isFinite(d) ? Double.toString(d) : null;
Review Comment:
[P2] Use Oracle floating literal syntax for large finite doubles
Oracle `BINARY_DOUBLE` columns map to Doris DOUBLE, but finiteness does not
guarantee that this untyped spelling is valid remote SQL. For example, `d <
CAST('1e200' AS DOUBLE)` now becomes `"d" < 1.0E200`. Oracle interprets
unsuffixed literals as NUMBER, whose range excludes `1e200`, so the scan fails
even for a matching `d=0` row; that case previously succeeded with the bounded
long spelling. Render a BINARY_DOUBLE literal using the `D` suffix (or
equivalent lossless conversion), or return null so the predicate stays local.
Oracle's [numeric literal
rules](https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Literals.html)
specify the default NUMBER type, binary-double suffix and out-of-range error.
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]