diff --git a/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java new file mode 100644 index 000000000000..124664dc7cff --- /dev/null +++ b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/java/com/google/cloud/spanner/jdbc/it/ITJdbcDatabaseMetaDataTest.java @@ -0,0 +1,560 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.jdbc.it; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; + +import com.google.cloud.spanner.IntegrationTest; +import com.google.cloud.spanner.jdbc.ITAbstractJdbcTest; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Arrays; +import java.util.List; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Integration tests for {@link DatabaseMetaData} implementation for Spanner. */ +@Category(IntegrationTest.class) +@RunWith(JUnit4.class) +public class ITJdbcDatabaseMetaDataTest extends ITAbstractJdbcTest { + private static final String DEFAULT_CATALOG = ""; + private static final String DEFAULT_SCHEMA = ""; + private static final String SINGERS_TABLE = "Singers"; + private static final String ALBUMS_TABLE = "Albums"; + private static final String SONGS_TABLE = "Songs"; + private static final String TABLE_WITH_ALL_COLS = "TableWithAllColumnTypes"; + + @Override + protected boolean doCreateMusicTables() { + return true; + } + + private static final class Column { + private final String name; + private final int type; + private final String typeName; + private final Integer colSize; + private final Integer decimalDigits; + private final Integer radix; + private final boolean nullable; + private final Integer charOctetLength; + + private Column( + String name, + int type, + String typeName, + Integer colSize, + Integer decimalDigits, + Integer radix, + boolean nullable, + Integer charOctetLength) { + this.name = name; + this.type = type; + this.typeName = typeName; + this.colSize = colSize; + this.decimalDigits = decimalDigits; + this.radix = radix; + this.nullable = nullable; + this.charOctetLength = charOctetLength; + } + } + + 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("ColBool", Types.BOOLEAN, "BOOL", null, null, null, false, null), + new Column("ColString", Types.NVARCHAR, "STRING(100)", 100, null, null, false, 100), + 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("ColTimestamp", Types.TIMESTAMP, "TIMESTAMP", 35, null, null, false, null), + new Column("ColCommitTS", Types.TIMESTAMP, "TIMESTAMP", 35, null, null, false, null), + new Column("ColInt64Array", Types.ARRAY, "ARRAY", 19, null, 10, true, null), + new Column("ColFloat64Array", Types.ARRAY, "ARRAY", 15, 16, 2, true, null), + new Column("ColBoolArray", Types.ARRAY, "ARRAY", null, null, null, true, null), + new Column( + "ColStringArray", Types.ARRAY, "ARRAY", 100, null, null, true, 100), + new Column( + "ColStringMaxArray", + Types.ARRAY, + "ARRAY", + 2621440, + null, + null, + true, + 2621440), + new Column( + "ColBytesArray", Types.ARRAY, "ARRAY", 100, null, null, true, null), + new Column( + "ColBytesMaxArray", + Types.ARRAY, + "ARRAY", + 10485760, + null, + null, + true, + null), + new Column("ColDateArray", Types.ARRAY, "ARRAY", 10, null, null, true, null), + new Column( + "ColTimestampArray", Types.ARRAY, "ARRAY", 35, null, null, true, null)); + + @Test + public void testGetColumns() throws SQLException { + try (Connection connection = createConnection()) { + try (ResultSet rs = + connection + .getMetaData() + .getColumns(DEFAULT_CATALOG, DEFAULT_SCHEMA, TABLE_WITH_ALL_COLS, null)) { + int pos = 1; + for (Column col : EXPECTED_COLUMNS) { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("TABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("TABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("TABLE_NAME"), is(equalTo(TABLE_WITH_ALL_COLS))); + assertThat(rs.getString("COLUMN_NAME"), is(equalTo(col.name))); + assertThat(rs.getInt("DATA_TYPE"), is(equalTo(col.type))); + assertThat(rs.getString("TYPE_NAME"), is(equalTo(col.typeName))); + if (col.colSize == null) { + assertThat(rs.getInt("COLUMN_SIZE"), is(equalTo(0))); + assertThat(rs.wasNull(), is(true)); + } else { + assertThat(rs.getInt("COLUMN_SIZE"), is(equalTo(col.colSize))); + } + rs.getObject("BUFFER_LENGTH"); // just assert that it exists + if (col.decimalDigits == null) { + assertThat(rs.getInt("DECIMAL_DIGITS"), is(equalTo(0))); + assertThat(rs.wasNull(), is(true)); + } else { + assertThat(rs.getInt("DECIMAL_DIGITS"), is(equalTo(col.decimalDigits))); + } + if (col.radix == null) { + assertThat(rs.getInt("NUM_PREC_RADIX"), is(equalTo(0))); + assertThat(rs.wasNull(), is(true)); + } else { + assertThat(rs.getInt("NUM_PREC_RADIX"), is(equalTo(col.radix))); + } + assertThat( + rs.getInt("NULLABLE"), + is( + equalTo( + col.nullable + ? DatabaseMetaData.columnNullable + : DatabaseMetaData.columnNoNulls))); + assertThat(rs.getString("REMARKS"), is(nullValue())); + assertThat(rs.getString("COLUMN_DEF"), is(nullValue())); + assertThat(rs.getInt("SQL_DATA_TYPE"), is(equalTo(0))); + assertThat(rs.getInt("SQL_DATETIME_SUB"), is(equalTo(0))); + if (col.charOctetLength == null) { + assertThat(rs.getInt("CHAR_OCTET_LENGTH"), is(equalTo(0))); + assertThat(rs.wasNull(), is(true)); + } else { + assertThat(rs.getInt("CHAR_OCTET_LENGTH"), is(equalTo(col.charOctetLength))); + } + assertThat(rs.getInt("ORDINAL_POSITION"), is(equalTo(pos))); + assertThat(rs.getString("IS_NULLABLE"), is(equalTo(col.nullable ? "YES" : "NO"))); + assertThat(rs.getString("SCOPE_CATALOG"), is(nullValue())); + assertThat(rs.getString("SCOPE_SCHEMA"), is(nullValue())); + assertThat(rs.getString("SCOPE_TABLE"), is(nullValue())); + assertThat(rs.getShort("SOURCE_DATA_TYPE"), is(equalTo((short) 0))); + assertThat(rs.wasNull(), is(true)); + assertThat(rs.getString("IS_AUTOINCREMENT"), is(equalTo("NO"))); + assertThat(rs.getString("IS_GENERATEDCOLUMN"), is(equalTo("NO"))); + assertThat(rs.getMetaData().getColumnCount(), is(equalTo(24))); + + pos++; + } + assertThat(rs.next(), is(false)); + } + } + } + + @Test + public void testGetCrossReferences() throws SQLException { + try (Connection connection = createConnection()) { + try (ResultSet rs = + connection + .getMetaData() + .getCrossReference( + DEFAULT_CATALOG, + DEFAULT_SCHEMA, + SINGERS_TABLE, + DEFAULT_CATALOG, + DEFAULT_SCHEMA, + ALBUMS_TABLE)) { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("PKTABLE_CAT"), is(equalTo(""))); + assertThat(rs.getString("PKTABLE_SCHEM"), is(equalTo(""))); + assertThat(rs.getString("PKTABLE_NAME"), is(equalTo("Singers"))); + assertThat(rs.getString("PKCOLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getString("FKTABLE_CAT"), is(equalTo(""))); + assertThat(rs.getString("FKTABLE_SCHEM"), is(equalTo(""))); + assertThat(rs.getString("FKTABLE_NAME"), is(equalTo("Albums"))); + assertThat(rs.getString("FKCOLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getShort("KEY_SEQ"), is(equalTo((short) 1))); + assertThat( + rs.getShort("UPDATE_RULE"), is(equalTo((short) DatabaseMetaData.importedKeyNoAction))); + assertThat( + rs.getShort("DELETE_RULE"), is(equalTo((short) DatabaseMetaData.importedKeyCascade))); + assertThat(rs.getString("FK_NAME"), is(nullValue())); + assertThat(rs.getString("PK_NAME"), is(equalTo("PRIMARY_KEY"))); + assertThat( + rs.getShort("DEFERRABILITY"), + is(equalTo((short) DatabaseMetaData.importedKeyNotDeferrable))); + } + try (ResultSet rs = + connection + .getMetaData() + .getCrossReference( + DEFAULT_CATALOG, + DEFAULT_SCHEMA, + ALBUMS_TABLE, + DEFAULT_CATALOG, + DEFAULT_SCHEMA, + SONGS_TABLE)) { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("PKTABLE_CAT"), is(equalTo(""))); + assertThat(rs.getString("PKTABLE_SCHEM"), is(equalTo(""))); + assertThat(rs.getString("PKTABLE_NAME"), is(equalTo("Albums"))); + assertThat(rs.getString("PKCOLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getString("FKTABLE_CAT"), is(equalTo(""))); + assertThat(rs.getString("FKTABLE_SCHEM"), is(equalTo(""))); + assertThat(rs.getString("FKTABLE_NAME"), is(equalTo("Songs"))); + assertThat(rs.getString("FKCOLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getShort("KEY_SEQ"), is(equalTo((short) 1))); + assertThat( + rs.getShort("UPDATE_RULE"), is(equalTo((short) DatabaseMetaData.importedKeyNoAction))); + assertThat( + rs.getShort("DELETE_RULE"), is(equalTo((short) DatabaseMetaData.importedKeyCascade))); + assertThat(rs.getString("FK_NAME"), is(nullValue())); + assertThat(rs.getString("PK_NAME"), is(equalTo("PRIMARY_KEY"))); + assertThat( + rs.getShort("DEFERRABILITY"), + is(equalTo((short) DatabaseMetaData.importedKeyNotDeferrable))); + + assertThat(rs.next(), is(true)); + assertThat(rs.getString("PKTABLE_CAT"), is(equalTo(""))); + assertThat(rs.getString("PKTABLE_SCHEM"), is(equalTo(""))); + assertThat(rs.getString("PKTABLE_NAME"), is(equalTo("Albums"))); + assertThat(rs.getString("PKCOLUMN_NAME"), is(equalTo("AlbumId"))); + assertThat(rs.getString("FKTABLE_CAT"), is(equalTo(""))); + assertThat(rs.getString("FKTABLE_SCHEM"), is(equalTo(""))); + assertThat(rs.getString("FKTABLE_NAME"), is(equalTo("Songs"))); + assertThat(rs.getString("FKCOLUMN_NAME"), is(equalTo("AlbumId"))); + assertThat(rs.getShort("KEY_SEQ"), is(equalTo((short) 2))); + assertThat( + rs.getShort("UPDATE_RULE"), is(equalTo((short) DatabaseMetaData.importedKeyNoAction))); + assertThat( + rs.getShort("DELETE_RULE"), is(equalTo((short) DatabaseMetaData.importedKeyCascade))); + assertThat(rs.getString("FK_NAME"), is(nullValue())); + assertThat(rs.getString("PK_NAME"), is(equalTo("PRIMARY_KEY"))); + assertThat( + rs.getShort("DEFERRABILITY"), + is(equalTo((short) DatabaseMetaData.importedKeyNotDeferrable))); + } + // try getting self-references + try (ResultSet rs = + connection + .getMetaData() + .getCrossReference( + DEFAULT_CATALOG, + DEFAULT_SCHEMA, + ALBUMS_TABLE, + DEFAULT_CATALOG, + DEFAULT_SCHEMA, + ALBUMS_TABLE)) { + assertThat(rs.next(), is(false)); + } + // try getting all cross-references in the database + try (ResultSet rs = + connection.getMetaData().getCrossReference(null, null, null, null, null, null)) { + for (int i = 0; i < 3; i++) { + assertThat(rs.next(), is(true)); + } + assertThat(rs.next(), is(false)); + } + } + } + + private static final class IndexInfo { + private final String tableName; + private final boolean nonUnique; + private final String indexName; + private final short ordinalPosition; + private final String columnName; + private final String ascDesc; + + private IndexInfo( + String tableName, + boolean nonUnique, + String indexName, + int ordinalPosition, + String columnName, + String ascDesc) { + this.tableName = tableName; + this.nonUnique = nonUnique; + this.indexName = indexName; + this.ordinalPosition = (short) ordinalPosition; + this.columnName = columnName; + this.ascDesc = ascDesc; + } + } + + private static final List EXPECTED_INDICES = + Arrays.asList( + new IndexInfo("Albums", false, "PRIMARY_KEY", 1, "SingerId", "A"), + new IndexInfo("Albums", false, "PRIMARY_KEY", 2, "AlbumId", "A"), + new IndexInfo("Albums", true, "AlbumsByAlbumTitle", 1, "AlbumTitle", "A"), + new IndexInfo("Albums", true, "AlbumsByAlbumTitle2", 0, "MarketingBudget", null), + new IndexInfo("Albums", true, "AlbumsByAlbumTitle2", 1, "AlbumTitle", "A"), + new IndexInfo("Concerts", false, "PRIMARY_KEY", 1, "VenueId", "A"), + new IndexInfo("Concerts", false, "PRIMARY_KEY", 2, "SingerId", "A"), + new IndexInfo("Concerts", false, "PRIMARY_KEY", 3, "ConcertDate", "A"), + new IndexInfo("Singers", false, "PRIMARY_KEY", 1, "SingerId", "A"), + new IndexInfo("Singers", true, "SingersByFirstLastName", 1, "FirstName", "A"), + new IndexInfo("Singers", true, "SingersByFirstLastName", 2, "LastName", "A"), + new IndexInfo("Songs", false, "PRIMARY_KEY", 1, "SingerId", "A"), + new IndexInfo("Songs", false, "PRIMARY_KEY", 2, "AlbumId", "A"), + new IndexInfo("Songs", false, "PRIMARY_KEY", 3, "TrackId", "A"), + new IndexInfo("Songs", false, "SongsBySingerAlbumSongNameDesc", 1, "SingerId", "A"), + new IndexInfo("Songs", false, "SongsBySingerAlbumSongNameDesc", 2, "AlbumId", "A"), + new IndexInfo("Songs", false, "SongsBySingerAlbumSongNameDesc", 3, "SongName", "D"), + new IndexInfo("Songs", true, "SongsBySongName", 1, "SongName", "A"), + new IndexInfo("TableWithAllColumnTypes", false, "PRIMARY_KEY", 1, "ColInt64", "A")); + + @Test + public void testGetIndexInfo() throws SQLException { + try (Connection connection = createConnection()) { + try (ResultSet rs = + connection + .getMetaData() + .getIndexInfo(DEFAULT_CATALOG, DEFAULT_SCHEMA, null, false, false)) { + + for (IndexInfo index : EXPECTED_INDICES) { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("TABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("TABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("TABLE_NAME"), is(equalTo(index.tableName))); + assertThat(rs.getBoolean("NON_UNIQUE"), is(index.nonUnique)); + assertThat(rs.getString("INDEX_QUALIFIER"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("INDEX_NAME"), is(equalTo(index.indexName))); + if (index.indexName.equals("PRIMARY_KEY")) { + assertThat(rs.getShort("TYPE"), is(equalTo(DatabaseMetaData.tableIndexClustered))); + } else { + assertThat(rs.getShort("TYPE"), is(equalTo(DatabaseMetaData.tableIndexHashed))); + } + assertThat(rs.getShort("ORDINAL_POSITION"), is(equalTo(index.ordinalPosition))); + if (index.ordinalPosition == 0) { + assertThat(rs.wasNull(), is(true)); + } + assertThat(rs.getString("COLUMN_NAME"), is(equalTo(index.columnName))); + assertThat(rs.getString("ASC_OR_DESC"), is(equalTo(index.ascDesc))); + assertThat(rs.getInt("CARDINALITY"), is(equalTo(-1))); + assertThat(rs.getInt("PAGES"), is(equalTo(-1))); + assertThat(rs.getString("FILTER_CONDITION"), is(nullValue())); + } + // all indices found + assertThat(rs.next(), is(false)); + } + } + } + + @Test + public void testGetExportedKeys() throws SQLException { + try (Connection connection = createConnection()) { + try (ResultSet rs = + connection + .getMetaData() + .getExportedKeys(DEFAULT_CATALOG, DEFAULT_SCHEMA, SINGERS_TABLE)) { + assertKeysSingersAlbums(rs); + } + try (ResultSet rs = + connection.getMetaData().getExportedKeys(DEFAULT_CATALOG, DEFAULT_SCHEMA, ALBUMS_TABLE)) { + assertKeysAlbumsSongs(rs); + } + } + } + + @Test + public void testGetImportedKeys() throws SQLException { + try (Connection connection = createConnection()) { + try (ResultSet rs = + connection.getMetaData().getImportedKeys(DEFAULT_CATALOG, DEFAULT_SCHEMA, ALBUMS_TABLE)) { + assertKeysSingersAlbums(rs); + } + try (ResultSet rs = + connection.getMetaData().getImportedKeys(DEFAULT_CATALOG, DEFAULT_SCHEMA, SONGS_TABLE)) { + assertKeysAlbumsSongs(rs); + } + } + } + + private void assertKeysSingersAlbums(ResultSet rs) throws SQLException { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("PKTABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("PKTABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("PKTABLE_NAME"), is(equalTo(SINGERS_TABLE))); + assertThat(rs.getString("PKCOLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getString("FKTABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("FKTABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("FKTABLE_NAME"), is(equalTo(ALBUMS_TABLE))); + assertThat(rs.getString("FKCOLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getShort("KEY_SEQ"), is(equalTo((short) 1))); + assertThat(rs.getInt("UPDATE_RULE"), is(equalTo(DatabaseMetaData.importedKeyRestrict))); + assertThat(rs.getInt("DELETE_RULE"), is(equalTo(DatabaseMetaData.importedKeyCascade))); + assertThat(rs.getString("FK_NAME"), is(nullValue())); + assertThat(rs.getString("PK_NAME"), is(equalTo("PRIMARY_KEY"))); + assertThat(rs.getInt("DEFERRABILITY"), is(equalTo(DatabaseMetaData.importedKeyNotDeferrable))); + assertThat(rs.next(), is(false)); + } + + private void assertKeysAlbumsSongs(ResultSet rs) throws SQLException { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("PKTABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("PKTABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("PKTABLE_NAME"), is(equalTo(ALBUMS_TABLE))); + assertThat(rs.getString("PKCOLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getString("FKTABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("FKTABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("FKTABLE_NAME"), is(equalTo(SONGS_TABLE))); + assertThat(rs.getString("FKCOLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getShort("KEY_SEQ"), is(equalTo((short) 1))); + assertThat(rs.getInt("UPDATE_RULE"), is(equalTo(DatabaseMetaData.importedKeyRestrict))); + assertThat(rs.getInt("DELETE_RULE"), is(equalTo(DatabaseMetaData.importedKeyCascade))); + assertThat(rs.getString("FK_NAME"), is(nullValue())); + assertThat(rs.getString("PK_NAME"), is(equalTo("PRIMARY_KEY"))); + assertThat(rs.getInt("DEFERRABILITY"), is(equalTo(DatabaseMetaData.importedKeyNotDeferrable))); + + assertThat(rs.next(), is(true)); + assertThat(rs.getString("PKTABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("PKTABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("PKTABLE_NAME"), is(equalTo(ALBUMS_TABLE))); + assertThat(rs.getString("PKCOLUMN_NAME"), is(equalTo("AlbumId"))); + assertThat(rs.getString("FKTABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("FKTABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("FKTABLE_NAME"), is(equalTo(SONGS_TABLE))); + assertThat(rs.getString("FKCOLUMN_NAME"), is(equalTo("AlbumId"))); + assertThat(rs.getShort("KEY_SEQ"), is(equalTo((short) 2))); + assertThat(rs.getInt("UPDATE_RULE"), is(equalTo(DatabaseMetaData.importedKeyRestrict))); + assertThat(rs.getInt("DELETE_RULE"), is(equalTo(DatabaseMetaData.importedKeyCascade))); + assertThat(rs.getString("FK_NAME"), is(nullValue())); + assertThat(rs.getString("PK_NAME"), is(equalTo("PRIMARY_KEY"))); + assertThat(rs.getInt("DEFERRABILITY"), is(equalTo(DatabaseMetaData.importedKeyNotDeferrable))); + assertThat(rs.next(), is(false)); + } + + @Test + public void testGetPrimaryKeys() throws SQLException { + try (Connection connection = createConnection()) { + try (ResultSet rs = + connection.getMetaData().getPrimaryKeys(DEFAULT_CATALOG, DEFAULT_SCHEMA, SINGERS_TABLE)) { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("TABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("TABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("TABLE_NAME"), is(equalTo(SINGERS_TABLE))); + assertThat(rs.getString("COLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getInt("KEY_SEQ"), is(equalTo(1))); + assertThat(rs.getString("PK_NAME"), is(equalTo("PRIMARY_KEY"))); + assertThat(rs.next(), is(false)); + } + try (ResultSet rs = + connection.getMetaData().getPrimaryKeys(DEFAULT_CATALOG, DEFAULT_SCHEMA, ALBUMS_TABLE)) { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("TABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("TABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("TABLE_NAME"), is(equalTo(ALBUMS_TABLE))); + assertThat(rs.getString("COLUMN_NAME"), is(equalTo("SingerId"))); + assertThat(rs.getInt("KEY_SEQ"), is(equalTo(1))); + assertThat(rs.getString("PK_NAME"), is(equalTo("PRIMARY_KEY"))); + assertThat(rs.next(), is(true)); + assertThat(rs.getString("TABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("TABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("TABLE_NAME"), is(equalTo(ALBUMS_TABLE))); + assertThat(rs.getString("COLUMN_NAME"), is(equalTo("AlbumId"))); + assertThat(rs.getInt("KEY_SEQ"), is(equalTo(2))); + assertThat(rs.getString("PK_NAME"), is(equalTo("PRIMARY_KEY"))); + assertThat(rs.next(), is(false)); + } + } + } + + @Test + public void testGetSchemas() throws SQLException { + try (Connection connection = createConnection()) { + try (ResultSet rs = connection.getMetaData().getSchemas()) { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("TABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("TABLE_CATALOG"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.next(), is(true)); + assertThat(rs.getString("TABLE_SCHEM"), is(equalTo("INFORMATION_SCHEMA"))); + assertThat(rs.getString("TABLE_CATALOG"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.next(), is(true)); + assertThat(rs.getString("TABLE_SCHEM"), is(equalTo("SPANNER_SYS"))); + assertThat(rs.getString("TABLE_CATALOG"), is(equalTo(DEFAULT_CATALOG))); + } + } + } + + private static final class Table { + private final String name; + + private Table(String name) { + this.name = name; + } + } + + private static final List EXPECTED_TABLES = + Arrays.asList( + new Table("Albums"), + new Table("Concerts"), + new Table("Singers"), + new Table("Songs"), + new Table("TableWithAllColumnTypes")); + + @Test + public void testGetTables() throws SQLException { + try (Connection connection = createConnection()) { + try (ResultSet rs = + connection.getMetaData().getTables(DEFAULT_CATALOG, DEFAULT_SCHEMA, null, null)) { + for (Table table : EXPECTED_TABLES) { + assertThat(rs.next(), is(true)); + assertThat(rs.getString("TABLE_CAT"), is(equalTo(DEFAULT_CATALOG))); + assertThat(rs.getString("TABLE_SCHEM"), is(equalTo(DEFAULT_SCHEMA))); + assertThat(rs.getString("TABLE_NAME"), is(equalTo(table.name))); + assertThat(rs.getString("TABLE_TYPE"), is(equalTo("TABLE"))); + assertThat(rs.getString("REMARKS"), is(nullValue())); + assertThat(rs.getString("TYPE_CAT"), is(nullValue())); + assertThat(rs.getString("TYPE_SCHEM"), is(nullValue())); + assertThat(rs.getString("TYPE_NAME"), is(nullValue())); + assertThat(rs.getString("SELF_REFERENCING_COL_NAME"), is(nullValue())); + assertThat(rs.getString("REF_GENERATION"), is(nullValue())); + } + assertThat(rs.next(), is(false)); + } + } + } +} diff --git a/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Albums.txt b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Albums.txt new file mode 100644 index 000000000000..0cf7eafedf85 --- /dev/null +++ b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Albums.txt @@ -0,0 +1,60 @@ +(1,1,"Album 1",980045); +(2,2,"Album 2",667788); +(3,3,"Album 3",908791); +(4,4,"Album 4",690335); +(5,5,"Album 5",133041); +(6,6,"Album 6",505292); +(7,7,"Album 7",91969); +(8,8,"Album 8",289965); +(9,9,"Album 9",78176); +(10,10,"Album 10",485664); +(11,11,"Album 11",972680); +(12,12,"Album 12",893680); +(13,13,"Album 13",892138); +(14,14,"Album 14",449562); +(15,15,"Album 15",150968); +(16,16,"Album 16",580377); +(17,17,"Album 17",763081); +(18,18,"Album 18",203427); +(19,19,"Album 19",995368); +(20,20,"Album 20",29900); +(21,21,"Album 21",723728); +(22,22,"Album 22",540582); +(23,23,"Album 23",784245); +(24,24,"Album 24",614788); +(25,25,"Album 25",275649); +(26,26,"Album 26",970898); +(27,27,"Album 27",409289); +(28,28,"Album 28",766560); +(29,29,"Album 29",32414); +(30,30,"Album 30",457957); +(1,31,"Album 31",52546); +(2,32,"Album 32",412424); +(3,33,"Album 33",568496); +(4,34,"Album 34",353491); +(5,35,"Album 35",489951); +(6,36,"Album 36",75938); +(7,37,"Album 37",460461); +(8,38,"Album 38",642042); +(9,39,"Album 39",282872); +(10,40,"Album 40",521496); +(11,41,"Album 41",98126); +(12,42,"Album 42",535113); +(13,43,"Album 43",957625); +(14,44,"Album 44",667630); +(15,45,"Album 45",236968); +(16,46,"Album 46",445647); +(17,47,"Album 47",446396); +(18,48,"Album 48",852859); +(19,49,"Album 49",404105); +(20,50,"Album 50",384439); +(21,51,"Album 51",440468); +(22,52,"Album 52",455384); +(23,53,"Album 53",210756); +(24,54,"Album 54",849113); +(25,55,"Album 55",63969); +(26,56,"Album 56",277122); +(27,57,"Album 57",350063); +(28,58,"Album 58",359473); +(29,59,"Album 59",209825); +(30,60,"Album 60",84543); diff --git a/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Concerts.txt b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Concerts.txt new file mode 100644 index 000000000000..2e53d92ccafc --- /dev/null +++ b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Concerts.txt @@ -0,0 +1,100 @@ +(1,1,DATE '2003-06-19',TIMESTAMP '2003-06-19T12:30:05Z',TIMESTAMP '2003-06-19T18:57:15Z',[11,93,140,923]); +(2,18,DATE '2004-01-25',TIMESTAMP '2004-01-25T14:58:28Z',TIMESTAMP '2004-01-26T01:10:52Z',[18,51,101,812]); +(3,21,DATE '2005-03-15',TIMESTAMP '2005-03-15T18:14:50Z',TIMESTAMP '2005-03-16T02:21:28Z',[23,26,107,721]); +(4,16,DATE '2009-05-09',TIMESTAMP '2009-05-09T05:22:34Z',TIMESTAMP '2009-05-09T15:28:28Z',[18,70,150,297]); +(5,11,DATE '2001-01-07',TIMESTAMP '2001-01-07T18:37:33Z',TIMESTAMP '2001-01-07T21:22:17Z',[20,55,185,672]); +(6,25,DATE '2015-11-19',TIMESTAMP '2015-11-19T22:47:42Z',TIMESTAMP '2015-11-20T02:54:01Z',[12,73,150,833]); +(7,26,DATE '2012-10-06',TIMESTAMP '2012-10-06T10:58:43Z',TIMESTAMP '2012-10-06T15:35:40Z',[8,83,199,625]); +(8,8,DATE '2001-09-26',TIMESTAMP '2001-09-26T06:41:20Z',TIMESTAMP '2001-09-26T16:38:35Z',[19,87,192,912]); +(9,27,DATE '2016-11-24',TIMESTAMP '2016-11-24T20:00:48Z',TIMESTAMP '2016-11-24T23:03:07Z',[20,84,134,885]); +(10,30,DATE '2017-05-05',TIMESTAMP '2017-05-05T12:44:05Z',TIMESTAMP '2017-05-05T23:06:55Z',[17,44,177,997]); +(11,7,DATE '2018-06-07',TIMESTAMP '2018-06-07T07:03:11Z',TIMESTAMP '2018-06-07T08:21:41Z',[10,73,182,287]); +(12,22,DATE '2009-01-07',TIMESTAMP '2009-01-07T23:22:11Z',TIMESTAMP '2009-01-08T08:34:18Z',[22,59,150,983]); +(13,16,DATE '2013-06-28',TIMESTAMP '2013-06-28T14:59:25Z',TIMESTAMP '2013-06-28T22:32:11Z',[17,41,129,433]); +(14,11,DATE '2005-08-19',TIMESTAMP '2005-08-19T01:11:28Z',TIMESTAMP '2005-08-19T01:30:30Z',[18,49,110,590]); +(15,18,DATE '2001-11-26',TIMESTAMP '2001-11-26T15:55:31Z',TIMESTAMP '2001-11-26T20:52:13Z',[18,51,132,854]); +(16,26,DATE '2009-01-04',TIMESTAMP '2009-01-04T03:09:11Z',TIMESTAMP '2009-01-04T12:02:14Z',[5,37,146,344]); +(17,20,DATE '2012-09-28',TIMESTAMP '2012-09-28T00:45:00Z',TIMESTAMP '2012-09-28T02:10:39Z',[15,89,185,480]); +(18,24,DATE '2004-09-06',TIMESTAMP '2004-09-06T09:55:40Z',TIMESTAMP '2004-09-06T18:10:32Z',[23,51,113,244]); +(19,21,DATE '2010-11-18',TIMESTAMP '2010-11-18T09:59:17Z',TIMESTAMP '2010-11-18T17:13:12Z',[14,69,164,218]); +(20,29,DATE '2010-12-24',TIMESTAMP '2010-12-24T04:21:25Z',TIMESTAMP '2010-12-24T06:10:08Z',[20,34,166,573]); +(21,3,DATE '2000-05-14',TIMESTAMP '2000-05-14T13:49:08Z',TIMESTAMP '2000-05-14T14:39:25Z',[21,67,136,779]); +(22,18,DATE '2000-05-14',TIMESTAMP '2000-05-14T00:23:23Z',TIMESTAMP '2000-05-14T01:20:04Z',[21,91,111,749]); +(23,26,DATE '2015-05-04',TIMESTAMP '2015-05-04T10:39:46Z',TIMESTAMP '2015-05-04T19:21:45Z',[24,91,128,559]); +(24,16,DATE '2012-08-18',TIMESTAMP '2012-08-18T08:47:12Z',TIMESTAMP '2012-08-18T09:35:03Z',[19,44,136,281]); +(25,4,DATE '2000-03-16',TIMESTAMP '2000-03-16T10:15:15Z',TIMESTAMP '2000-03-16T12:29:53Z',[22,28,111,948]); +(26,4,DATE '2002-11-20',TIMESTAMP '2002-11-20T16:28:19Z',TIMESTAMP '2002-11-20T17:56:10Z',[7,70,141,517]); +(27,23,DATE '2000-08-09',TIMESTAMP '2000-08-09T04:30:51Z',TIMESTAMP '2000-08-09T15:27:15Z',[13,98,156,230]); +(28,16,DATE '2000-10-15',TIMESTAMP '2000-10-15T04:12:39Z',TIMESTAMP '2000-10-15T14:07:05Z',[8,39,160,455]); +(29,22,DATE '2003-03-25',TIMESTAMP '2003-03-25T17:21:56Z',TIMESTAMP '2003-03-25T19:18:25Z',[17,70,148,681]); +(30,15,DATE '2008-11-11',TIMESTAMP '2008-11-11T22:56:07Z',TIMESTAMP '2008-11-12T09:33:48Z',[24,47,175,901]); +(31,7,DATE '2018-05-22',TIMESTAMP '2018-05-22T20:54:59Z',TIMESTAMP '2018-05-23T02:52:28Z',[13,34,177,804]); +(32,30,DATE '2000-04-03',TIMESTAMP '2000-04-03T13:54:10Z',TIMESTAMP '2000-04-03T15:57:02Z',[16,48,137,249]); +(33,23,DATE '2003-12-24',TIMESTAMP '2003-12-24T22:22:00Z',TIMESTAMP '2003-12-25T06:09:40Z',[15,36,131,922]); +(34,12,DATE '2012-06-23',TIMESTAMP '2012-06-23T18:15:30Z',TIMESTAMP '2012-06-24T03:46:17Z',[25,31,160,564]); +(35,5,DATE '2017-12-15',TIMESTAMP '2017-12-15T09:43:38Z',TIMESTAMP '2017-12-15T17:18:28Z',[22,31,177,868]); +(36,20,DATE '2012-12-21',TIMESTAMP '2012-12-21T08:28:14Z',TIMESTAMP '2012-12-21T11:34:59Z',[25,62,143,437]); +(37,19,DATE '2014-07-07',TIMESTAMP '2014-07-07T22:01:35Z',TIMESTAMP '2014-07-08T04:39:37Z',[8,31,184,784]); +(38,15,DATE '2012-07-26',TIMESTAMP '2012-07-26T09:45:35Z',TIMESTAMP '2012-07-26T13:03:53Z',[19,79,140,908]); +(39,24,DATE '2014-03-19',TIMESTAMP '2014-03-19T07:52:25Z',TIMESTAMP '2014-03-19T11:47:01Z',[11,90,141,978]); +(40,4,DATE '2015-08-26',TIMESTAMP '2015-08-26T20:51:25Z',TIMESTAMP '2015-08-27T07:06:46Z',[15,94,195,510]); +(41,24,DATE '2016-04-11',TIMESTAMP '2016-04-11T08:59:07Z',TIMESTAMP '2016-04-11T13:23:30Z',[15,51,173,233]); +(42,18,DATE '2005-03-19',TIMESTAMP '2005-03-19T15:45:04Z',TIMESTAMP '2005-03-19T16:28:42Z',[19,31,188,546]); +(43,7,DATE '2001-01-04',TIMESTAMP '2001-01-04T11:02:16Z',TIMESTAMP '2001-01-04T11:32:21Z',[20,37,133,958]); +(44,5,DATE '2015-12-24',TIMESTAMP '2015-12-24T06:49:48Z',TIMESTAMP '2015-12-24T14:46:46Z',[12,61,175,233]); +(45,12,DATE '2011-08-24',TIMESTAMP '2011-08-24T03:45:46Z',TIMESTAMP '2011-08-24T06:13:10Z',[18,38,169,913]); +(46,16,DATE '2017-03-04',TIMESTAMP '2017-03-04T04:01:04Z',TIMESTAMP '2017-03-04T13:44:38Z',[21,79,119,839]); +(47,18,DATE '2009-05-19',TIMESTAMP '2009-05-19T23:10:52Z',TIMESTAMP '2009-05-20T04:02:01Z',[25,79,151,357]); +(48,22,DATE '2003-10-03',TIMESTAMP '2003-10-03T14:10:24Z',TIMESTAMP '2003-10-03T17:35:09Z',[18,60,140,450]); +(49,9,DATE '2003-03-07',TIMESTAMP '2003-03-07T22:09:59Z',TIMESTAMP '2003-03-08T08:28:29Z',[22,41,122,726]); +(50,9,DATE '2015-07-12',TIMESTAMP '2015-07-12T07:43:51Z',TIMESTAMP '2015-07-12T12:45:20Z',[18,67,126,474]); +(51,12,DATE '2014-11-05',TIMESTAMP '2014-11-05T19:03:00Z',TIMESTAMP '2014-11-06T05:27:07Z',[19,43,125,865]); +(52,6,DATE '2016-07-25',TIMESTAMP '2016-07-25T14:39:28Z',TIMESTAMP '2016-07-26T00:36:03Z',[6,74,192,344]); +(53,13,DATE '2005-08-02',TIMESTAMP '2005-08-02T16:06:47Z',TIMESTAMP '2005-08-02T17:13:41Z',[5,52,192,977]); +(54,18,DATE '2010-01-25',TIMESTAMP '2010-01-25T07:34:54Z',TIMESTAMP '2010-01-25T16:29:11Z',[24,85,181,304]); +(55,14,DATE '2012-05-20',TIMESTAMP '2012-05-20T13:15:12Z',TIMESTAMP '2012-05-20T17:40:09Z',[15,43,104,665]); +(56,3,DATE '2013-09-08',TIMESTAMP '2013-09-08T19:53:42Z',TIMESTAMP '2013-09-08T22:32:52Z',[14,81,129,354]); +(57,27,DATE '2003-07-18',TIMESTAMP '2003-07-18T23:11:24Z',TIMESTAMP '2003-07-19T03:29:46Z',[21,85,188,854]); +(58,27,DATE '2001-04-10',TIMESTAMP '2001-04-10T08:36:49Z',TIMESTAMP '2001-04-10T16:17:57Z',[17,86,161,438]); +(59,2,DATE '2002-07-02',TIMESTAMP '2002-07-02T17:32:20Z',TIMESTAMP '2002-07-03T01:59:33Z',[23,59,164,357]); +(60,28,DATE '2000-11-24',TIMESTAMP '2000-11-24T12:53:25Z',TIMESTAMP '2000-11-24T22:37:53Z',[22,47,161,739]); +(61,12,DATE '2017-07-04',TIMESTAMP '2017-07-04T21:02:01Z',TIMESTAMP '2017-07-05T03:57:29Z',[16,88,179,478]); +(62,3,DATE '2015-10-07',TIMESTAMP '2015-10-07T17:58:42Z',TIMESTAMP '2015-10-07T21:04:38Z',[21,44,155,381]); +(63,23,DATE '2005-05-03',TIMESTAMP '2005-05-03T15:08:10Z',TIMESTAMP '2005-05-03T20:58:30Z',[20,43,111,824]); +(64,24,DATE '2012-12-09',TIMESTAMP '2012-12-09T02:52:09Z',TIMESTAMP '2012-12-09T08:01:11Z',[18,87,106,997]); +(65,30,DATE '2004-03-01',TIMESTAMP '2004-03-01T07:09:06Z',TIMESTAMP '2004-03-01T07:49:32Z',[14,26,195,895]); +(66,24,DATE '2007-05-19',TIMESTAMP '2007-05-19T10:20:57Z',TIMESTAMP '2007-05-19T15:21:09Z',[18,54,179,238]); +(67,16,DATE '2016-01-06',TIMESTAMP '2016-01-06T21:32:20Z',TIMESTAMP '2016-01-07T02:31:32Z',[20,61,120,652]); +(68,2,DATE '2007-10-26',TIMESTAMP '2007-10-26T03:37:22Z',TIMESTAMP '2007-10-26T10:02:36Z',[11,65,151,537]); +(69,2,DATE '2018-08-11',TIMESTAMP '2018-08-11T01:33:38Z',TIMESTAMP '2018-08-11T07:39:21Z',[10,98,105,621]); +(70,23,DATE '2012-07-06',TIMESTAMP '2012-07-06T01:02:23Z',TIMESTAMP '2012-07-06T05:04:16Z',[14,44,172,953]); +(71,7,DATE '2006-01-24',TIMESTAMP '2006-01-24T15:32:10Z',TIMESTAMP '2006-01-24T17:40:43Z',[9,58,150,713]); +(72,8,DATE '2002-11-06',TIMESTAMP '2002-11-06T05:58:03Z',TIMESTAMP '2002-11-06T07:43:24Z',[25,36,193,213]); +(73,10,DATE '2003-11-24',TIMESTAMP '2003-11-24T17:39:10Z',TIMESTAMP '2003-11-25T03:17:36Z',[8,55,200,352]); +(74,16,DATE '2007-11-03',TIMESTAMP '2007-11-03T05:49:12Z',TIMESTAMP '2007-11-03T16:34:16Z',[21,50,114,820]); +(75,4,DATE '2009-05-06',TIMESTAMP '2009-05-06T18:52:07Z',TIMESTAMP '2009-05-06T21:10:02Z',[16,42,101,281]); +(76,1,DATE '2012-12-03',TIMESTAMP '2012-12-03T06:01:05Z',TIMESTAMP '2012-12-03T06:45:00Z',[24,60,140,292]); +(77,1,DATE '2016-11-26',TIMESTAMP '2016-11-26T01:19:27Z',TIMESTAMP '2016-11-26T07:20:17Z',[19,31,123,214]); +(78,9,DATE '2018-05-21',TIMESTAMP '2018-05-21T00:14:43Z',TIMESTAMP '2018-05-21T08:43:35Z',[7,28,115,634]); +(79,14,DATE '2013-11-20',TIMESTAMP '2013-11-20T08:54:47Z',TIMESTAMP '2013-11-20T10:44:54Z',[18,39,155,328]); +(80,17,DATE '2015-10-11',TIMESTAMP '2015-10-11T23:41:17Z',TIMESTAMP '2015-10-12T02:42:48Z',[16,94,102,894]); +(81,23,DATE '2011-08-07',TIMESTAMP '2011-08-07T19:33:01Z',TIMESTAMP '2011-08-07T21:51:53Z',[23,90,134,370]); +(82,7,DATE '2010-04-10',TIMESTAMP '2010-04-10T13:22:08Z',TIMESTAMP '2010-04-10T17:59:08Z',[18,68,121,303]); +(83,27,DATE '2001-07-08',TIMESTAMP '2001-07-08T20:19:54Z',TIMESTAMP '2001-07-08T22:46:15Z',[18,86,148,746]); +(84,6,DATE '2017-09-02',TIMESTAMP '2017-09-02T10:29:03Z',TIMESTAMP '2017-09-02T13:06:41Z',[12,85,138,471]); +(85,1,DATE '2013-11-02',TIMESTAMP '2013-11-02T04:01:03Z',TIMESTAMP '2013-11-02T14:08:47Z',[9,65,111,583]); +(86,22,DATE '2004-04-03',TIMESTAMP '2004-04-03T19:13:48Z',TIMESTAMP '2004-04-04T05:59:31Z',[19,72,105,908]); +(87,2,DATE '2012-02-26',TIMESTAMP '2012-02-26T22:52:21Z',TIMESTAMP '2012-02-27T02:55:24Z',[16,75,129,740]); +(88,9,DATE '2017-09-17',TIMESTAMP '2017-09-17T11:28:49Z',TIMESTAMP '2017-09-17T12:13:03Z',[24,77,182,755]); +(89,11,DATE '2011-03-28',TIMESTAMP '2011-03-28T13:05:23Z',TIMESTAMP '2011-03-28T16:32:29Z',[22,96,174,731]); +(90,21,DATE '2006-12-12',TIMESTAMP '2006-12-12T20:44:10Z',TIMESTAMP '2006-12-12T22:10:34Z',[15,68,166,616]); +(91,27,DATE '2010-08-18',TIMESTAMP '2010-08-18T05:49:35Z',TIMESTAMP '2010-08-18T12:58:36Z',[12,84,157,369]); +(92,2,DATE '2003-02-03',TIMESTAMP '2003-02-03T11:19:43Z',TIMESTAMP '2003-02-03T22:10:42Z',[25,59,140,939]); +(93,5,DATE '2016-01-04',TIMESTAMP '2016-01-04T08:10:26Z',TIMESTAMP '2016-01-04T13:08:30Z',[5,90,163,272]); +(94,3,DATE '2018-04-20',TIMESTAMP '2018-04-20T07:19:52Z',TIMESTAMP '2018-04-20T17:41:01Z',[5,59,109,854]); +(95,19,DATE '2016-10-09',TIMESTAMP '2016-10-09T17:02:59Z',TIMESTAMP '2016-10-09T17:37:27Z',[6,35,176,442]); +(96,9,DATE '2007-06-12',TIMESTAMP '2007-06-12T16:50:12Z',TIMESTAMP '2007-06-12T19:27:30Z',[7,49,169,729]); +(97,29,DATE '2012-11-25',TIMESTAMP '2012-11-25T20:40:30Z',TIMESTAMP '2012-11-25T21:29:50Z',[12,35,128,269]); +(98,11,DATE '2013-10-22',TIMESTAMP '2013-10-22T03:26:36Z',TIMESTAMP '2013-10-22T06:42:42Z',[14,49,148,726]); +(99,10,DATE '2006-05-10',TIMESTAMP '2006-05-10T05:49:43Z',TIMESTAMP '2006-05-10T07:12:18Z',[5,67,131,360]); +(100,18,DATE '2015-02-15',TIMESTAMP '2015-02-15T01:18:05Z',TIMESTAMP '2015-02-15T04:19:27Z',[11,38,127,909]); diff --git a/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql new file mode 100644 index 000000000000..896b8b9cbf2e --- /dev/null +++ b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/CreateMusicTables.sql @@ -0,0 +1,88 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +START BATCH DDL; + +CREATE TABLE Singers ( + SingerId INT64 NOT NULL, + FirstName STRING(1024), + LastName STRING(1024), + SingerInfo BYTES(MAX), + BirthDate DATE +) PRIMARY KEY(SingerId); + +CREATE INDEX SingersByFirstLastName ON Singers(FirstName, LastName); + +CREATE TABLE Albums ( + SingerId INT64 NOT NULL, + AlbumId INT64 NOT NULL, + AlbumTitle STRING(MAX), + MarketingBudget INT64 +) PRIMARY KEY(SingerId, AlbumId), + INTERLEAVE IN PARENT Singers ON DELETE CASCADE; + +CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle); + +CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget); + +CREATE TABLE Songs ( + SingerId INT64 NOT NULL, + AlbumId INT64 NOT NULL, + TrackId INT64 NOT NULL, + SongName STRING(MAX), + Duration INT64, + SongGenre STRING(25) +) PRIMARY KEY(SingerId, AlbumId, TrackId), + INTERLEAVE IN PARENT Albums ON DELETE CASCADE; + +CREATE UNIQUE INDEX SongsBySingerAlbumSongNameDesc ON Songs(SingerId, AlbumId, SongName DESC), INTERLEAVE IN Albums; + +CREATE INDEX SongsBySongName ON Songs(SongName); + +CREATE TABLE Concerts ( + VenueId INT64 NOT NULL, + SingerId INT64 NOT NULL, + ConcertDate DATE NOT NULL, + BeginTime TIMESTAMP, + EndTime TIMESTAMP, + TicketPrices ARRAY +) PRIMARY KEY(VenueId, SingerId, ConcertDate); + +CREATE TABLE TableWithAllColumnTypes ( + ColInt64 INT64 NOT NULL, + ColFloat64 FLOAT64 NOT NULL, + ColBool BOOL NOT NULL, + ColString STRING(100) NOT NULL, + ColStringMax STRING(MAX) NOT NULL, + ColBytes BYTES(100) NOT NULL, + ColBytesMax BYTES(MAX) NOT NULL, + ColDate DATE NOT NULL, + ColTimestamp TIMESTAMP NOT NULL, + ColCommitTS TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true), + + ColInt64Array ARRAY, + ColFloat64Array ARRAY, + ColBoolArray ARRAY, + ColStringArray ARRAY, + ColStringMaxArray ARRAY, + ColBytesArray ARRAY, + ColBytesMaxArray ARRAY, + ColDateArray ARRAY, + ColTimestampArray ARRAY +) PRIMARY KEY (ColInt64) +; + +RUN BATCH; \ No newline at end of file diff --git a/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Singers.txt b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Singers.txt new file mode 100644 index 000000000000..939873de17e6 --- /dev/null +++ b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Singers.txt @@ -0,0 +1,30 @@ +(1,'First 1','A Last 1',FROM_BASE64('5KckBUgBLuj+nlmI0WXBEA0TCSeOK8x/B35kzIIHC01YrF8CNTjRT8hVQ4T0NkVGZjz96bF68aBu4QQ9VlZ/EhX22++vPADslt5YdqFzJjdxhlbGCufKIbrCVn1Po5u+j46SaV1TAHffIGfsAY0lhHJNmRS2P4p2/CGWJas4bzEo/Fn/JxuKF/et1LXgmlShOiE+LbnysvjbDt7GcbL7mA=='),DATE '1906-04-28'); +(2,'First 2','ALast 2',FROM_BASE64('1uLrsGLZS2BUfLGU0CLO9lgDau+TfX/XYK0RyEKvwgWdm3f0mbt4vbLziTn7iY/fM5OeGoeNZneQFWJoAY1XimD4aFDcQlIkkUxaXHFbOik4KNc/OiQMNaLghXtyaTP+UEaHX7o3w7iCp/wjzljEsnaYZxYTKY8Nm6JfKSwXvP1xHXi0KpaCdLf/V/8Vg102CNqqR4fgFwLy3/5QLxbGAg=='),DATE '1922-11-17'); +(3,'First 3','A Last 3',FROM_BASE64('Mc3i5IYbAWfrpZbCa8R2IXsK2DM0zW8mCx58tMClAPvIKktEIOh/HEl3l6qnJ8FPqp17E+PYZsplE9Hxu0LV9N1inR4TO+my3h9Vq72BA6hoSHmo2mxhRSF+iUL3TrC+MalcKPZuKnmI48RRfKoIrwP0Am1iqXWhhpOMo+zHDVL40FsbDIDW7zezTjyxPmwryF9I5vF+t1j8B5NKPA8Gnw=='),DATE '1935-11-08'); +(4,'First 4','A Last 4',FROM_BASE64('FyMiT7GA1pQzfrf/SnGN4iWMizOf+M59fVauKUqP84oGBSkI4F746K+grXinm3txsfPGu23J4OYtZt9FUxQssbaVykkhGBX9+nuiV+RYESLRj6uHT6mZH5g2BOR9L6cWRclks6GBFzIwjFu7JqeofmiJt/R1BwJMFH+07rDRPgi/9oS/DK6/ipC77dpomAuW48d9IbUNofd9/tc89mJbEg=='),DATE '1945-03-23'); +(5,'First 5','A Last 5',FROM_BASE64('BfpuifEdiau23UcEnnaONRxA9V0UH2uMhv3gZG/o0tnh6IR306luK4UL12RSbDVzGgpmDa7tLNC2pZzAlDMJmO4h5F73GzvSa8mVFrJrnqeNy9ECLM1sTIH1HYaF9jZXAYcSo14PK4+xygz1tsENs3jfKfWNuNBEi463x+fL8RcVxVMclSyOEBQaTnLD0pnzji99NkwMBQiwIHN5bl6XLA=='),DATE '1953-06-03'); +(6,'First 6','A Last 6',FROM_BASE64('Hdcj53Vc1yNAuCAP7H8YGadmbdOFGg1nfSpfVuiWWgx2OGR8KQIzTTHny8FsYnmyEBmJQZQMv1m1HU0EFmq5b4id0TmBUMfPzgWF5LFAJPgziAnbprYiKhwDaiRxrmL4Q0kVozeT1vniS3T6HioC20pjzmN8aF1vxzrLBr3IC9e8zHt9+Vla52lNoG/8atlWaSPx1agj5CyPncO7QTdPuw=='),DATE '1956-02-07'); +(7,'First 7','B Last 7',FROM_BASE64('FqOl3vAVSMU6NGINNZjVbYQRgmb95stb6CHfMYEec32ngI8XCS2687kGHfZ16innPuGau5Z/JSchkE8JYMaSITQ/7+B5eh40vZI1CKuLyXKfZ4BR8VkBVqxXyAsAShboxlt+kMHZEvWMY0iXcl9jCB3V+GNbPMHlCxz46CAnjp9ArnwwojRZgUDK9PonTr9N4GBEmO04DLip30LyvCpW/g=='),DATE '1969-05-26'); +(8,'First 8','B Last 8',FROM_BASE64('PQLBMSGGZXeSI7FLot4EcX3JfPTafiu5yeisMBQvuQmDW7kQC/mU9Oh+UhAbovDIx0dZGJ5dIhoAXZEzZPxGgBMWvbPNFmTB7+Q5Hd3/1uxL81XDZs6FlVCpGCKB0KER4WxtKbVqeQgltCeEvhYsTeLRNJdka33uq06lSZFyJXKX9bQyRLCZlGQRy2VHG1+sqjAX0FfcLf6RNEG64sDwOA=='),DATE '1978-11-08'); +(9,'First 9','B Last 9',FROM_BASE64('Nk2ZqJZSCFKKY+NMSq0WGVnNDS/BDHDEyb/bbJFxC/TqRPi+8DQ1csNlqvULW0pDEE6IygIRQR2lv5kT43E4tal4PKXx/z5LTeL9xiJ+qOHwLqAJrZK3V4aQFCNXT6t95lsxZLcjaP6fzNWlGwuN++iR7hpYJLI3WQSlaPL2GuHI9dLGS9ZUPR9KhDor72IURkOHU9Dt1eWfYouPsuVnrA=='),DATE '1987-07-04'); +(10,'First 10','B Last 10',FROM_BASE64('E0rzdg+IDhd1N9S/Nh11Yr6Za+xZlfCOQr0TrsxjFzRvO1ZnXjHGQPdWvT/LIJV+f7TXu0rYtk75fx7uPylxANNEYnLfD7v6UHB5Yful0TCweTFs9qH35BEd0jJl0ATb1ggUmsxXF0xZQpsRRnfycPbMY59w2APSX3hvgF2Xk7lvhHQaSbjnHOh4s78cqa2Atrjeds8KI/I4v+aVQIX9+Q=='),DATE '1993-07-06'); +(11,'First 11','C Last 11',FROM_BASE64('rO6MoGIcZJ+6zIPyMCt2td9ytNkSAn/LxWkrBKUGQs+Fk+Se43Ml7YsuRYhdcIeawAtySL35vZzb6Avl7bH/MyXrg4E0jdvjpEsi7KHiN4f0ky85purgyEg8tRASTi2zVsIM8c27DZenHOqRFl4KUaGRdQATOEoEIH3aHLVoACb0Y1m9JDTIDBcKST8nvTDzayQx1Ur4CO+ZqqG8ye99ww=='),DATE '1895-09-15'); +(12,'First 12','C Last 12',FROM_BASE64('ki4b0vB6EHp9qdm9lFrxplFPTnFCq9/BWwBLK1Jzz39K2q1rESpVXFIe2L2WzOKrunXo8e+p7+xlzBBKCwVIW6hQy0A+7kp7SwdZgWr2pXJqtSuo43fwfhf/A63zFaUYg3AkuNJNAtV/F3mOVudPeJ2xvfRfJ06uKY4MzsDhXAFW5Wsf1ypWMCke58U1VncvpuNOwzSb0El+hOreiQRX8g=='),DATE '1922-01-03'); +(13,'First 13','C Last 13',FROM_BASE64('KEx72v8CBibM16yet2U0Nsbt8KypF1ih18jLso5Q4AmFYUK7961GTYWj0YprWHxIxL/3qAXkm8jjtcRqEUmIXxW7kR0xC7sOcMYJsOSsy2m59YnDTlzDLlR1gynzNJVUhj+aKkUPMQfYV6Dw3UEx2Kik4NKDlGJQc9A0w3rfXjzRln8Ou3F+KYMuuoi/4jP4GEu1Pgyqy8jhQKiN0e9cjA=='),DATE '1930-08-03'); +(14,'First 14','C Last 14',FROM_BASE64('SdOTrssLh3vCqjtPNSqUvX5xrHs6/tpdlqgbp1jp9FseXhhJm+sq6FhgSMX+jm/grBUkUbGCNcWYthv3hdRMIapyZANENn/8CN0BxoVnvECGA9moThVIVghiSAiUNB+SyZg9XlmFRBaQcXpSWoZ1tIRTIuFRKpKaC2GYiOHVPLSQEUOBGc+sN4J0eCvM5aytanUGzn0o98yL73hbRXjwUw=='),DATE '1940-05-12'); +(15,'First 15','C Last 15',FROM_BASE64('NFgZNOzxoDSrAOPXtDIyUtetwm6eUN11YdjB7rIFfylx2SSTbhWZMuJoToE8xQz458BNaUJ8xPB+fJR2AQJL75eZdwJgSA7nnSiFcQgJxU7CEShlBT1ANNJvPujQ7cowRAo4joPfxoBSODuZcEc9WeXhJpEnlQtiGq7k+kzQ0oPgGaj0gLNwiC2zZwL5XCiet5qsRk4LSkUcX3OugpgeCg=='),DATE '1946-09-23'); +(16,'First 16','D Last 16',FROM_BASE64('mmXbRxEVEhiWeMGeuYOv6xGovovbq/qfevmWdMcGiqmCU1yzUrWKLvDhwzYZMbdscj7Tr5e4YyaXpIgpdMro3SApCyfhX5o/dsBlBNVmwLqg8DYbzAeApkaXeiStpAtKdQ8kZ1jezAFlhR/PioNsZjj1iAU4paFLG5F1i01spp3OOeJaD1mUTCSEO85rOAbQ8+B1N3vzz1Yc3E3mTQtxHg=='),DATE '1947-09-30'); +(17,'First 17','D Last 17',FROM_BASE64('zXIaISyrpPC/s0Yowmfdcbcavm6bGs95oBnWOHeTlXXk2n61Ug/GdG4gn5KxcXTfkqZAyzCBEnoaVcrwcp3HzEPUQeumXQn0dt2/oc5s0qfmGDo1+eOVy3tWMTdXv3vKmc4xXQ9bTMQE+MTtZDUknVCJ73zGUAMunFgzVnERLGBfOVaoLxcwC4HBrRtvtLlMboaCHirA1U5fF8xx81dK/g=='),DATE '1948-02-04'); +(18,'First 18','D Last 18',FROM_BASE64('mYZ5eW8+N/PFaDAmnIU77XX1jOZszdOXxblHbB0gKoJ6XOLYKcsmJKG8mjmUCQDYiG1b12xRQga6wprvLsciiyIwTCca6i4JL4RoVz+GqyDLmNSxHruz4xIB7XFIQ0q5SIeL7nob7llp7n+4+T9VYeoMDlFkG903WfjZNqsMRzpFYTT1C4ef+IlHOQSD5K3f/H/uWQ61PUebhSYe9hYQNg=='),DATE '1962-11-10'); +(19,'First 19','D Last 19',FROM_BASE64('/FqFHFjzF6yL/d3bKfSS9ZS1j8xkDlmF6gLpFf/MlC8idAt9ceLvr6oNEAKIdu0xqfLN9fKh9B7wQjAGUBKFLFlVzPIC2BBt7cCiiVVqgYwH3PIKiWL1LndLi1VRcNpy+gWLdgaFn+u4FxNotLDhdx9jUJOsDDPy9aBDSYmYOBajVUgN6jyfvG6egGnIhj+RNGxRkKfZ0isLOByT82v73w=='),DATE '1988-10-07'); +(20,'First 20','D Last 20',FROM_BASE64('3YII52xQjwk1RwhDPlbEKYWje92/04jIYhSJWa7LsLEt6qDxaFt1/1viQKAJWreCzgD0iC08CSJOQDLEmpuDPW5HZmWSnA0AuO46TGaYWtdQDFeJhgVzcldsAC7dMRid+SO1+sjvr/VfGCJP0XT3kWdE8mWNTdI74KrVm0CChj6XF7fLtjekbjZETrg7ySo8pmawVbTKrrZ5FIuNlkxI/Q=='),DATE '2000-02-29'); +(21,'First 21','D Last 21',FROM_BASE64('sKVHb3YTv4OPAB+77pjXln3omYqFy20LkBT/uP7PMSWlYaH+UpRdzOO52pDUh6BrMDjS3qgXU7irLoNA2NEma1QFzvVrLaa6yArnpZCyAEOw3OzpIQf2lJ7YqN8ZjwWEn8SztpMZBiJVXeZoYyYWnhkn9a+crIBOWMYI9ZfPUWk1xtvMX7I1QgHdSqPsLpT8iSnO42tjraGd5ulqkWrIRg=='),DATE '1886-08-09'); +(22,'First 22','E Last 22',FROM_BASE64('07GVEGBPEhQC8lELkxIGFhrQNspbl2NEGIrND5VXnUJFnuFctZaSpPovPHlYKtORcpGFsHTv3rSM6UUxTYFHzIUrxQJxNJ84KXjEXrlAN4tWkQOifh4icFc9FezQzQfsjf0KDjRatIFy8Q2jcSUfnhHbeZ1gpbsLIp8Ajioc7ptZG7Lnl1JyPmqKjQwQ+9WyE4uB0BGJTHI3xwzXQLm45A=='),DATE '1889-04-03'); +(23,'First 23','E Last 23',FROM_BASE64('tyGduCzcRQhWJXhDm5c9a8Mfpyyc1sKKk/OxSJFJ2numyNWuurKglMuDZSgdC9sH122eZdJU1uid7umiWYwhYYUC0JuYaYLNpYCnRuOL2FWVSN9jrJYX6AsNNpUDUfcKlJobFL/XJ+ulAr18Z/qtoWXDr4lx5TZAk05TTlFHJwRjIrybzrFYohhZZ20O4WtL3dryRKTgTgvVSElX0SZ8Tw=='),DATE '1892-01-21'); +(24,'First 24','E Last 24',FROM_BASE64('bXe6LecQB+BcWwzcE3b+JrH/20zrVIUXsH9AcBMduKoVIpCnrloUziiWbE1b2Te3/mD7ShKfD4RXSahJ7KgACA3CxS70yAa945NaqoX/aND7kGfFE6PEiS4pUrkJ10A1mRY2fP0J/Qn2tEyegtTF4b2BZuACQJy0qU8QyYrykaVK/+ExVI+MrvHA2LD062EDWPJrPgApCpPRMmtAV3KnTA=='),DATE '1898-02-21'); +(25,'First 25','Last 25',FROM_BASE64('82g7Ytc6/RBp/3vFxUG7JfAz9al82TRPlqBybWKBj/1pA26Pgv1UTxdDloQ24ovTmRZ3agPmaFEc/0ry820ozm8NmR340IwHRmO+jb2LQY4FGEMKFg7zDxAZpJXqITMZsFL1zO/EJ6VMnvZ90Udk2mywsnvv857PRCXJgx6vu4gn+oqUaRAQnSHq3pveu4/88FogqWoOotSzraD2RkW39Q=='),DATE '1911-12-15'); +(26,'First 26','Last 26',FROM_BASE64('KwbjBuHNQvzeWR2Ucf3v5dHAIO/b3/A0AlKxWI2qARDKuaXNuBooTCtdhIv5ZczOH5BbEKlaYkK3mr3GA5GClmwxsafbv3eE0LkV88T7KjfrKSkfatyTtcIWLIrw60B5hlMS5uxmj4X9nZfivj9boB4g3rqEdg/vgOsO9xdk/BKw6FMCuDO3PgDGEn89dOZmaB0PgadYNN3vqz8ZLgXWtg=='),DATE '1912-07-01'); +(27,'First 27','Last 27',FROM_BASE64('O3T43r6OjBwCWu925WlVnd6NLufFAken2Jk/QQBJOGQWsqc4dQsFhs/RSAC8iMZg32lfpfjMQPltRjmwqV7JleYRxL9e6co5WDj9cQk7AcL6wedgR5O/voPZIJ0aqkh5bZvijuxNIerbYhmYZEPOuzhgz9ayE7LgPkvO6WWNfhYuhnulnuDa3e2RsBNC7J1zuuf3DKHnL8SpaD0SMcZRuw=='),DATE '1939-05-17'); +(28,'First 28','Last 28',FROM_BASE64('xC71kYOpe6iZJd4DZnb11wBapa37lquOSW0JzuS15kW1xSG/Jxu0FXUIbFaBJ84hvFYQ3OSxr5HRxI0SBaFyUQhglUT3KTv/m8fEN/W+apBu4aUtlLcZPOTr1amaz30fu89J6pEoQOgmswSIr/0CtiaQ/ZHnuU2rZUXh7hTzBdygF30bAIq6yBGPpfb/MV66yagZtQO/q69sRmar70H/hg=='),DATE '1946-10-18'); +(29,'First 29','Last 29',FROM_BASE64('koHC6ZTUt89ksDORKlw5ep/zJCO0/LNo5A6yC5E8HEKOZpzX7xllDsIQuDmMQDn1HCHkpouKFmoTM24kWvfAs9B6yE7JccSFJbUU5s4Z/iLtYnnfKDzMEDDd/TyL6FxxS0McscfZ/TIc6ZFCArlJCbviqTSafPamrlD7tOJNxkCZae+dFIgnTCiTcwcjvkQeM5Ul6jDNoqIy5lrZdR6wJg=='),DATE '1956-12-23'); +(30,'First 30','Last 30',FROM_BASE64('WjdDzKHsiWCc0kXraf7NbebOU2TIv9KicHO6Og18iZpsxKH0am6wN7f1FwB1VSvZkvfJQgFkqjoqYEJ8qmgKB/YC9mbQAP14BjoJTq6fwDehF5leqSYT7NJarlhV7BX+hn4cCOBZ/gdGPCdK2aXZy8KJrnxh6RBGe0+84L3mEOaSZmZRvmXMcRjRozu17qV3xm6mo7BTq+/7tES3CAovMw=='),DATE '1988-05-29'); diff --git a/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Songs.txt b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Songs.txt new file mode 100644 index 000000000000..bda929b0fe5f --- /dev/null +++ b/google-cloud-clients/google-cloud-contrib/google-cloud-spanner-jdbc/src/test/resources/com/google/cloud/spanner/jdbc/it/Songs.txt @@ -0,0 +1,149 @@ +(12,42,1,"Song 12 42 1",387,'Unknown'); +(12,12,2,"Song 12 12 2",202,'Unknown'); +(29,59,3,"Song 29 59 3",160,'Unknown'); +(23,23,4,"Song 23 23 4",255,'Unknown'); +(24,54,5,"Song 24 54 5",436,'Unknown'); +(28,58,6,"Song 28 58 6",121,'Unknown'); +(27,27,7,"Song 27 27 7",319,'Unknown'); +(24,24,8,"Song 24 24 8",213,'Unknown'); +(19,49,9,"Song 19 49 9",280,'Unknown'); +(17,47,10,"Song 17 47 10",253,'Unknown'); +(6,6,11,"Song 6 6 11",321,'Unknown'); +(12,42,12,"Song 12 42 12 12 42 12",124,'Unknown'); +(25,25,13,"Song 25 25 13",449,'Unknown'); +(24,24,14,"Song 24 24 14",438,'Unknown'); +(5,5,15,"Song 5 5 15",378,'Unknown'); +(9,39,16,"Song 9 39 16",202,'Unknown'); +(20,50,17,"Song 20 50 17",452,'Unknown'); +(7,37,18,"Song 7 37 18",420,'Unknown'); +(8,8,19,"Song 8 8 19",318,'Unknown'); +(5,35,20,"Song 5 35 20",347,'Unknown'); +(3,3,21,"Song 3 3 21",377,'Unknown'); +(15,15,22,"Song 15 15 22",314,'Unknown'); +(19,49,23,"Song 19 49 23",199,'Unknown'); +(20,20,24,"Song 20 20 24",266,'Unknown'); +(15,45,25,"Song 15 45 25",433,'Unknown'); +(14,44,26,"Song 14 44 26",482,'Unknown'); +(19,19,27,"Song 19 19 27",345,'Unknown'); +(13,43,28,"Song 13 43 28",159,'Unknown'); +(18,48,29,"Song 18 48 29",350,'Unknown'); +(13,13,30,"Song 13 13 30",131,'Unknown'); +(9,9,31,"Song 9 9 31",183,'Unknown'); +(13,13,32,"Song 13 13 32",193,'Unknown'); +(24,24,33,"Song 24 24 33",378,'Unknown'); +(30,60,34,"Song 30 60 34",270,'Unknown'); +(13,43,35,"Song 13 43 35",375,'Unknown'); +(27,27,36,"Song 27 27 36",219,'Unknown'); +(20,50,37,"Song 20 50 37",314,'Unknown'); +(18,48,38,"Song 18 48 38",416,'Unknown'); +(21,51,39,"Song 21 51 39",330,'Unknown'); +(1,31,40,"Song 1 31 40",376,'Unknown'); +(5,5,41,"Song 5 5 41",398,'Unknown'); +(15,45,42,"Song 15 45 42",466,'Unknown'); +(24,24,43,"v 24 24 43",384,'Unknown'); +(19,19,44,"Song 19 19 44",472,'Unknown'); +(15,45,45,"Song 15 45 45",246,'Unknown'); +(3,33,46,"Song 3 33 46",412,'Unknown'); +(23,23,47,"Song 23 23 47",159,'Unknown'); +(30,60,48,"Song 30 60 48",290,'Unknown'); +(19,19,49,"Song 19 19 49",446,'Unknown'); +(16,16,50,"Song 16 16 50",485,'Unknown'); +(4,4,51,"Song 4 4 51",185,'Unknown'); +(8,38,52,"Song 8 38 52",349,'Unknown'); +(24,54,53,"Song 24 54 53",301,'Unknown'); +(5,35,54,"Song 5 35 54",206,'Unknown'); +(30,30,55,"Song 30 30 55",250,'Unknown'); +(12,42,56,"Song 12 42 56",146,'Unknown'); +(30,30,57,"Song 30 30 57",416,'Unknown'); +(26,56,58,"Song 26 56 58",244,'Unknown'); +(20,50,59,"Song 20 50 59",356,'Unknown'); +(7,7,60,"Song 7 7 60",234,'Unknown'); +(19,19,61,"Song 19 19 61",412,'Unknown'); +(13,43,62,"Song 13 43 62",161,'Unknown'); +(5,5,63,"Song 5 5 63",300,'Unknown'); +(1,31,64,"Song 1 31 64",307,'Unknown'); +(4,4,65,"Song 4 4 65",197,'Unknown'); +(24,54,66,"Song 24 54 66",180,'Unknown'); +(3,3,67,"Song 3 3 67",156,'Unknown'); +(14,44,68,"Song 14 44 68",184,'Unknown'); +(21,51,69,"Song 21 51 69",486,'Unknown'); +(19,49,70,"Song 19 49 70",212,'Unknown'); +(9,39,71,"Song 9 39 71",452,'Unknown'); +(23,53,72,"Song 23 53 72",425,'Unknown'); +(11,41,73,"Song 11 41 73",316,'Unknown'); +(8,8,74,"Song 8 8 74",395,'Unknown'); +(9,9,75,"Song 9 9 75",189,'Unknown'); +(2,2,76,"Song 2 2 76",354,'Unknown'); +(23,53,77,"Song 23 53 77",137,'Unknown'); +(15,15,78,"TSong 15 15 78",176,'Unknown'); +(30,60,79,"Song 30 60 79",224,'Unknown'); +(14,44,80,"Song 14 44 80",305,'Unknown'); +(27,27,81,"Song 27 27 81",432,'Unknown'); +(18,18,82,"Song 18 18 82",357,'Unknown'); +(10,10,83,"Song 10 10 83",187,'Unknown'); +(12,42,84,"Song 12 42 84",461,'Unknown'); +(8,8,85,"Song 8 8 85",434,'Unknown'); +(1,31,86,"Song 1 31 86",436,'Unknown'); +(11,41,87,"Song 11 41 87",469,'Unknown'); +(13,13,88,"Song 13 13 88",452,'Unknown'); +(4,34,89,"Song 4 34 89",309,'Unknown'); +(21,21,90,"Song 21 21 90",226,'Unknown'); +(6,36,91,"Song 6 36 91",257,'Unknown'); +(27,27,92,"Song 27 27 92",251,'Unknown'); +(9,39,93,"Song 9 39 93",325,'Unknown'); +(30,30,94,"Song 30 30 94",122,'Unknown'); +(29,59,95,"Song 29 59 95",207,'Unknown'); +(1,1,96,"Song 1 1 96",318,'Unknown'); +(4,4,97,"Song 4 4 97",353,'Unknown'); +(23,23,98,"Song 23 23 98",450,'Unknown'); +(12,12,99,"Song 12 12 99",323,'Unknown'); +(24,24,100,"Song 24 24 100",397,'Unknown'); +(27,27,101,"Song 27 27 101",296,'Unknown'); +(29,59,102,"Song 29 59 102",349,'Unknown'); +(17,47,103,"Song 17 47 103",438,'Unknown'); +(5,5,104,"Song 5 5 104",388,'Unknown'); +(26,56,105,"Song 26 56 105",425,'Unknown'); +(22,52,106,"Song 22 52 106",154,'Unknown'); +(23,23,107,"Song 23 23 107",213,'Unknown'); +(8,38,108,"Song 8 38 108",276,'Unknown'); +(9,39,109,"Song 9 39 109",417,'Unknown'); +(9,9,110,"Song 9 9 110",299,'Unknown'); +(22,52,111,"Song 22 52 111",476,'Unknown'); +(21,21,112,"Song 21 21 112",225,'Unknown'); +(23,23,113,"Song 23 23 113",303,'Unknown'); +(7,7,114,"Song 7 7 114",291,'Unknown'); +(8,38,115,"Song 8 38 115",276,'Unknown'); +(14,44,116,"Song 14 44 116",238,'Unknown'); +(27,57,117,"Song 27 57 117",188,'Unknown'); +(28,28,118,"Song 28 28 118",372,'Unknown'); +(15,15,119,"Song 15 15 119",258,'Unknown'); +(21,21,120,"Song 21 21 120",308,'Unknown'); +(29,59,121,"Song 29 59 121",319,'Unknown'); +(28,58,122,"Song 28 58 122",453,'Unknown'); +(7,7,123,"Song 7 7 123",198,'Unknown'); +(4,4,124,"Song 4 4 124",435,'Unknown'); +(27,27,125,"Song 27 27 125",475,'Unknown'); +(30,30,126,"Song 30 30 126",395,'Unknown'); +(21,51,127,"Song 21 51 127",454,'Unknown'); +(29,29,128,"Song 29 29 128",376,'Unknown'); +(27,57,129,"Song 27 57 129",396,'Unknown'); +(23,53,130,"Song 23 53 130",458,'Unknown'); +(6,36,131,"Song 6 36 131",289,'Unknown'); +(29,29,132,"Song 29 29 132",207,'Unknown'); +(25,55,133,"Song 25 55 133",280,'Unknown'); +(3,3,134,"Song 3 3 134",432,'Unknown'); +(5,35,135,"1 5 35 135",304,'Unknown'); +(3,3,136,"2 3 3 136",392,'Unknown'); +(12,12,137,"3 12 12 137",393,'Unknown'); +(13,13,138,"4 13 13 138",382,'Unknown'); +(18,48,139,"5 18 48 139",447,'Unknown'); +(17,17,140,"6 17 17 140",182,'Unknown'); +(23,23,141,"7 23 23 141",266,'Unknown'); +(21,51,142,"8 21 51 142",383,'Unknown'); +(3,3,143,"9 3 3 143",439,'Unknown'); +(25,25,144,"10 25 25 144",454,'Unknown'); +(12,12,145,"11 12 12 145",179,'Unknown'); +(19,19,146,"12 19 19 146",422,'Unknown'); +(24,54,147,"13 24 54 147",478,'Unknown'); +(8,38,148,"14 8 38 148",233,'Unknown'); +(6,6,149,"15 6 6 149",245,'Unknown');