Skip to content

Commit ad97128

Browse files
committed
perf(spanner-jdbc): cache JDBC metadata query strings
Cache the SQL strings that are loaded from disk for the standard JDBC metadata queries.
1 parent 96a7e6f commit ad97128

2 files changed

Lines changed: 24 additions & 10 deletions

File tree

java-spanner-jdbc/src/main/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaData.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626
import com.google.cloud.spanner.Type.StructField;
2727
import com.google.cloud.spanner.connection.Connection.InternalMetadataQuery;
2828
import com.google.common.annotations.VisibleForTesting;
29+
import com.google.common.base.Preconditions;
2930
import com.google.common.collect.ImmutableSet;
3031
import java.io.BufferedReader;
3132
import java.io.InputStream;
3233
import java.io.InputStreamReader;
34+
import java.nio.charset.StandardCharsets;
3335
import java.sql.Connection;
3436
import java.sql.DatabaseMetaData;
3537
import java.sql.ResultSet;
@@ -40,6 +42,8 @@
4042
import java.util.Collections;
4143
import java.util.Properties;
4244
import java.util.Scanner;
45+
import java.util.concurrent.ConcurrentHashMap;
46+
import java.util.concurrent.ConcurrentMap;
4347

4448
/** {@link DatabaseMetaData} implementation for Cloud Spanner */
4549
class JdbcDatabaseMetaData extends AbstractJdbcWrapper implements DatabaseMetaData {
@@ -50,18 +54,19 @@ class JdbcDatabaseMetaData extends AbstractJdbcWrapper implements DatabaseMetaDa
5054
private static final String PRODUCT_NAME = "Google Cloud Spanner";
5155
private static final String POSTGRESQL_PRODUCT_NAME = PRODUCT_NAME + " PostgreSQL";
5256

57+
private static final ConcurrentMap<String, String> SQL_CACHE = new ConcurrentHashMap<>();
58+
5359
@VisibleForTesting
5460
static String readSqlFromFile(String filename, Dialect dialect) {
55-
InputStream in;
56-
switch (dialect) {
57-
case POSTGRESQL:
58-
in = JdbcDatabaseMetaData.class.getResourceAsStream("postgresql/" + filename);
59-
break;
60-
case GOOGLE_STANDARD_SQL:
61-
default:
62-
in = JdbcDatabaseMetaData.class.getResourceAsStream(filename);
63-
}
64-
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
61+
return SQL_CACHE.computeIfAbsent(
62+
filename + "/" + dialect, (key) -> loadSqlFromFile(filename, dialect));
63+
}
64+
65+
private static String loadSqlFromFile(String filename, Dialect dialect) {
66+
String resourcePath = dialect == Dialect.POSTGRESQL ? "postgresql/" + filename : filename;
67+
InputStream in = JdbcDatabaseMetaData.class.getResourceAsStream(resourcePath);
68+
Preconditions.checkNotNull(in, "Resource not found: " + resourcePath);
69+
BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
6570
StringBuilder builder = new StringBuilder();
6671
try (Scanner scanner = new Scanner(reader)) {
6772
while (scanner.hasNextLine()) {

java-spanner-jdbc/src/test/java/com/google/cloud/spanner/jdbc/JdbcDatabaseMetaDataTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.junit.Assert.assertEquals;
2020
import static org.junit.Assert.assertFalse;
2121
import static org.junit.Assert.assertNotNull;
22+
import static org.junit.Assert.assertSame;
2223
import static org.junit.Assert.assertTrue;
2324
import static org.mockito.Mockito.mock;
2425
import static org.mockito.Mockito.when;
@@ -574,4 +575,12 @@ public void testGetUserName() throws SQLException, IOException {
574575
DatabaseMetaData meta = new JdbcDatabaseMetaData(connection);
575576
assertEquals("test@test-project.iam.gserviceaccount.com", meta.getUserName());
576577
}
578+
579+
@Test
580+
public void testReadSqlFromFileCaching() {
581+
String sql1 = JdbcDatabaseMetaData.readSqlFromFile("DatabaseMetaData_GetTables.sql", dialect);
582+
String sql2 = JdbcDatabaseMetaData.readSqlFromFile("DatabaseMetaData_GetTables.sql", dialect);
583+
assertNotNull(sql1);
584+
assertSame(sql1, sql2);
585+
}
577586
}

0 commit comments

Comments
 (0)