This is an automated email from the ASF dual-hosted git repository.

mihaibudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new 5b2a14494d [CALCITE-7524] JdbcSchema throws exception for DECIMAL 
columns with precision 0 in JDBC metadata
5b2a14494d is described below

commit 5b2a14494dc370ac7692f57319f9748c31999418
Author: AlexisCubilla <[email protected]>
AuthorDate: Tue May 12 15:47:04 2026 -0300

    [CALCITE-7524] JdbcSchema throws exception for DECIMAL columns with 
precision 0 in JDBC metadata
    
    Problem:
    JdbcSchema builds RelDataType from DatabaseMetaData (COLUMN_SIZE, 
DECIMAL_DIGITS).
    Some JDBC drivers (notably PostgreSQL) return COLUMN_SIZE 0 for 
NUMERIC/DECIMAL
    columns declared without explicit precision. That led to
    createSqlType(DECIMAL, 0, scale), which SqlTypeFactoryImpl rejects
    ("DECIMAL precision 0 must be between 1 and ...").
    
    Root cause:
    sqlType() treated any non-negative precision as literal. Zero is used by 
drivers
    as "unspecified" / unknown width, not as a valid SQL DECIMAL precision.
    
    Fix:
    When sqlTypeName is DECIMAL and reported precision is 0, replace it with
    typeFactory.getTypeSystem().getDefaultPrecision(DECIMAL) before 
createSqlType.
---
 .../apache/calcite/adapter/jdbc/JdbcSchema.java    |  9 ++-
 .../apache/calcite/test/JdbcSchemaSqlTypeTest.java | 74 ++++++++++++++++++++++
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java 
b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java
index eb1f11b74d..7d1cb8864a 100644
--- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java
+++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java
@@ -448,7 +448,14 @@ private static RelDataType sqlType(RelDataTypeFactory 
typeFactory, int dataType,
     if (precision >= 0
         && scale >= 0
         && sqlTypeName.allowsPrecScale(true, true)) {
-      return typeFactory.createSqlType(sqlTypeName, precision, scale);
+      int p = precision;
+      // Some JDBC drivers (e.g. PostgreSQL) report column size 0 for NUMERIC /
+      // DECIMAL columns without explicit precision in DDL. Calcite rejects
+      // DECIMAL(0, scale) (see SqlTypeFactoryImpl#createSqlType).
+      if (p == 0 && sqlTypeName == SqlTypeName.DECIMAL) {
+        p = typeFactory.getTypeSystem().getDefaultPrecision(sqlTypeName);
+      }
+      return typeFactory.createSqlType(sqlTypeName, p, scale);
     } else if (precision >= 0 && sqlTypeName.allowsPrecNoScale()) {
       return typeFactory.createSqlType(sqlTypeName, precision);
     } else {
diff --git 
a/core/src/test/java/org/apache/calcite/test/JdbcSchemaSqlTypeTest.java 
b/core/src/test/java/org/apache/calcite/test/JdbcSchemaSqlTypeTest.java
new file mode 100644
index 0000000000..33a74c9416
--- /dev/null
+++ b/core/src/test/java/org/apache/calcite/test/JdbcSchemaSqlTypeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.test;
+
+import org.apache.calcite.adapter.jdbc.JdbcSchema;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelDataTypeSystem;
+import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
+import org.apache.calcite.sql.type.SqlTypeName;
+
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Method;
+import java.sql.Types;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/** Tests JDBC metadata type mapping in {@link JdbcSchema}. */
+class JdbcSchemaSqlTypeTest {
+
+  @Test void jdbcSchemaSqlTypeMapsNumericZeroPrecision() throws Exception {
+    final RelDataTypeFactory factory =
+        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    final Method sqlType =
+        JdbcSchema.class.getDeclaredMethod(
+            "sqlType",
+            RelDataTypeFactory.class,
+            int.class,
+            int.class,
+            int.class,
+            String.class);
+    sqlType.setAccessible(true);
+    final RelDataType t =
+        (RelDataType) sqlType.invoke(null, factory, Types.NUMERIC, 0, 6, null);
+    assertThat(t.getSqlTypeName(), is(SqlTypeName.DECIMAL));
+    assertThat(t.getPrecision(), is(19));
+    assertThat(t.getScale(), is(6));
+  }
+
+  @Test void jdbcSchemaSqlTypeMapsDecimalZeroPrecision() throws Exception {
+    final RelDataTypeFactory factory =
+        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    final Method sqlType =
+        JdbcSchema.class.getDeclaredMethod(
+            "sqlType",
+            RelDataTypeFactory.class,
+            int.class,
+            int.class,
+            int.class,
+            String.class);
+    sqlType.setAccessible(true);
+    final RelDataType t =
+        (RelDataType) sqlType.invoke(null, factory, Types.DECIMAL, 0, 2, null);
+    assertThat(t.getSqlTypeName(), is(SqlTypeName.DECIMAL));
+    assertThat(t.getPrecision(), is(19));
+    assertThat(t.getScale(), is(2));
+  }
+}

Reply via email to