Skip to content

Commit 5f65c13

Browse files
[FLINK-37288] Handle Spanner semicolon params in getDatabaseUrl
1 parent 8007713 commit 5f65c13

2 files changed

Lines changed: 35 additions & 6 deletions

File tree

flink-connector-jdbc-spanner/src/main/java/org/apache/flink/connector/jdbc/spanner/database/catalog/SpannerCatalog.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,31 @@ public SpannerCatalog(
105105
this.dialectTypeMapper = new SpannerTypeMapper();
106106
}
107107

108+
@Override
109+
protected String getDatabaseUrl(String databaseName) {
110+
// Spanner JDBC URL uses semicolon for parameters instead of question mark
111+
// Handle semicolon params the same way AbstractJdbcCatalog handles '?' params
112+
// Example: "jdbc:cloudspanner://host/projects/.../databases/;autoConfigEmulator=true"
113+
// -> "jdbc:cloudspanner://host/projects/.../databases/mydb;autoConfigEmulator=true"
114+
int semiColonIndex = baseUrl.indexOf(';');
115+
116+
if (semiColonIndex == -1) {
117+
// No parameters: traditional baseUrl + databaseName
118+
return baseUrl + databaseName;
119+
}
120+
121+
// Parameters present: insert database name before ';'
122+
String urlWithoutParams = baseUrl.substring(0, semiColonIndex);
123+
String params = baseUrl.substring(semiColonIndex);
124+
125+
// Remove trailing '/' from params if AbstractJdbcCatalog added it
126+
if (params.endsWith("/")) {
127+
params = params.substring(0, params.length() - 1);
128+
}
129+
130+
return urlWithoutParams + databaseName + params;
131+
}
132+
108133
private ConnectionOptions getConnectionOptions() {
109134
return ConnectionOptions.newBuilder().setUri(defaultUrl.replace("jdbc:", "")).build();
110135
}
@@ -218,10 +243,7 @@ public CatalogBaseTable getTable(ObjectPath tablePath)
218243
pk -> schemaBuilder.primaryKeyNamed(pk.getName(), pk.getColumns()));
219244
Schema tableSchema = schemaBuilder.build();
220245

221-
return CatalogTable.newBuilder()
222-
.schema(tableSchema)
223-
.options(getOptions(tablePath))
224-
.build();
246+
return CatalogTable.of(tableSchema, null, Lists.newArrayList(), getOptions(tablePath));
225247
} catch (Exception e) {
226248
throw new CatalogException(
227249
String.format("Failed getting table %s", tablePath.getFullName()), e);

flink-connector-jdbc-spanner/src/test/java/org/apache/flink/connector/jdbc/spanner/database/catalog/SpannerCatalogTestBase.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,20 @@ protected static TableRow createTableGroupedBy(String name) {
152152
@BeforeAll
153153
static void beforeAll() throws SQLException {
154154
String jdbcUrl = SpannerDatabase.getMetadata().getJdbcUrl();
155-
baseUrl = jdbcUrl.substring(0, jdbcUrl.lastIndexOf("/"));
155+
// Preserve connection parameters in baseUrl with '/' before ';'
156+
// Example: jdbc:cloudspanner://host/.../databases/testdb;autoConfigEmulator=true
157+
// -> jdbc:cloudspanner://host/.../databases/;autoConfigEmulator=true
158+
int semiColonIndex = jdbcUrl.indexOf(';');
159+
String params = semiColonIndex != -1 ? jdbcUrl.substring(semiColonIndex) : "";
160+
String urlWithoutParams =
161+
semiColonIndex != -1 ? jdbcUrl.substring(0, semiColonIndex) : jdbcUrl;
162+
// Include trailing '/' before params so database name can be inserted
163+
baseUrl = urlWithoutParams.substring(0, urlWithoutParams.lastIndexOf("/") + 1) + params;
156164
metadata = SpannerDatabase.getMetadata();
157165

158166
Properties props =
159167
JdbcConnectionOptions.getBriefAuthProperties(
160168
metadata.getUsername(), metadata.getPassword());
161-
props.put("autoConfigEmulator", "true");
162169
catalog =
163170
new SpannerCatalog(
164171
Thread.currentThread().getContextClassLoader(),

0 commit comments

Comments
 (0)