This is an automated email from the ASF dual-hosted git repository.
thomasrebele 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 6626bcc16e [CALCITE-5832] CyclicMetadataException thrown in complex
JOIN
6626bcc16e is described below
commit 6626bcc16e4bec10b0032bc29d418336d15a7a93
Author: Thomas Rebele <[email protected]>
AuthorDate: Mon Feb 23 23:16:10 2026 +0100
[CALCITE-5832] CyclicMetadataException thrown in complex JOIN
---
.../org/apache/calcite/test/JdbcAdapterTest.java | 115 +++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
index 989aac3604..98c8edff3f 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
@@ -36,6 +36,7 @@
import java.sql.Connection;
import java.sql.DriverManager;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
@@ -1555,6 +1556,120 @@ private LockWrapper exclusiveCleanDb(Connection c)
throws SQLException {
.returnsCount(4);
}
+ /**
+ * Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-5832">[CALCITE-5832]
+ * CyclicMetadataException thrown in complex JOIN</a>. */
+ @Test void testJdbcCyclicMetadata() throws Exception {
+ final String url = MultiJdbcSchemaJoinTest.TempDb.INSTANCE.getUrl();
+ Connection baseConnection = DriverManager.getConnection(url);
+ Statement baseStmt = baseConnection.createStatement();
+ baseStmt.execute("CREATE TABLE T1 (\n"
+ + "\"contentViewsCount\" INTEGER,\n"
+ + "\"isExpired\" BOOLEAN,\n"
+ + "\"metadataPreviewUrl\" VARCHAR(100),\n"
+ + "\"format\" VARCHAR(100),\n"
+ + "\"description\" VARCHAR(100),\n"
+ + "\"language\" VARCHAR(100),\n"
+ + "\"assetTitle\" VARCHAR(100),\n"
+ + "\"assetType\" VARCHAR(100),\n"
+ + "\"contentType\" VARCHAR(100),\n"
+ + "\"doi\" VARCHAR(100),\n"
+ + "\"crmBpn\" VARCHAR(100),\n"
+ + "PRIMARY KEY(\"doi\"))");
+ baseStmt.execute("CREATE TABLE T2 (\n"
+ + "\"doi\" VARCHAR(100),\n"
+ + "\"industry\" VARCHAR(100),\n"
+ + "PRIMARY KEY(\"doi\", \"industry\"))");
+ baseStmt.execute("CREATE TABLE T3 (\n"
+ + "\"semaphoreId\" VARCHAR(100),\n"
+ + "\"name\" VARCHAR(100),\n"
+ + "\"industryId\" VARCHAR(100),\n"
+ + "PRIMARY KEY(\"semaphoreId\"))");
+ baseStmt.execute("CREATE TABLE T4 (\n"
+ + "\"contentViewsCount\" INTEGER,\n"
+ + "\"CRM_Account_ID\" VARCHAR(100),\n"
+ + "\"CRM_Account_Name\" VARCHAR(100),\n"
+ + "PRIMARY KEY(\"CRM_Account_ID\"))");
+ baseStmt.close();
+ baseConnection.commit();
+
+ Properties info = new Properties();
+ info.put("model",
+ "inline:"
+ + "{\n"
+ + " version: '1.0',\n"
+ + " defaultSchema: 'BASEJDBC',\n"
+ + " schemas: [\n"
+ + " {\n"
+ + " type: 'jdbc',\n"
+ + " name: 'BASEJDBC',\n"
+ + " jdbcDriver: '" + jdbcDriver.class.getName() + "',\n"
+ + " jdbcUrl: '" + url + "',\n"
+ + " jdbcCatalog: null,\n"
+ + " jdbcSchema: null\n"
+ + " }\n"
+ + " ]\n"
+ + "}");
+
+ final Connection calciteConnection =
+ DriverManager.getConnection("jdbc:calcite:", info);
+ final PreparedStatement preparedStatement = calciteConnection
+ .prepareStatement("SELECT \"_metadata.status\", \"doi\",
\"industry.title\", "
+ + "\"crm_account.crm_account_name\", \"assettitle\",
\"description\", \"assettype\", "
+ + "\"format\", \"contentviewscount\", \"metadatapreviewurl\",
\"language\", "
+ + "\"contenttype\", \"isexpired\" FROM (select\n"
+ + " \"A\".\"contentViewsCount\" \"contentviewscount\",\n"
+ + " \"A\".\"isExpired\" \"isexpired\",\n"
+ + " \"A\".\"metadataPreviewUrl\" \"metadatapreviewurl\",\n"
+ + " \"A\".\"format\" \"format\",\n"
+ + " \"A\".\"description\" \"description\",\n"
+ + " \"A\".\"language\" \"language\",\n"
+ + " \"A\".\"assetTitle\" \"assettitle\",\n"
+ + " \"A\".\"assetType\" \"assettype\",\n"
+ + " \"A\".\"contentType\" \"contenttype\",\n"
+ + " \"A\".\"doi\" \"doi\",\n"
+ + " null \"_metadata.status\",\n"
+ + " \"D\".\"industry.title\" \"industry.title\",\n"
+ + " \"F\".\"crm_account.crm_account_name\"
\"crm_account.crm_account_name\"\n"
+ + "from \"T1\" \"A\"\n"
+ + " left outer join \"T2\" \"B\"\n"
+ + " on \"A\".\"doi\" = \"B\".\"doi\"\n"
+ + " left outer join (\n"
+ + " select\n"
+ + " \"C\".\"semaphoreId\" \"industry.semaphoreId\",\n"
+ + " \"C\".\"name\" \"industry.title\"\n"
+ + " from \"T3\" \"C\"\n"
+ + " ) \"D\"\n"
+ + " on \"B\".\"industry\" = \"D\".\"industry.semaphoreId\"\n"
+ + " left outer join (\n"
+ + " select\n"
+ + " \"E\".\"CRM_Account_ID\"
\"crm_account.CRM_Account_ID\",\n"
+ + " \"E\".\"CRM_Account_Name\"
\"crm_account.crm_account_name\"\n"
+ + " from \"T4\" \"E\"\n"
+ + " ) \"F\"\n"
+ + " on \"A\".\"crmBpn\" = \"F\".\"crm_account"
+ + ".CRM_Account_ID\")\n"
+ + "WHERE (\"isexpired\" = ?)\n"
+ + "AND (\"language\" IN (?, ?))\n"
+ + "AND (\"contenttype\" IN (?, ?))\n"
+ + "AND (\"doi\" IN (?))\n"
+ + "ORDER BY \"doi\" ASC\n"
+ + "LIMIT 500 OFFSET 0");
+ preparedStatement.setBoolean(1, false);
+ preparedStatement.setString(2, "en");
+ preparedStatement.setString(3, "de");
+ preparedStatement.setString(4, "text/html");
+ preparedStatement.setString(5, "text/plain");
+ preparedStatement.setString(6, "");
+ ResultSet rs = preparedStatement.executeQuery();
+
+ assertThat(rs.next(), is(false));
+
+ rs.close();
+ calciteConnection.close();
+ }
+
/** Acquires a lock, and releases it when closed. */
static class LockWrapper implements AutoCloseable {
private final Lock lock;