diff --git a/jdbc-v2/src/main/java/com/clickhouse/jdbc/metadata/DatabaseMetaDataImpl.java b/jdbc-v2/src/main/java/com/clickhouse/jdbc/metadata/DatabaseMetaDataImpl.java index f31b8034f..a41046425 100644 --- a/jdbc-v2/src/main/java/com/clickhouse/jdbc/metadata/DatabaseMetaDataImpl.java +++ b/jdbc-v2/src/main/java/com/clickhouse/jdbc/metadata/DatabaseMetaDataImpl.java @@ -3,12 +3,12 @@ import com.clickhouse.client.api.sql.SQLUtils; import com.clickhouse.data.ClickHouseColumn; import com.clickhouse.data.ClickHouseDataType; +import com.clickhouse.jdbc.ClientInfoProperties; import com.clickhouse.jdbc.ConnectionImpl; import com.clickhouse.jdbc.Driver; +import com.clickhouse.jdbc.DriverProperties; import com.clickhouse.jdbc.JdbcV2Wrapper; import com.clickhouse.jdbc.ResultSetImpl; -import com.clickhouse.jdbc.ClientInfoProperties; -import com.clickhouse.jdbc.DriverProperties; import com.clickhouse.jdbc.internal.ExceptionUtils; import com.clickhouse.jdbc.internal.JdbcUtils; import com.clickhouse.jdbc.internal.MetadataResultSet; @@ -903,7 +903,6 @@ private static String columnDataTypeToSqlType(String value) { @Override public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { //Return an empty result set with the required columns - log.warn("getColumnPrivileges is not supported and may return invalid results"); try { return connection.createStatement().executeQuery("SELECT NULL::Nullable(String) AS TABLE_CAT, " + "NULL::Nullable(String) AS TABLE_SCHEM, " + @@ -912,7 +911,8 @@ public ResultSet getColumnPrivileges(String catalog, String schema, String table "NULL::Nullable(String) AS GRANTOR, " + "NULL::Nullable(String) AS GRANTEE, " + "NULL::Nullable(String) AS PRIVILEGE, " + - "NULL::Nullable(String) AS IS_GRANTABLE"); + "NULL::Nullable(String) AS IS_GRANTABLE" + + " LIMIT 0"); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); } @@ -921,7 +921,6 @@ public ResultSet getColumnPrivileges(String catalog, String schema, String table @Override public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { //Return an empty result set with the required columns - log.warn("getTablePrivileges is not supported and may return invalid results"); try { return connection.createStatement().executeQuery("SELECT NULL::Nullable(String) AS TABLE_CAT, " + "NULL::Nullable(String) AS TABLE_SCHEM, " + @@ -929,7 +928,8 @@ public ResultSet getTablePrivileges(String catalog, String schemaPattern, String "NULL::Nullable(String) AS GRANTOR, " + "NULL::Nullable(String) AS GRANTEE, " + "NULL::Nullable(String) AS PRIVILEGE, " + - "NULL::Nullable(String) AS IS_GRANTABLE"); + "NULL::Nullable(String) AS IS_GRANTABLE" + + " LIMIT 0"); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); } @@ -938,7 +938,6 @@ public ResultSet getTablePrivileges(String catalog, String schemaPattern, String @Override public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { //Return an empty result set with the required columns - log.warn("getBestRowIdentifier is not supported and may return invalid results"); try { return connection.createStatement().executeQuery("SELECT NULL::Nullable(Int16) AS SCOPE, " + "NULL::Nullable(String) AS COLUMN_NAME, " + @@ -947,7 +946,8 @@ public ResultSet getBestRowIdentifier(String catalog, String schema, String tabl "NULL::Nullable(Int32) AS COLUMN_SIZE, " + "NULL::Nullable(Int32) AS BUFFER_LENGTH, " + "NULL::Nullable(Int16) AS DECIMAL_DIGITS, " + - "NULL::Nullable(Int16) AS PSEUDO_COLUMN"); + "NULL::Nullable(Int16) AS PSEUDO_COLUMN" + + " LIMIT 0"); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); } @@ -956,7 +956,6 @@ public ResultSet getBestRowIdentifier(String catalog, String schema, String tabl @Override public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException { //Return an empty result set with the required columns - log.warn("getVersionColumns is not supported and may return invalid results"); try { return connection.createStatement().executeQuery("SELECT NULL::Nullable(Int16) AS SCOPE, " + "NULL::Nullable(String) AS COLUMN_NAME, " + @@ -965,7 +964,8 @@ public ResultSet getVersionColumns(String catalog, String schema, String table) "NULL::Nullable(Int32) AS COLUMN_SIZE, " + "NULL::Nullable(Int32) AS BUFFER_LENGTH, " + "NULL::Nullable(Int16) AS DECIMAL_DIGITS, " + - "NULL::Nullable(Int16) AS PSEUDO_COLUMN"); + "NULL::Nullable(Int16) AS PSEUDO_COLUMN" + + " LIMIT 0"); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); } @@ -995,8 +995,7 @@ public ResultSet getPrimaryKeys(String catalog, String schema, String table) thr @Override public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException { - //Return an empty result set with the required columns - log.warn("getImportedKeys is not supported and may return invalid results"); + // ClickHouse has no notion of foreign key. This method should return empty resultset try { String sql = "SELECT NULL::Nullable(String) AS PKTABLE_CAT, " + "NULL::Nullable(String) AS PKTABLE_SCHEM, " + @@ -1011,7 +1010,8 @@ public ResultSet getImportedKeys(String catalog, String schema, String table) th "NULL::Nullable(Int16) AS DELETE_RULE, " + "NULL::Nullable(String) AS FK_NAME, " + "NULL::Nullable(String) AS PK_NAME, " + - "NULL::Nullable(Int16) AS DEFERRABILITY"; + "NULL::Nullable(Int16) AS DEFERRABILITY" + + " LIMIT 0"; return connection.createStatement().executeQuery(sql); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); @@ -1020,8 +1020,7 @@ public ResultSet getImportedKeys(String catalog, String schema, String table) th @Override public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException { - //Return an empty result set with the required columns - log.warn("getExportedKeys is not supported and may return invalid results"); + // ClickHouse has no notion of foreign key. This method should return empty resultset try { return connection.createStatement().executeQuery("SELECT NULL::Nullable(String) AS PKTABLE_CAT, " + "NULL::Nullable(String) AS PKTABLE_SCHEM, " + @@ -1036,7 +1035,8 @@ public ResultSet getExportedKeys(String catalog, String schema, String table) th "NULL::Nullable(Int16) AS DELETE_RULE, " + "NULL::Nullable(String) AS FK_NAME, " + "NULL::Nullable(String) AS PK_NAME, " + - "NULL::Nullable(Int16) AS DEFERRABILITY"); + "NULL::Nullable(Int16) AS DEFERRABILITY" + + " LIMIT 0"); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); } @@ -1045,7 +1045,6 @@ public ResultSet getExportedKeys(String catalog, String schema, String table) th @Override public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { //Return an empty result set with the required columns - log.warn("getCrossReference is not supported and may return invalid results"); try { String columns = "NULL ::Nullable(String) AS PKTABLE_CAT, " + "NULL::Nullable(String) AS PKTABLE_SCHEM, " + @@ -1060,7 +1059,8 @@ public ResultSet getCrossReference(String parentCatalog, String parentSchema, St "NULL::Nullable(Int16) AS DELETE_RULE, " + "NULL::Nullable(String) AS FK_NAME, " + "NULL::Nullable(String) AS PK_NAME, " + - "NULL::Nullable(Int16) AS DEFERRABILITY"; + "NULL::Nullable(Int16) AS DEFERRABILITY" + + " LIMIT 0"; return connection.createStatement().executeQuery("SELECT " + columns); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); @@ -1150,7 +1150,8 @@ public ResultSet getIndexInfo(String catalog, String schema, String table, boole "null::Nullable(String) AS ASC_OR_DESC, " + "null::Nullable(Int64) AS CARDINALITY, " + "null::Nullable(Int64) AS PAGES, " + - "null::Nullable(String) AS FILTER_CONDITION "; + "null::Nullable(String) AS FILTER_CONDITION " + + " LIMIT 0"; return connection.createStatement().executeQuery(sql); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); @@ -1220,7 +1221,6 @@ public boolean supportsBatchUpdates() throws SQLException { @Override public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { //Return an empty result set with the required columns - log.warn("getUDTs is not supported and may return invalid results"); try { return connection.createStatement().executeQuery("SELECT " + "NULL::Nullable(String) AS TYPE_CAT, " + @@ -1229,7 +1229,8 @@ public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePa "NULL::Nullable(String) AS CLASS_NAME, " + "NULL::Nullable(Int32) AS DATA_TYPE, " + "NULL::Nullable(String) AS REMARKS, " + - "NULL::Nullable(Int16) AS BASE_TYPE"); + "NULL::Nullable(Int16) AS BASE_TYPE" + + " LIMIT 0"); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); } @@ -1266,7 +1267,6 @@ public boolean supportsGetGeneratedKeys() throws SQLException { @Override public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException { //Return an empty result set with the required columns - log.warn("getSuperTypes is not supported and may return invalid results"); try { return connection.createStatement().executeQuery( "SELECT NULL::Nullable(String) AS TYPE_CAT, " @@ -1274,7 +1274,8 @@ public ResultSet getSuperTypes(String catalog, String schemaPattern, String type + "NULL::Nullable(String) AS TYPE_NAME, " + "NULL::Nullable(String) AS SUPERTYPE_CAT, " + "NULL::Nullable(String) AS SUPERTYPE_SCHEM, " - + "NULL::Nullable(String) AS SUPERTYPE_NAME"); + + "NULL::Nullable(String) AS SUPERTYPE_NAME" + + " LIMIT 0"); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); } @@ -1283,14 +1284,14 @@ public ResultSet getSuperTypes(String catalog, String schemaPattern, String type @Override public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { //Return an empty result set with the required columns - log.warn("getSuperTables is not supported and may return invalid results"); try { return connection.createStatement().executeQuery( "SELECT " + "NULL::Nullable(String) AS TABLE_CAT, " + "NULL::Nullable(String) AS TABLE_SCHEM, " + "NULL::Nullable(String) AS TABLE_NAME, " - + "NULL::Nullable(String) AS SUPERTABLE_NAME"); + + "NULL::Nullable(String) AS SUPERTABLE_NAME" + + " LIMIT 0"); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); } @@ -1299,7 +1300,6 @@ public ResultSet getSuperTables(String catalog, String schemaPattern, String tab @Override public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException { //Return an empty result set with the required columns - log.warn("getAttributes is not supported and may return invalid results"); try { return connection.createStatement().executeQuery( "SELECT " @@ -1323,7 +1323,8 @@ public ResultSet getAttributes(String catalog, String schemaPattern, String type + "NULL::Nullable(String) AS SCOPE_CATALOG, " + "NULL::Nullable(String) AS SCOPE_SCHEMA, " + "NULL::Nullable(String) AS SCOPE_TABLE, " - + "NULL::Nullable(Int16) AS SOURCE_DATA_TYPE"); + + "NULL::Nullable(Int16) AS SOURCE_DATA_TYPE" + + " LIMIT 0"); } catch (Exception e) { throw ExceptionUtils.toSqlState(e); } diff --git a/jdbc-v2/src/test/java/com/clickhouse/jdbc/metadata/DatabaseMetaDataTest.java b/jdbc-v2/src/test/java/com/clickhouse/jdbc/metadata/DatabaseMetaDataTest.java index af3191a42..142c9596f 100644 --- a/jdbc-v2/src/test/java/com/clickhouse/jdbc/metadata/DatabaseMetaDataTest.java +++ b/jdbc-v2/src/test/java/com/clickhouse/jdbc/metadata/DatabaseMetaDataTest.java @@ -3,9 +3,9 @@ import com.clickhouse.client.ClickHouseServerForTest; import com.clickhouse.data.ClickHouseDataType; import com.clickhouse.data.ClickHouseVersion; -import com.clickhouse.jdbc.JdbcIntegrationTest; import com.clickhouse.jdbc.ClientInfoProperties; import com.clickhouse.jdbc.DriverProperties; +import com.clickhouse.jdbc.JdbcIntegrationTest; import com.clickhouse.jdbc.internal.JdbcUtils; import org.testng.Assert; import org.testng.annotations.Test; @@ -467,7 +467,7 @@ public void testGetFunctionColumns() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); try (ResultSet rs = dbmd.getFunctionColumns(null, null, "mapContains", null)) { - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList( "FUNCTION_CAT", "FUNCTION_SCHEM", @@ -577,6 +577,7 @@ public void testGetIndexInfoColumnType() throws Exception { ); ResultSet rs = dbmd.getIndexInfo(null, null, null, false, false); + assertFalse(rs.next()); ResultSetMetaData rsmd = rs.getMetaData(); assertProcedureColumns(rsmd, expectedColumnNames, expectedColumnTypes); } @@ -592,6 +593,7 @@ public void testGetProcedures() throws Exception { Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, Types.SMALLINT, Types.VARCHAR); ResultSet rs = dbmd.getProcedures(null, null, null); + assertFalse(rs.next()); ResultSetMetaData rsmd = rs.getMetaData(); assertProcedureColumns(rsmd, columnNames, columnTypes); } @@ -645,6 +647,7 @@ public void testGetProceduresColumnType() throws Exception { Types.VARCHAR, Types.VARCHAR); ResultSetMetaData rsmd = dbmd.getProcedureColumns(null, null, null, null).getMetaData(); + assertProcedureColumns(rsmd, expectedColumnNames, columnTypes); } } @@ -655,7 +658,7 @@ public void testGetColumnPrivileges() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getColumnPrivileges(null, null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", @@ -686,7 +689,7 @@ public void testGetTablePrivileges() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getTablePrivileges(null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", @@ -714,7 +717,7 @@ public void testGetVersionColumnsColumns() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getVersionColumns(null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("SCOPE", "COLUMN_NAME", "DATA_TYPE", @@ -771,8 +774,10 @@ public void testGetImportedKeys() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getImportedKeys(null, null, null); + assertFalse(rs.next()); - List expectedColumnNames = Arrays.asList("PKTABLE_CAT", + List expectedColumnNames = Arrays.asList( + "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", "PKCOLUMN_NAME", @@ -813,7 +818,7 @@ public void testGetExportedKeys() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getExportedKeys(null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", @@ -856,7 +861,7 @@ public void testGetCrossReference() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getCrossReference(null, null, null, null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", @@ -898,7 +903,7 @@ public void testGetUDTs() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getUDTs(null, null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", @@ -927,7 +932,7 @@ public void testGetSuperTypes() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getSuperTypes(null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", @@ -953,7 +958,7 @@ public void testGetSuperTables() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getSuperTables(null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", @@ -976,7 +981,7 @@ public void testGetBestRowIdentifier() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getBestRowIdentifier(null, null, null, 0, true); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("SCOPE", "COLUMN_NAME", "DATA_TYPE", @@ -1007,7 +1012,7 @@ public void testGetAttributes() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getAttributes(null, null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("TYPE_CAT", "TYPE_SCHEM", "TYPE_NAME", @@ -1064,7 +1069,7 @@ public void testGetPseudoColumns() throws Exception { try (Connection conn = getJdbcConnection()) { DatabaseMetaData dbmd = conn.getMetaData(); ResultSet rs = dbmd.getPseudoColumns(null, null, null, null); - + assertFalse(rs.next()); List expectedColumnNames = Arrays.asList("TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",