This is an automated email from the ASF dual-hosted git repository.
diqiu50 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 2937e7be21 [#10519] fix(postgresql): handle unconstrained NUMERIC type
with precision=0 (#10534)
2937e7be21 is described below
commit 2937e7be214f810b3eb1d693694a2689563b0a57
Author: Qi Yu <[email protected]>
AuthorDate: Mon May 18 11:52:32 2026 +0800
[#10519] fix(postgresql): handle unconstrained NUMERIC type with
precision=0 (#10534)
### What changes were proposed in this pull request?
In `PostgreSqlTypeConverter.toGravitino()`, when a PostgreSQL column is
defined as `NUMERIC` without explicit precision/scale, the JDBC driver
returns `columnSize=0`. This was passed directly to
`Types.DecimalType.of(0, ...)` which rejects precision=0 with an
`IllegalArgumentException`.
Fix: map `columnSize=null` or `columnSize=0` to `DECIMAL(38, 18)` — the
maximum supported precision with a sensible default scale.
### Why are the changes needed?
Fix: #10519
Unconstrained `NUMERIC` columns are valid in PostgreSQL and commonly
used. Loading any table containing such a column was completely broken.
### Does this PR introduce _any_ user-facing change?
Yes — loading tables with unconstrained `NUMERIC` columns now succeeds,
returning `DECIMAL(38, 18)` instead of throwing an error.
### How was this patch tested?
Added unit tests in `TestPostgreSqlTypeConverter` for both
`columnSize=0` and `columnSize=null` cases.
---------
Co-authored-by: Claude Sonnet 4.6 <[email protected]>
---
.../postgresql/converter/PostgreSqlTypeConverter.java | 12 +++++++++++-
.../postgresql/converter/TestPostgreSqlTypeConverter.java | 15 +++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git
a/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/converter/PostgreSqlTypeConverter.java
b/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/converter/PostgreSqlTypeConverter.java
index a50e12baf0..09613ecac5 100644
---
a/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/converter/PostgreSqlTypeConverter.java
+++
b/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/converter/PostgreSqlTypeConverter.java
@@ -41,6 +41,8 @@ public class PostgreSqlTypeConverter extends
JdbcTypeConverter {
static final String BYTEA = "bytea";
@VisibleForTesting static final String JDBC_ARRAY_PREFIX = "_";
@VisibleForTesting static final String ARRAY_TOKEN = "[]";
+ @VisibleForTesting static final int DEFAULT_NUMERIC_PRECISION = 38;
+ @VisibleForTesting static final int DEFAULT_NUMERIC_SCALE = 18;
@Override
public Type toGravitino(JdbcTypeBean typeBean) {
@@ -76,7 +78,15 @@ public class PostgreSqlTypeConverter extends
JdbcTypeConverter {
.map(Types.TimestampType::withTimeZone)
.orElseGet(Types.TimestampType::withTimeZone);
case NUMERIC:
- return Types.DecimalType.of(typeBean.getColumnSize(),
typeBean.getScale());
+ Integer columnSize = typeBean.getColumnSize();
+ Integer scale = typeBean.getScale();
+ if (columnSize == null || columnSize == 0) {
+ // PostgreSQL unconstrained NUMERIC has no fixed precision/scale.
Gravitino DecimalType
+ // cannot represent that exactly, so use the maximum supported
decimal as a compatibility
+ // tradeoff for engines and clients that cannot consume ExternalType.
+ return Types.DecimalType.of(DEFAULT_NUMERIC_PRECISION,
DEFAULT_NUMERIC_SCALE);
+ }
+ return Types.DecimalType.of(columnSize, scale == null ? 0 : scale);
case VARCHAR:
return typeBean.getColumnSize() == null
? Types.StringType.get()
diff --git
a/catalogs/catalog-jdbc-postgresql/src/test/java/org/apache/gravitino/catalog/postgresql/converter/TestPostgreSqlTypeConverter.java
b/catalogs/catalog-jdbc-postgresql/src/test/java/org/apache/gravitino/catalog/postgresql/converter/TestPostgreSqlTypeConverter.java
index d976336fb1..b868ab1f18 100644
---
a/catalogs/catalog-jdbc-postgresql/src/test/java/org/apache/gravitino/catalog/postgresql/converter/TestPostgreSqlTypeConverter.java
+++
b/catalogs/catalog-jdbc-postgresql/src/test/java/org/apache/gravitino/catalog/postgresql/converter/TestPostgreSqlTypeConverter.java
@@ -27,6 +27,8 @@ import static
org.apache.gravitino.catalog.postgresql.converter.PostgreSqlTypeCo
import static
org.apache.gravitino.catalog.postgresql.converter.PostgreSqlTypeConverter.BOOL;
import static
org.apache.gravitino.catalog.postgresql.converter.PostgreSqlTypeConverter.BPCHAR;
import static
org.apache.gravitino.catalog.postgresql.converter.PostgreSqlTypeConverter.BYTEA;
+import static
org.apache.gravitino.catalog.postgresql.converter.PostgreSqlTypeConverter.DEFAULT_NUMERIC_PRECISION;
+import static
org.apache.gravitino.catalog.postgresql.converter.PostgreSqlTypeConverter.DEFAULT_NUMERIC_SCALE;
import static
org.apache.gravitino.catalog.postgresql.converter.PostgreSqlTypeConverter.FLOAT_4;
import static
org.apache.gravitino.catalog.postgresql.converter.PostgreSqlTypeConverter.FLOAT_8;
import static
org.apache.gravitino.catalog.postgresql.converter.PostgreSqlTypeConverter.INT_2;
@@ -68,6 +70,19 @@ public class TestPostgreSqlTypeConverter {
checkJdbcTypeToGravitinoType(Types.TimestampType.withoutTimeZone(3),
TIMESTAMP, 23, null, 3);
checkJdbcTypeToGravitinoType(Types.TimestampType.withoutTimeZone(6),
TIMESTAMP, 26, null, 6);
checkJdbcTypeToGravitinoType(Types.DecimalType.of(10, 2), NUMERIC, 10, 2,
0);
+ // Unconstrained NUMERIC (no precision) returns columnSize=0 from JDBC
metadata;
+ // mapped to Gravitino's maximum supported decimal as a compatibility
tradeoff.
+ checkJdbcTypeToGravitinoType(
+ Types.DecimalType.of(DEFAULT_NUMERIC_PRECISION,
DEFAULT_NUMERIC_SCALE), NUMERIC, 0, 0, 0);
+ checkJdbcTypeToGravitinoType(
+ Types.DecimalType.of(DEFAULT_NUMERIC_PRECISION, DEFAULT_NUMERIC_SCALE),
+ NUMERIC,
+ null,
+ null,
+ 0);
+ checkJdbcTypeToGravitinoType(Types.DecimalType.of(9, 0), NUMERIC, 9, 0, 0);
+ checkJdbcTypeToGravitinoType(Types.DecimalType.of(18, 0), NUMERIC, 18, 0,
0);
+ checkJdbcTypeToGravitinoType(Types.DecimalType.of(20, 0), NUMERIC, 20, 0,
0);
checkJdbcTypeToGravitinoType(Types.VarCharType.of(20), VARCHAR, 20, null,
0);
checkJdbcTypeToGravitinoType(Types.FixedCharType.of(20), BPCHAR, 20, null,
0);
checkJdbcTypeToGravitinoType(Types.StringType.get(), TEXT, null, null, 0);