fatmanverse opened a new issue, #12914:
URL: https://github.com/apache/seatunnel/issues/12914

   ### Search before asking
   
   - [x] I had searched in the issues and found no similar issues.
   
   ### What happened
   
   `numeric_special_value_as_null = true` (#12790, #12792) does not cover 
PostgreSQL `Infinity` and `-Infinity` once pgjdbc switches to the binary 
transfer protocol. The job still fails with:
   
   ```
   java.lang.IllegalArgumentException: invalid sign in "numeric" value
        at org.postgresql.util.ByteConverter.numeric(ByteConverter.java:163)
        at org.postgresql.jdbc.PgResultSet.getNumeric(PgResultSet.java:2683)
        at org.postgresql.jdbc.PgResultSet.getBigDecimal(PgResultSet.java:2658)
        at 
org.apache.seatunnel.connectors.seatunnel.jdbc.utils.JdbcFieldTypeUtils.getBigDecimal(JdbcFieldTypeUtils.java:110)
        at 
org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.psql.PostgresJdbcRowConverter.getDecimalValue(PostgresJdbcRowConverter.java:231)
   ```
   
   `JdbcFieldTypeUtils#getBigDecimal` only catches `SQLException` and 
`ClassCastException`. In binary mode the driver cannot decode the sign word of 
the infinities (`0xD000` / `0xF000`) and throws `IllegalArgumentException`, and 
`getString` on the same column fails the same way, so `isNumericSpecialValue` 
cannot identify the value either. `NaN` is not affected.
   
   This also happens with the default URL. pgjdbc uses binary results for 
server-prepared statements, and a statement is server-prepared after 
`prepareThreshold` (default 5) executions on one connection. A partitioned read 
runs the same split query on one connection, so from the 6th split on the rows 
come back in binary. In the repro below the job wrote 51 of 100 rows and failed.
   
   The existing e2e case 
`jdbc_postgres_source_and_sink_numeric_special_value_binary.conf` only sets 
`binaryTransfer=true`, which is already the driver default, so it runs in text 
mode and does not cover this.
   
   ### How to reproduce (verified on `dev` e2957d2, PostgreSQL 16, pgjdbc 
42.4.3)
   
   ```sql
   CREATE TABLE public.num_special_part (id INT PRIMARY KEY, n_free NUMERIC);
   INSERT INTO public.num_special_part SELECT n, n * 1.5 FROM 
generate_series(1, 100) AS n;
   UPDATE public.num_special_part SET n_free = 'Infinity' WHERE id = 52;
   ```
   
   ```hocon
   source {
     Jdbc {
       url = "jdbc:postgresql://127.0.0.1:5432/postgres"
       driver = "org.postgresql.Driver"
       username = "postgres"
       password = "..."
       table_path = "postgres.public.num_special_part"
       partition_column = "id"
       split.size = 4
       numeric_special_value_as_null = true
     }
   }
   ```
   
   The same failure happens on the first row with `?prepareThreshold=-1` in the 
URL, with both `table_path` and `query`.
   
   ### Expected behavior
   
   With `numeric_special_value_as_null = true`, `Infinity` and `-Infinity` are 
read as null in binary mode as they are in text mode.
   
   ### SeaTunnel Version
   
   dev (3.0.1-SNAPSHOT, e2957d2)
   
   ### Zeta or Flink or Spark Version
   
   Zeta
   
   ### Java or Scala Version
   
   JDK 11
   
   ### Are you willing to submit PR?
   
   - [x] Yes I am willing to submit a PR!
   


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