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