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

rubenada 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 c989bfb0a5 [CALCITE-7908] ModelHandler should apply the model 
class-name filter to the JDBC driver auto-detected from jdbcUrl
c989bfb0a5 is described below

commit c989bfb0a5c28d03975089f207e4aaa98e730a0d
Author: Ruben Quesada Lopez <[email protected]>
AuthorDate: Fri Oct 30 16:51:50 2026 +0000

    [CALCITE-7908] ModelHandler should apply the model class-name filter to the 
JDBC driver auto-detected from jdbcUrl
---
 .../org/apache/calcite/model/ModelHandler.java     | 15 ++++++++--
 .../org/apache/calcite/model/ModelHandlerTest.java | 34 ++++++++++++++++++++++
 site/_docs/history.md                              |  4 ++-
 site/_docs/model.md                                |  3 ++
 4 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/model/ModelHandler.java 
b/core/src/main/java/org/apache/calcite/model/ModelHandler.java
index d9b064392a..c6e1deee1a 100644
--- a/core/src/main/java/org/apache/calcite/model/ModelHandler.java
+++ b/core/src/main/java/org/apache/calcite/model/ModelHandler.java
@@ -61,6 +61,7 @@
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.sql.DriverManager;
 import java.sql.SQLException;
 import java.util.ArrayDeque;
 import java.util.Collections;
@@ -411,10 +412,20 @@ protected Map<String, Object> operandMap(@Nullable 
JsonSchema jsonSchema,
 
   public void visit(JsonJdbcSchema jsonSchema) {
     final SchemaPlus parentSchema = currentMutableSchema("jdbc schema");
-    classNameFilter.check(jsonSchema.jdbcDriver);
+    String driverClassName = jsonSchema.jdbcDriver;
+    if (driverClassName == null || driverClassName.trim().isEmpty()) {
+      // No driver class in the model; check the one DriverManager picks for 
the URL
+      try {
+        driverClassName = 
DriverManager.getDriver(jsonSchema.jdbcUrl).getClass().getName();
+      } catch (SQLException e) {
+        throw new RuntimeException(e);
+      }
+    }
+    classNameFilter.check(driverClassName);
+
     final DataSource dataSource =
         JdbcSchema.dataSource(jsonSchema.jdbcUrl,
-            jsonSchema.jdbcDriver,
+            driverClassName,
             jsonSchema.jdbcUser,
             jsonSchema.jdbcPassword);
     final JdbcSchema schema;
diff --git a/core/src/test/java/org/apache/calcite/model/ModelHandlerTest.java 
b/core/src/test/java/org/apache/calcite/model/ModelHandlerTest.java
index 258c0d8bf0..87c76ac860 100644
--- a/core/src/test/java/org/apache/calcite/model/ModelHandlerTest.java
+++ b/core/src/test/java/org/apache/calcite/model/ModelHandlerTest.java
@@ -341,4 +341,38 @@ public static class NotAFunction {
         not(containsString("see log of")));
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-7908";>[CALCITE-7908]
+   * ModelHandler should apply the model class-name filter to the JDBC driver
+   * auto-detected from jdbcUrl</a>. */
+  @Test void testJdbcSchemaWithoutDriverChecksDetectedDriver() {
+    final String model = "inline:{"
+        + "  version: '1.0',"
+        + "  defaultSchema: 'SCOTT',"
+        + "  schemas: [ {"
+        + "    type: 'jdbc',"
+        + "    name: 'SCOTT',"
+        + "    jdbcUser: 'SA',"
+        + "    jdbcPassword: '',"
+        + "    jdbcUrl: 'jdbc:hsqldb:res:scott',"
+        + "    jdbcSchema: 'SCOTT'"
+        + "  } ]"
+        + "}";
+    // The model has no jdbcDriver, so the filter must see the driver
+    // that DriverManager picks for the URL
+    final SchemaPlus root = CalciteSchema.createRootSchema(false, 
false).plus();
+    Throwable e =
+        assertThrows(RuntimeException.class, () ->
+            new ModelHandler(root, model, ClassNameFilter.of("", 
"org.apache.calcite.")));
+    while (e != null && !(e instanceof SecurityException)) {
+      e = e.getCause();
+    }
+    assertThat("expected SecurityException in chain", e, notNullValue());
+    assertThat(e.getMessage(), containsString("org.hsqldb.jdbc.JDBCDriver"));
+
+    final SchemaPlus root2 = CalciteSchema.createRootSchema(false, 
false).plus();
+    assertDoesNotThrow(() ->
+        new ModelHandler(root2, model, ClassNameFilter.of("", "org.hsqldb.")));
+  }
+
 }
diff --git a/site/_docs/history.md b/site/_docs/history.md
index 0eb0fe88c3..511cfd6b01 100644
--- a/site/_docs/history.md
+++ b/site/_docs/history.md
@@ -84,7 +84,9 @@ #### Breaking Changes
 * [<a 
href="https://issues.apache.org/jira/browse/CALCITE-7713";>CALCITE-7713</a>]
 Class loading from model files has been disabled by default. Any attempt to 
load
 classes from model files will lead to `SecurityException` unless an appropriate
-pattern is set in `calcite.model.classes.allowed` system property.
+pattern is set in `calcite.model.classes.allowed` system property. This also 
applies
+to the JDBC driver that `DriverManager` chooses for `jdbcUrl` when a JDBC 
schema
+does not specify `jdbcDriver`.
 
 * [<a 
href="https://issues.apache.org/jira/browse/CALCITE-7716";>CALCITE-7716</a>]
 `UUID` values are now ordered as unsigned 128-bit values, as SQL requires.
diff --git a/site/_docs/model.md b/site/_docs/model.md
index 567313d973..5485d0597c 100644
--- a/site/_docs/model.md
+++ b/site/_docs/model.md
@@ -249,6 +249,9 @@ #### YAML
 
 `jdbcDriver` (optional string) is the name of the JDBC driver class. If not
 specified, uses whichever class the JDBC DriverManager chooses.
+Note: the class must pass the
+[`calcite.model.classes.allowed`]({{ site.apiRoot 
}}/org/apache/calcite/config/CalciteSystemProperty.html#MODEL_CLASSES_ALLOWED)
+system property.
 
 `jdbcUrl` (optional string) is the JDBC connect string, for example
 "jdbc:mysql://localhost/foodmart".

Reply via email to