Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions scripts/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
48 changes: 30 additions & 18 deletions src/main/java/org/duckdb/DuckDBDatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -682,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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -744,16 +752,21 @@ 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);
Expand Down Expand Up @@ -790,8 +803,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();
Expand All @@ -803,8 +815,8 @@ 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"))
Expand All @@ -818,30 +830,30 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
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("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());
sb.append("NULL AS 'SCOPE_TABLE'").append(TRAILING_COMMA).append(lineSeparator());
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());

Expand Down
70 changes: 48 additions & 22 deletions src/test/java/org/duckdb/TestMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@

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()) {
Expand All @@ -22,26 +34,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());
}

Expand Down Expand Up @@ -504,7 +508,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);
Expand Down Expand Up @@ -550,8 +554,8 @@ 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);
Expand All @@ -578,7 +582,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());
}

Expand Down Expand Up @@ -746,7 +750,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
Expand Down Expand Up @@ -793,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"};
String[] tableTypesArray = new String[] {"TABLE", "LOCAL TEMPORARY", "VIEW", "SYSTEM VIEW"};
List<String> tableTypesList = new ArrayList<>(asList(tableTypesArray));
tableTypesList.sort(Comparator.naturalOrder());

Expand Down Expand Up @@ -1026,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);
}
}
}
Loading