diff --git a/src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetColumns.sql b/src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetColumns.sql index 94d2a0e61..b59f3b78a 100644 --- a/src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetColumns.sql +++ b/src/main/resources/com/google/cloud/spanner/jdbc/DatabaseMetaData_GetColumns.sql @@ -63,7 +63,7 @@ SELECT TABLE_CATALOG AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME, COLU ELSE 2 END AS NULLABLE, NULL AS REMARKS, - NULL AS COLUMN_DEF, + COLUMN_DEFAULT AS COLUMN_DEF, 0 AS SQL_DATA_TYPE, 0 AS SQL_DATETIME_SUB, CASE diff --git a/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql b/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql index 38c105108..5924f980f 100644 --- a/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql +++ b/src/main/resources/com/google/cloud/spanner/jdbc/postgresql/DatabaseMetaData_GetColumns.sql @@ -62,7 +62,7 @@ SELECT TABLE_CATALOG AS "TABLE_CAT", TABLE_SCHEMA AS "TABLE_SCHEM", TABLE_NAME A ELSE 2 END AS "NULLABLE", NULL AS "REMARKS", - NULL AS "COLUMN_DEF", + COLUMN_DEFAULT AS "COLUMN_DEF", 0 AS "SQL_DATA_TYPE", 0 AS "SQL_DATETIME_SUB", CHARACTER_MAXIMUM_LENGTH AS "CHAR_OCTET_LENGTH", diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java index 94d9ad140..0ebd0031a 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java @@ -21,7 +21,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeFalse; import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseAdminClient; @@ -62,10 +61,6 @@ public class ITJdbcDatabaseMetaDataTest extends ITAbstractJdbcTest { @BeforeClass public static void setup() throws Exception { - assumeFalse( - "Named schemas are not yet supported on the emulator", - EmulatorSpannerHelper.isUsingEmulator()); - database = env.getOrCreateDatabase( Dialect.GOOGLE_STANDARD_SQL, getMusicTablesDdl(Dialect.GOOGLE_STANDARD_SQL)); @@ -89,6 +84,18 @@ public static void setup() throws Exception { .map(statement -> statement.replace(" ON ", " ON test.")) .map(statement -> statement.replace(" ON test.DELETE", " ON DELETE")) .map(statement -> statement.replace(" REFERENCES ", " REFERENCES test.")) + .map( + statement -> + EmulatorSpannerHelper.isUsingEmulator() + ? statement.replace("Fk_Concerts_Singer", "test_Fk_Concerts_Singer") + : statement) + .map( + statement -> + EmulatorSpannerHelper.isUsingEmulator() + ? statement.replace( + "Fk_TableWithRef_TableWithAllColumnTypes", + "test_Fk_TableWithRef_TableWithAllColumnTypes") + : statement) .collect(Collectors.toList()); tables.add(0, "create schema test"); client @@ -110,6 +117,7 @@ private static final class Column { private final boolean nullable; private final Integer charOctetLength; private final boolean computed; + private final String defaultValue; private Column( String name, @@ -120,7 +128,17 @@ private Column( Integer radix, boolean nullable, Integer charOctetLength) { - this(name, type, typeName, colSize, decimalDigits, radix, nullable, charOctetLength, false); + this( + name, + type, + typeName, + colSize, + decimalDigits, + radix, + nullable, + charOctetLength, + false, + null); } private Column( @@ -132,7 +150,8 @@ private Column( Integer radix, boolean nullable, Integer charOctetLength, - boolean computed) { + boolean computed, + String defaultValue) { this.name = name; this.type = type; this.typeName = typeName; @@ -142,21 +161,42 @@ private Column( this.nullable = nullable; this.charOctetLength = charOctetLength; this.computed = computed; + this.defaultValue = defaultValue; } } private static final List EXPECTED_COLUMNS = Arrays.asList( new Column("ColInt64", Types.BIGINT, "INT64", 19, null, 10, false, null), - new Column("ColFloat64", Types.DOUBLE, "FLOAT64", 15, 16, 2, false, null), - new Column("ColFloat32", Types.REAL, "FLOAT32", 15, 16, 2, false, null), + new Column("ColFloat64", Types.DOUBLE, "FLOAT64", 15, 16, 2, false, null, false, "0.0"), + new Column("ColFloat32", Types.REAL, "FLOAT32", 15, 16, 2, false, null, false, "0.0"), new Column("ColBool", Types.BOOLEAN, "BOOL", null, null, null, false, null), - new Column("ColString", Types.NVARCHAR, "STRING(100)", 100, null, null, false, 100), + new Column( + "ColString", + Types.NVARCHAR, + "STRING(100)", + 100, + null, + null, + false, + 100, + false, + "'Hello World!'"), new Column( "ColStringMax", Types.NVARCHAR, "STRING(MAX)", 2621440, null, null, false, 2621440), new Column("ColBytes", Types.BINARY, "BYTES(100)", 100, null, null, false, null), new Column("ColBytesMax", Types.BINARY, "BYTES(MAX)", 10485760, null, null, false, null), - new Column("ColDate", Types.DATE, "DATE", 10, null, null, false, null), + new Column( + "ColDate", + Types.DATE, + "DATE", + 10, + null, + null, + false, + null, + false, + "DATE '2000-01-01'"), new Column("ColTimestamp", Types.TIMESTAMP, "TIMESTAMP", 35, null, null, false, null), new Column("ColCommitTS", Types.TIMESTAMP, "TIMESTAMP", 35, null, null, false, null), new Column("ColNumeric", Types.NUMERIC, "NUMERIC", 15, null, 10, false, null), @@ -202,7 +242,8 @@ private Column( null, true, 2621440, - true)); + true, + null)); @Test public void testGetColumns() throws SQLException { @@ -244,7 +285,7 @@ public void testGetColumns() throws SQLException { col.nullable ? DatabaseMetaData.columnNullable : DatabaseMetaData.columnNoNulls, rs.getInt("NULLABLE")); assertNull(rs.getString("REMARKS")); - assertNull(rs.getString("COLUMN_DEF")); + assertEquals(col.defaultValue, rs.getString("COLUMN_DEF")); assertEquals(0, rs.getInt("SQL_DATA_TYPE")); assertEquals(0, rs.getInt("SQL_DATETIME_SUB")); if (col.charOctetLength == null) { @@ -360,7 +401,11 @@ public void testGetCrossReferences() throws SQLException { assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("DELETE_RULE")); - assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_Concerts_Singer", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + } assertEquals("PK_Singers", rs.getString("PK_NAME")); assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getShort("DEFERRABILITY")); assertFalse(rs.next()); @@ -389,7 +434,11 @@ public void testGetCrossReferences() throws SQLException { assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getShort("DEFERRABILITY")); assertTrue(rs.next()); @@ -404,7 +453,11 @@ public void testGetCrossReferences() throws SQLException { assertEquals(2, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getShort("DEFERRABILITY")); assertTrue(rs.next()); @@ -419,7 +472,11 @@ public void testGetCrossReferences() throws SQLException { assertEquals(3, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyNoAction, rs.getShort("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getShort("DEFERRABILITY")); assertFalse(rs.next()); @@ -519,6 +576,12 @@ public void testGetIndexInfo() throws SQLException { connection.getMetaData().getIndexInfo(DEFAULT_CATALOG, schema, null, false, false)) { for (IndexInfo index : EXPECTED_INDICES) { + // The emulator does not generate indexes for foreign keys in a non-default schema. + if (EmulatorSpannerHelper.isUsingEmulator() + && "test".equals(schema) + && ("FOREIGN_KEY".equals(index.indexName) || "GENERATED".equals(index.indexName))) { + continue; + } assertTrue(rs.next()); assertEquals(DEFAULT_CATALOG, rs.getString("TABLE_CAT")); assertEquals(schema, rs.getString("TABLE_SCHEM")); @@ -612,7 +675,11 @@ private void assertImportedKeysTableWithRef(String schema, ResultSet rs) throws assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertNotNull(rs.getString("PK_NAME")); // Index name is generated. assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -628,7 +695,11 @@ private void assertImportedKeysTableWithRef(String schema, ResultSet rs) throws assertEquals(2, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertNotNull(rs.getString("PK_NAME")); // Index name is generated. assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -644,7 +715,11 @@ private void assertImportedKeysTableWithRef(String schema, ResultSet rs) throws assertEquals(3, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_TableWithRef_TableWithAllColumnTypes", rs.getString("FK_NAME")); + } assertNotNull(rs.getString("PK_NAME")); // Index name is generated. assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -684,7 +759,11 @@ private void assertImportedKeysConcerts(String schema, ResultSet rs) throws SQLE assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_Concerts_Singer", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + } assertEquals("PK_Singers", rs.getString("PK_NAME")); assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -720,7 +799,11 @@ private void assertExportedKeysSingers(String schema, ResultSet rs) throws SQLEx assertEquals(1, rs.getShort("KEY_SEQ")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("UPDATE_RULE")); assertEquals(DatabaseMetaData.importedKeyRestrict, rs.getInt("DELETE_RULE")); - assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + if (EmulatorSpannerHelper.isUsingEmulator() && "test".equals(schema)) { + assertEquals("test_Fk_Concerts_Singer", rs.getString("FK_NAME")); + } else { + assertEquals("Fk_Concerts_Singer", rs.getString("FK_NAME")); + } assertEquals("PK_Singers", rs.getString("PK_NAME")); assertEquals(DatabaseMetaData.importedKeyNotDeferrable, rs.getInt("DEFERRABILITY")); @@ -888,9 +971,6 @@ public void testGetTables() throws SQLException { try (ResultSet rs = connection.getMetaData().getTables(DEFAULT_CATALOG, schema, null, null)) { for (Table table : EXPECTED_TABLES) { - if (EmulatorSpannerHelper.isUsingEmulator() && table.name.equals("SingersView")) { - continue; - } assertTrue(rs.next()); assertEquals(DEFAULT_CATALOG, rs.getString("TABLE_CAT")); assertEquals(schema, rs.getString("TABLE_SCHEM")); diff --git a/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql b/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql index 51f7d1ea1..8e4a60b24 100644 --- a/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql +++ b/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql @@ -49,7 +49,7 @@ CREATE TABLE Songs ( TrackId INT64 NOT NULL, SongName STRING(MAX), Duration INT64, - SongGenre STRING(25) + SongGenre STRING(25) DEFAULT ('Jazz') ) PRIMARY KEY(SingerId, AlbumId, TrackId), INTERLEAVE IN PARENT Albums ON DELETE CASCADE; @@ -69,14 +69,14 @@ CREATE TABLE Concerts ( CREATE TABLE TableWithAllColumnTypes ( ColInt64 INT64 NOT NULL, - ColFloat64 FLOAT64 NOT NULL, - ColFloat32 FLOAT32 NOT NULL, + ColFloat64 FLOAT64 NOT NULL DEFAULT (0.0), + ColFloat32 FLOAT32 NOT NULL DEFAULT (0.0), ColBool BOOL NOT NULL, - ColString STRING(100) NOT NULL, + ColString STRING(100) NOT NULL DEFAULT ('Hello World!'), ColStringMax STRING(MAX) NOT NULL, ColBytes BYTES(100) NOT NULL, ColBytesMax BYTES(MAX) NOT NULL, - ColDate DATE NOT NULL, + ColDate DATE NOT NULL DEFAULT (DATE '2000-01-01'), ColTimestamp TIMESTAMP NOT NULL, ColCommitTS TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true), ColNumeric NUMERIC NOT NULL,