From 1bab7ad532abcf43a1f56dda536e0eea35fdfd6e Mon Sep 17 00:00:00 2001 From: Sigge <6099273+siggemannen@users.noreply.github.com> Date: Thu, 9 Apr 2026 08:46:55 +0200 Subject: [PATCH 1/3] Added support for system views --- .../org/duckdb/DuckDBDatabaseMetaData.java | 55 +++++++++++-------- src/test/java/org/duckdb/TestMetadata.java | 50 +++++++++-------- 2 files changed, 61 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java b/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java index 47aa5eada..9a48b14a8 100644 --- a/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java +++ b/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java @@ -2,7 +2,15 @@ import static java.lang.System.lineSeparator; -import java.sql.*; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.RowIdLifetime; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.Statement; +import java.sql.Types; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -714,7 +722,7 @@ public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLExce @Override public ResultSet getTableTypes() throws SQLException { - String[] tableTypesArray = new String[] {"TABLE", "LOCAL TEMPORARY", "VIEW"}; + String[] tableTypesArray = new String[] {"TABLE", "LOCAL TEMPORARY", "VIEW", "SYSTEM VIEW" }; StringBuilder stringBuilder = new StringBuilder(128); boolean first = true; for (String tableType : tableTypesArray) { @@ -744,16 +752,22 @@ public ResultSet getTables(String catalog, String schemaPattern, String tableNam sb.append("table_catalog AS 'TABLE_CAT'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("table_schema AS 'TABLE_SCHEM'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("table_name AS 'TABLE_NAME'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append("CASE WHEN table_type = 'BASE TABLE' THEN 'TABLE' ELSE table_type END AS 'TABLE_TYPE'") - .append(TRAILING_COMMA) - .append(lineSeparator()); + sb.append("table_type AS 'TABLE_TYPE'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("TABLE_COMMENT AS 'REMARKS'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL::VARCHAR AS 'TYPE_CAT'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL::VARCHAR AS 'TYPE_SCHEM'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL::VARCHAR AS 'TYPE_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL::VARCHAR AS 'SELF_REFERENCING_COL_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL::VARCHAR AS 'REF_GENERATION'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append("FROM information_schema.tables").append(lineSeparator()); + sb + .append( + "FROM (select database_name as table_catalog, schema_name as table_schema, table_name, CASE WHEN (\"temporary\") THEN ('LOCAL TEMPORARY') WHEN (\"internal\") THEN 'SYSTEM TABLE' ELSE 'TABLE' END AS table_type, comment AS TABLE_COMMENT") + .append(lineSeparator()); + sb.append("from duckdb_tables() x").append(lineSeparator()); + sb + .append( + "union all select database_name,schema_name, view_name, CASE WHEN (\"internal\") then 'SYSTEM VIEW' ELSE 'VIEW' END, comment from duckdb_views() x ) x") + .append(lineSeparator()); sb.append("WHERE table_name LIKE ? ESCAPE '\\'").append(lineSeparator()); boolean hasCatalogParam = appendEqualsQual(sb, "table_catalog", catalog); boolean hasSchemaParam = appendLikeQual(sb, "table_schema", schemaPattern); @@ -790,8 +804,7 @@ public ResultSet getTables(String catalog, String schemaPattern, String tableNam if (types != null && types.length > 0) { for (int i = 0; i < types.length; i++) { - String param = "TABLE".equals(types[i]) ? "BASE TABLE" : types[i]; - ps.setString(paramIdx + i, param); + ps.setString(paramIdx + i, types[i]); } } ps.closeOnCompletion(); @@ -803,27 +816,25 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa throws SQLException { StringBuilder sb = new StringBuilder(QUERY_SB_DEFAULT_CAPACITY); sb.append("SELECT").append(lineSeparator()); - sb.append("table_catalog AS 'TABLE_CAT'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append("table_schema AS 'TABLE_SCHEM'").append(TRAILING_COMMA).append(lineSeparator()); + sb.append("database_name AS 'TABLE_CAT'").append(TRAILING_COMMA).append(lineSeparator()); + sb.append("schema_name AS 'TABLE_SCHEM'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("table_name AS 'TABLE_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("column_name as 'COLUMN_NAME'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append(makeDataMap("regexp_replace(c.data_type, '\\(.*\\)', '')", "DATA_TYPE")) - .append(TRAILING_COMMA) - .append(lineSeparator()); + sb.append(makeDataMap("regexp_replace(c.data_type, '\\(.*\\)', '')", "DATA_TYPE")).append(TRAILING_COMMA) + .append(lineSeparator()); sb.append("c.data_type AS 'TYPE_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("numeric_precision AS 'COLUMN_SIZE'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL AS 'BUFFER_LENGTH'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("numeric_scale AS 'DECIMAL_DIGITS'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("10 AS 'NUM_PREC_RADIX'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append("CASE WHEN is_nullable = 'YES' THEN 1 else 0 END AS 'NULLABLE'") - .append(TRAILING_COMMA) - .append(lineSeparator()); - sb.append("COLUMN_COMMENT as 'REMARKS'").append(TRAILING_COMMA).append(lineSeparator()); + sb.append("CASE WHEN is_nullable = 'YES' THEN 1 else 0 END AS 'NULLABLE'").append(TRAILING_COMMA) + .append(lineSeparator()); + sb.append("comment as 'REMARKS'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("column_default AS 'COLUMN_DEF'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL AS 'SQL_DATA_TYPE'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL AS 'SQL_DATETIME_SUB'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL AS 'CHAR_OCTET_LENGTH'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append("ordinal_position AS 'ORDINAL_POSITION'").append(TRAILING_COMMA).append(lineSeparator()); + sb.append("column_index AS 'ORDINAL_POSITION'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("is_nullable AS 'IS_NULLABLE'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL AS 'SCOPE_CATALOG'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL AS 'SCOPE_SCHEMA'").append(TRAILING_COMMA).append(lineSeparator()); @@ -831,17 +842,17 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa sb.append("NULL AS 'SOURCE_DATA_TYPE'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("'' AS 'IS_AUTOINCREMENT'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("'' AS 'IS_GENERATEDCOLUMN'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append("FROM information_schema.columns c").append(lineSeparator()); + sb.append("FROM duckdb_columns() c").append(lineSeparator()); sb.append("WHERE TRUE").append(lineSeparator()); - boolean hasCatalogParam = appendEqualsQual(sb, "table_catalog", catalog); - boolean hasSchemaParam = appendLikeQual(sb, "table_schema", schemaPattern); + boolean hasCatalogParam = appendEqualsQual(sb, "database_name", catalog); + boolean hasSchemaParam = appendLikeQual(sb, "schema_name", schemaPattern); sb.append("AND table_name LIKE ? ESCAPE '\\'").append(lineSeparator()); sb.append("AND column_name LIKE ? ESCAPE '\\'").append(lineSeparator()); sb.append("ORDER BY").append(lineSeparator()); sb.append("\"TABLE_CAT\"").append(TRAILING_COMMA).append(lineSeparator()); sb.append("\"TABLE_SCHEM\"").append(TRAILING_COMMA).append(lineSeparator()); sb.append("\"TABLE_NAME\"").append(TRAILING_COMMA).append(lineSeparator()); - sb.append("\"ORDINAL_POSITION\"").append(lineSeparator()); + sb.append("\"column_index\"").append(lineSeparator()); PreparedStatement ps = conn.prepareStatement(sb.toString()); diff --git a/src/test/java/org/duckdb/TestMetadata.java b/src/test/java/org/duckdb/TestMetadata.java index c0e7b9cf9..f4795bd05 100644 --- a/src/test/java/org/duckdb/TestMetadata.java +++ b/src/test/java/org/duckdb/TestMetadata.java @@ -11,6 +11,21 @@ public class TestMetadata { + private static void assertNonSystemTables(ResultSet rs, String name) throws Exception + { + assertTrue(rs.next()); + while(true) + { + String type = rs.getString("TABLE_TYPE"); + if(type.equals("SYSTEM VIEW") || type.equals("SYSTEM TABLE")) + { + assertTrue(rs.next()); + continue; + } + assertEquals(rs.getString("TABLE_NAME"), name); + break; + } + } public static void test_get_table_types_bug1258() throws Exception { try (Connection conn = DriverManager.getConnection(JDBC_URL)) { try (Statement stmt = conn.createStatement()) { @@ -22,26 +37,18 @@ public static void test_get_table_types_bug1258() throws Exception { DatabaseMetaData dm = conn.getMetaData(); try (ResultSet rs = dm.getTables(null, null, null, null)) { - assertTrue(rs.next()); - assertEquals(rs.getString("TABLE_NAME"), "b"); - assertTrue(rs.next()); - assertEquals(rs.getString("TABLE_NAME"), "a1"); - assertTrue(rs.next()); - assertEquals(rs.getString("TABLE_NAME"), "a2"); - assertTrue(rs.next()); - assertEquals(rs.getString("TABLE_NAME"), "c"); + assertNonSystemTables(rs, "b"); + assertNonSystemTables(rs, "a1"); + assertNonSystemTables(rs, "a2"); + assertNonSystemTables(rs, "c"); assertFalse(rs.next()); } try (ResultSet rs = dm.getTables(null, null, null, new String[] {})) { - assertTrue(rs.next()); - assertEquals(rs.getString("TABLE_NAME"), "b"); - assertTrue(rs.next()); - assertEquals(rs.getString("TABLE_NAME"), "a1"); - assertTrue(rs.next()); - assertEquals(rs.getString("TABLE_NAME"), "a2"); - assertTrue(rs.next()); - assertEquals(rs.getString("TABLE_NAME"), "c"); + assertNonSystemTables(rs, "b"); + assertNonSystemTables(rs, "a1"); + assertNonSystemTables(rs,"a2"); + assertNonSystemTables(rs, "c"); assertFalse(rs.next()); } @@ -504,7 +511,7 @@ public static void test_schema_reflection() throws Exception { assertFalse(rs.next()); } - try (ResultSet rs = md.getTables(null, null, "%", null)) { + try (ResultSet rs = md.getTables(null, null, "%", new String[] {"TABLE", "VIEW"})) { assertTrue(rs.next()); assertTrue(rs.getObject("TABLE_CAT") != null); assertEquals(rs.getString("TABLE_SCHEM"), DuckDBConnection.DEFAULT_SCHEMA); @@ -550,8 +557,7 @@ public static void test_schema_reflection() throws Exception { assertFalse(rs.next()); } - try (ResultSet rs = md.getTables(null, DuckDBConnection.DEFAULT_SCHEMA, "a", null)) { - + try (ResultSet rs = md.getTables(null, DuckDBConnection.DEFAULT_SCHEMA, "a", new String[] {"TABLE", "VIEW"})) { assertTrue(rs.next()); assertTrue(rs.getObject("TABLE_CAT") != null); assertEquals(rs.getString("TABLE_SCHEM"), DuckDBConnection.DEFAULT_SCHEMA); @@ -578,7 +584,7 @@ public static void test_schema_reflection() throws Exception { assertFalse(rs.next()); } - try (ResultSet rs = md.getTables("", "", "%", null)) { + try (ResultSet rs = md.getTables("", "", "%", new String[] {"TABLE", "VIEW"})) { assertFalse(rs.next()); } @@ -746,7 +752,7 @@ public static void test_get_tables_with_attached_catalog() throws Exception { } // test if getTables with null catalog returns all tables. - try (ResultSet resultSet = databaseMetaData.getTables(null, null, "%", null)) { + try (ResultSet resultSet = databaseMetaData.getTables(null, null, "%", new String[] {"TABLE"})) { assertTrue(resultSet.next(), "getTables should return 2 tables, got 0"); // first table should be ATTACHED_CATALOG.T2 @@ -793,7 +799,7 @@ public static void test_get_tables_param_binding_for_table_types() throws Except } public static void test_get_table_types() throws Exception { - String[] tableTypesArray = new String[] {"TABLE", "LOCAL TEMPORARY", "VIEW"}; + String[] tableTypesArray = new String[] {"TABLE", "LOCAL TEMPORARY", "VIEW" , "SYSTEM VIEW"}; List tableTypesList = new ArrayList<>(asList(tableTypesArray)); tableTypesList.sort(Comparator.naturalOrder()); From 9e38dfcce50747bc066fd86a871df2e7443e6b9a Mon Sep 17 00:00:00 2001 From: Sigge <6099273+siggemannen@users.noreply.github.com> Date: Thu, 9 Apr 2026 21:03:27 +0200 Subject: [PATCH 2/3] Added a couple of more tests to verify view calls fixed formatting on windows + fixed test formatting --- scripts/format.py | 7 ++-- .../org/duckdb/DuckDBDatabaseMetaData.java | 31 +++++++-------- src/test/java/org/duckdb/TestMetadata.java | 38 ++++++++++++++----- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/scripts/format.py b/scripts/format.py index 37e399c65..f8f4bcd31 100644 --- a/scripts/format.py +++ b/scripts/format.py @@ -11,11 +11,12 @@ if args.check: template += ['--dry-run', '--Werror'] -hpp_files = set(glob('src/jni/*.hpp')) +hpp_files = set([r.replace("\\", "/") for r in glob('src/jni/*.hpp')]) + hpp_files.remove('src/jni/functions.hpp') -cpp_files = set(glob('src/jni/*.cpp')) +cpp_files = set([r.replace("\\", "/") for r in glob('src/jni/*.cpp')]) cpp_files.remove('src/jni/functions.cpp') -java_files = set(glob('src/**/*.java', recursive=True)) +java_files = set([r.replace("\\", "/") for r in glob('src/**/*.java', recursive=True)]) for name in [*hpp_files] + [*cpp_files] + [*java_files]: print('Formatting', name) diff --git a/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java b/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java index 9a48b14a8..a14597e31 100644 --- a/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java +++ b/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java @@ -690,8 +690,8 @@ public ResultSet getCatalogs() throws SQLException { public ResultSet getSchemas() throws SQLException { Statement statement = conn.createStatement(); statement.closeOnCompletion(); - return statement.executeQuery( - "SELECT schema_name AS 'TABLE_SCHEM', catalog_name AS 'TABLE_CATALOG' FROM information_schema.schemata ORDER BY \"TABLE_CATALOG\", \"TABLE_SCHEM\""); + return statement.executeQuery("SELECT schema_name AS 'TABLE_SCHEM', catalog_name AS 'TABLE_CATALOG' FROM " + + "information_schema.schemata ORDER BY \"TABLE_CATALOG\", \"TABLE_SCHEM\""); } @Override @@ -722,7 +722,7 @@ public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLExce @Override public ResultSet getTableTypes() throws SQLException { - String[] tableTypesArray = new String[] {"TABLE", "LOCAL TEMPORARY", "VIEW", "SYSTEM VIEW" }; + String[] tableTypesArray = new String[] {"TABLE", "LOCAL TEMPORARY", "VIEW", "SYSTEM VIEW"}; StringBuilder stringBuilder = new StringBuilder(128); boolean first = true; for (String tableType : tableTypesArray) { @@ -759,15 +759,14 @@ public ResultSet getTables(String catalog, String schemaPattern, String tableNam sb.append("NULL::VARCHAR AS 'TYPE_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL::VARCHAR AS 'SELF_REFERENCING_COL_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL::VARCHAR AS 'REF_GENERATION'").append(TRAILING_COMMA).append(lineSeparator()); - sb - .append( - "FROM (select database_name as table_catalog, schema_name as table_schema, table_name, CASE WHEN (\"temporary\") THEN ('LOCAL TEMPORARY') WHEN (\"internal\") THEN 'SYSTEM TABLE' ELSE 'TABLE' END AS table_type, comment AS TABLE_COMMENT") - .append(lineSeparator()); + sb.append("FROM (select database_name as table_catalog, schema_name as table_schema, table_name, CASE WHEN " + + "(\"temporary\") THEN ('LOCAL TEMPORARY') WHEN (\"internal\") THEN 'SYSTEM TABLE' ELSE 'TABLE' " + + "END AS table_type, comment AS TABLE_COMMENT") + .append(lineSeparator()); sb.append("from duckdb_tables() x").append(lineSeparator()); - sb - .append( - "union all select database_name,schema_name, view_name, CASE WHEN (\"internal\") then 'SYSTEM VIEW' ELSE 'VIEW' END, comment from duckdb_views() x ) x") - .append(lineSeparator()); + sb.append("union all select database_name,schema_name, view_name, CASE WHEN (\"internal\") then 'SYSTEM " + + "VIEW' ELSE 'VIEW' END, comment from duckdb_views() x ) x") + .append(lineSeparator()); sb.append("WHERE table_name LIKE ? ESCAPE '\\'").append(lineSeparator()); boolean hasCatalogParam = appendEqualsQual(sb, "table_catalog", catalog); boolean hasSchemaParam = appendLikeQual(sb, "table_schema", schemaPattern); @@ -820,15 +819,17 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa sb.append("schema_name AS 'TABLE_SCHEM'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("table_name AS 'TABLE_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("column_name as 'COLUMN_NAME'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append(makeDataMap("regexp_replace(c.data_type, '\\(.*\\)', '')", "DATA_TYPE")).append(TRAILING_COMMA) - .append(lineSeparator()); + sb.append(makeDataMap("regexp_replace(c.data_type, '\\(.*\\)', '')", "DATA_TYPE")) + .append(TRAILING_COMMA) + .append(lineSeparator()); sb.append("c.data_type AS 'TYPE_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("numeric_precision AS 'COLUMN_SIZE'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL AS 'BUFFER_LENGTH'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("numeric_scale AS 'DECIMAL_DIGITS'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("10 AS 'NUM_PREC_RADIX'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append("CASE WHEN is_nullable = 'YES' THEN 1 else 0 END AS 'NULLABLE'").append(TRAILING_COMMA) - .append(lineSeparator()); + sb.append("CASE WHEN is_nullable = 'YES' THEN 1 else 0 END AS 'NULLABLE'") + .append(TRAILING_COMMA) + .append(lineSeparator()); sb.append("comment as 'REMARKS'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("column_default AS 'COLUMN_DEF'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL AS 'SQL_DATA_TYPE'").append(TRAILING_COMMA).append(lineSeparator()); diff --git a/src/test/java/org/duckdb/TestMetadata.java b/src/test/java/org/duckdb/TestMetadata.java index f4795bd05..c5c9220ec 100644 --- a/src/test/java/org/duckdb/TestMetadata.java +++ b/src/test/java/org/duckdb/TestMetadata.java @@ -11,14 +11,11 @@ public class TestMetadata { - private static void assertNonSystemTables(ResultSet rs, String name) throws Exception - { + private static void assertNonSystemTables(ResultSet rs, String name) throws Exception { assertTrue(rs.next()); - while(true) - { + while (true) { String type = rs.getString("TABLE_TYPE"); - if(type.equals("SYSTEM VIEW") || type.equals("SYSTEM TABLE")) - { + if (type.equals("SYSTEM VIEW") || type.equals("SYSTEM TABLE")) { assertTrue(rs.next()); continue; } @@ -47,7 +44,7 @@ public static void test_get_table_types_bug1258() throws Exception { try (ResultSet rs = dm.getTables(null, null, null, new String[] {})) { assertNonSystemTables(rs, "b"); assertNonSystemTables(rs, "a1"); - assertNonSystemTables(rs,"a2"); + assertNonSystemTables(rs, "a2"); assertNonSystemTables(rs, "c"); assertFalse(rs.next()); } @@ -557,7 +554,8 @@ public static void test_schema_reflection() throws Exception { assertFalse(rs.next()); } - try (ResultSet rs = md.getTables(null, DuckDBConnection.DEFAULT_SCHEMA, "a", new String[] {"TABLE", "VIEW"})) { + try (ResultSet rs = + md.getTables(null, DuckDBConnection.DEFAULT_SCHEMA, "a", new String[] {"TABLE", "VIEW"})) { assertTrue(rs.next()); assertTrue(rs.getObject("TABLE_CAT") != null); assertEquals(rs.getString("TABLE_SCHEM"), DuckDBConnection.DEFAULT_SCHEMA); @@ -799,7 +797,7 @@ public static void test_get_tables_param_binding_for_table_types() throws Except } public static void test_get_table_types() throws Exception { - String[] tableTypesArray = new String[] {"TABLE", "LOCAL TEMPORARY", "VIEW" , "SYSTEM VIEW"}; + String[] tableTypesArray = new String[] {"TABLE", "LOCAL TEMPORARY", "VIEW", "SYSTEM VIEW"}; List tableTypesList = new ArrayList<>(asList(tableTypesArray)); tableTypesList.sort(Comparator.naturalOrder()); @@ -1032,4 +1030,26 @@ public static void test_metadata_type_info() throws Exception { assertEquals(count, 21); } } + + public static void test_metadata_system_views() throws Exception { + try (Connection conn = DriverManager.getConnection(JDBC_URL); + ResultSet rs = conn.getMetaData().getTables(null, "information_schema", "columns", null)) { + int count = 0; + while (rs.next()) { + count += 1; + } + assertEquals(count, 1); + } + } + + public static void test_metadata_system_columns() throws Exception { + try (Connection conn = DriverManager.getConnection(JDBC_URL); + ResultSet rs = conn.getMetaData().getColumns("system", "information_schema", "views", null)) { + int count = 0; + while (rs.next()) { + count += 1; + } + assertTrue(count > 0); + } + } } From 43bab87f050d9b2caaa815a78a3a2ee5221918ee Mon Sep 17 00:00:00 2001 From: Sigge <6099273+siggemannen@users.noreply.github.com> Date: Thu, 9 Apr 2026 21:11:54 +0200 Subject: [PATCH 3/3] Fixed more formatting --- .../java/org/duckdb/DuckDBDatabaseMetaData.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java b/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java index a14597e31..1fc7fdd2b 100644 --- a/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java +++ b/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java @@ -690,8 +690,8 @@ public ResultSet getCatalogs() throws SQLException { public ResultSet getSchemas() throws SQLException { Statement statement = conn.createStatement(); statement.closeOnCompletion(); - return statement.executeQuery("SELECT schema_name AS 'TABLE_SCHEM', catalog_name AS 'TABLE_CATALOG' FROM " + - "information_schema.schemata ORDER BY \"TABLE_CATALOG\", \"TABLE_SCHEM\""); + return statement.executeQuery("SELECT schema_name AS 'TABLE_SCHEM', catalog_name AS 'TABLE_CATALOG' FROM " + + "information_schema.schemata ORDER BY \"TABLE_CATALOG\", \"TABLE_SCHEM\""); } @Override @@ -759,13 +759,13 @@ public ResultSet getTables(String catalog, String schemaPattern, String tableNam sb.append("NULL::VARCHAR AS 'TYPE_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL::VARCHAR AS 'SELF_REFERENCING_COL_NAME'").append(TRAILING_COMMA).append(lineSeparator()); sb.append("NULL::VARCHAR AS 'REF_GENERATION'").append(TRAILING_COMMA).append(lineSeparator()); - sb.append("FROM (select database_name as table_catalog, schema_name as table_schema, table_name, CASE WHEN " + - "(\"temporary\") THEN ('LOCAL TEMPORARY') WHEN (\"internal\") THEN 'SYSTEM TABLE' ELSE 'TABLE' " + - "END AS table_type, comment AS TABLE_COMMENT") + sb.append("FROM (select database_name as table_catalog, schema_name as table_schema, table_name, CASE WHEN " + + "(\"temporary\") THEN ('LOCAL TEMPORARY') WHEN (\"internal\") THEN 'SYSTEM TABLE' ELSE 'TABLE' " + + "END AS table_type, comment AS TABLE_COMMENT") .append(lineSeparator()); sb.append("from duckdb_tables() x").append(lineSeparator()); - sb.append("union all select database_name,schema_name, view_name, CASE WHEN (\"internal\") then 'SYSTEM " + - "VIEW' ELSE 'VIEW' END, comment from duckdb_views() x ) x") + sb.append("union all select database_name,schema_name, view_name, CASE WHEN (\"internal\") then 'SYSTEM " + + "VIEW' ELSE 'VIEW' END, comment from duckdb_views() x ) x") .append(lineSeparator()); sb.append("WHERE table_name LIKE ? ESCAPE '\\'").append(lineSeparator()); boolean hasCatalogParam = appendEqualsQual(sb, "table_catalog", catalog);