Skip to content

Commit 948e893

Browse files
authored
Merge branch 'main' into migrateJavaToLibrarain
2 parents 7bee362 + 4640eba commit 948e893

37 files changed

Lines changed: 534 additions & 195 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,6 @@ monorepo
8686
*.tfstate.lock.info
8787

8888
.jqwik-database
89+
90+
# Python build artifacts for library_generation tool
91+
sdk-platform-java/hermetic_build/library_generation/build/

java-bigquery-jdbc/pom-it.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<dependency>
2222
<groupId>com.google.cloud</groupId>
2323
<artifactId>google-cloud-bigquery-jdbc</artifactId>
24-
<version>0.4.1-SNAPSHOT</version>
24+
<version>1.0.0-SNAPSHOT</version><!-- {x-version-update:google-cloud-bigquery-jdbc:current} -->
2525
<type>test-jar</type>
2626
<scope>compile</scope>
2727
</dependency>

java-bigquery-jdbc/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<modelVersion>4.0.0</modelVersion>
2121
<groupId>com.google.cloud</groupId>
2222
<artifactId>google-cloud-bigquery-jdbc</artifactId>
23-
<version>0.11.0-SNAPSHOT</version><!-- {x-version-update:google-cloud-bigquery-jdbc:current} -->
23+
<version>1.0.0-SNAPSHOT</version><!-- {x-version-update:google-cloud-bigquery-jdbc:current} -->
2424
<packaging>jar</packaging>
2525
<name>BigQuery JDBC</name>
2626
<url>https://github.com/googleapis/google-cloud-java</url>

java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryDatabaseMetaData.java

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5080,40 +5080,35 @@ Pattern compileSqlLikePattern(String sqlLikePattern) {
50805080
}
50815081
StringBuilder regex = new StringBuilder(sqlLikePattern.length() * 2);
50825082
regex.append('^');
5083+
boolean escaped = false;
50835084
for (int i = 0; i < sqlLikePattern.length(); i++) {
50845085
char c = sqlLikePattern.charAt(i);
5085-
switch (c) {
5086-
case '%':
5087-
regex.append(".*");
5088-
break;
5089-
case '_':
5090-
regex.append('.');
5091-
break;
5092-
case '\\':
5093-
case '.':
5094-
case '[':
5095-
case ']':
5096-
case '(':
5097-
case ')':
5098-
case '{':
5099-
case '}':
5100-
case '*':
5101-
case '+':
5102-
case '?':
5103-
case '^':
5104-
case '$':
5105-
case '|':
5106-
regex.append('\\').append(c);
5107-
break;
5108-
default:
5109-
regex.append(c);
5110-
break;
5086+
if (!escaped && c == '\\') {
5087+
escaped = true;
5088+
continue;
5089+
} else if (!escaped && c == '%') {
5090+
regex.append(".*");
5091+
} else if (!escaped && c == '_') {
5092+
regex.append('.');
5093+
} else {
5094+
if (isRegexMetacharacter(c)) {
5095+
regex.append('\\');
5096+
}
5097+
regex.append(c);
5098+
escaped = false;
51115099
}
51125100
}
5101+
if (escaped) {
5102+
regex.append('\\').append('\\');
5103+
}
51135104
regex.append('$');
51145105
return Pattern.compile(regex.toString(), Pattern.CASE_INSENSITIVE);
51155106
}
51165107

5108+
private static boolean isRegexMetacharacter(char c) {
5109+
return "\\.[]{}()*+?^$|".indexOf(c) != -1;
5110+
}
5111+
51175112
boolean needsListing(String pattern) {
51185113
return pattern == null || pattern.contains("%") || pattern.contains("_");
51195114
}

java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQuerySqlTypeConverter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ static SqlType getSqlTypeFromStatementType(StatementType statementType) {
7272
case "ROLLBACK_TRANSACTION":
7373
return SqlType.TCL;
7474
case "EXPORT_DATA":
75+
return SqlType.EXPORT;
7576
case "EXPORT_MODEL":
7677
case "LOAD_DATA":
7778
default:

java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryStatement.java

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -685,15 +685,12 @@ void handleQueryResult(String query, TableResult results, SqlType queryType)
685685
break;
686686
case DML:
687687
case DML_EXTRA:
688-
try {
689-
Job completedJob = this.bigQuery.getJob(results.getJobId()).waitFor();
690-
JobStatistics.QueryStatistics statistics = completedJob.getStatistics();
691-
updateAffectedRowCount(statistics.getNumDmlAffectedRows());
692-
} catch (InterruptedException ex) {
693-
throw new BigQueryJdbcRuntimeException(ex);
694-
} catch (NullPointerException ex) {
695-
throw new BigQueryJdbcException(ex);
696-
}
688+
QueryStatistics dmlStats = getQueryStatisticsFromJob(results);
689+
Long dmlRowCount =
690+
(dmlStats != null && dmlStats.getNumDmlAffectedRows() != null)
691+
? dmlStats.getNumDmlAffectedRows()
692+
: 0L;
693+
updateAffectedRowCount(dmlRowCount);
697694
break;
698695
case TCL:
699696
case DDL:
@@ -725,8 +722,43 @@ void handleQueryResult(String query, TableResult results, SqlType queryType)
725722
throw new BigQueryJdbcException(ex);
726723
}
727724
break;
725+
case EXPORT:
726+
QueryStatistics exportStats = getQueryStatisticsFromJob(results);
727+
Long exportRowCount = 0L;
728+
if (exportStats != null) {
729+
QueryStatistics.ExportDataStats dataStats = exportStats.getExportDataStats();
730+
if (dataStats != null && dataStats.getRowCount() != null) {
731+
exportRowCount = dataStats.getRowCount();
732+
}
733+
}
734+
updateAffectedRowCount(exportRowCount);
735+
break;
728736
case OTHER:
729-
throw new BigQueryJdbcException(String.format("Unexpected value: " + queryType));
737+
String truncatedQuery = truncateQuery(query);
738+
String id =
739+
(results.getJobId() != null) ? results.getJobId().getJob() : results.getQueryId();
740+
LOG.warning(
741+
"Encountered unmapped SQL statement type [Job/Query ID: %s]. Treating as update statement: %s",
742+
id, truncatedQuery);
743+
updateAffectedRowCount(results.getTotalRows());
744+
break;
745+
}
746+
}
747+
748+
private QueryStatistics getQueryStatisticsFromJob(TableResult results) throws SQLException {
749+
try {
750+
Job job = this.bigQuery.getJob(results.getJobId());
751+
Job completedJob = (job != null) ? job.waitFor() : null;
752+
JobStatistics stats = (completedJob != null) ? completedJob.getStatistics() : null;
753+
if (stats instanceof QueryStatistics) {
754+
return (QueryStatistics) stats;
755+
}
756+
return null;
757+
} catch (InterruptedException ex) {
758+
Thread.currentThread().interrupt();
759+
throw new BigQueryJdbcRuntimeException("Interrupted while waiting for job completion", ex);
760+
} catch (BigQueryException ex) {
761+
throw new BigQueryJdbcException("BigQueryException while waiting for job completion", ex);
730762
}
731763
}
732764

@@ -1589,13 +1621,19 @@ protected void logQueryExecutionStart(String sql) {
15891621
if (sql == null) {
15901622
return;
15911623
}
1592-
String sanitizedSql = sql.trim().replaceAll("\\s+", " ");
1593-
String truncatedSql =
1594-
sanitizedSql.length() > 256 ? sanitizedSql.substring(0, 256) + "..." : sanitizedSql;
1624+
String truncatedSql = truncateQuery(sql);
15951625
LOG.info("Executing query: " + truncatedSql);
15961626
LOG.info("Using query settings: " + this.querySettings.toString());
15971627
}
15981628

1629+
private String truncateQuery(String sql) {
1630+
if (sql == null) {
1631+
return null;
1632+
}
1633+
String sanitizedSql = sql.trim().replaceAll("\\s+", " ");
1634+
return sanitizedSql.length() > 256 ? sanitizedSql.substring(0, 256) + "..." : sanitizedSql;
1635+
}
1636+
15991637
/** Throws a {@link BigQueryJdbcException} if this object is closed */
16001638
void checkClosed() throws SQLException {
16011639
if (isClosed()) {
@@ -1610,6 +1648,7 @@ enum SqlType {
16101648
DDL,
16111649
SCRIPT,
16121650
TCL,
1651+
EXPORT,
16131652
OTHER
16141653
}
16151654

java-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryDatabaseMetaDataTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,23 @@ public void testCompileSqlLikePattern() {
243243
assertNotNull(bracketPattern);
244244
assertTrue(bracketPattern.matcher("array[0]").matches());
245245
assertFalse(bracketPattern.matcher("array_0_").matches());
246+
247+
// Escaped wildcards
248+
Pattern escapedUnderscore = dbMetadata.compileSqlLikePattern("test\\_table");
249+
assertNotNull(escapedUnderscore);
250+
assertTrue(escapedUnderscore.matcher("test_table").matches());
251+
assertFalse(escapedUnderscore.matcher("test1table").matches());
252+
253+
Pattern escapedPercent = dbMetadata.compileSqlLikePattern("100\\%discount");
254+
assertNotNull(escapedPercent);
255+
assertTrue(escapedPercent.matcher("100%discount").matches());
256+
assertFalse(escapedPercent.matcher("100PERCENTdiscount").matches());
257+
258+
// Escape character at the end
259+
Pattern escapeLast = dbMetadata.compileSqlLikePattern("test\\");
260+
assertNotNull(escapeLast);
261+
assertTrue(escapeLast.matcher("test\\").matches());
262+
assertFalse(escapeLast.matcher("test").matches());
246263
}
247264

248265
@Test

java-spanner/google-cloud-spanner/clirr-ignored-differences.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -910,21 +910,21 @@
910910
<method>java.lang.Object runTransaction(com.google.cloud.spanner.connection.Connection$TransactionCallable)</method>
911911
</difference>
912912

913-
<!-- Added experimental host option -->
913+
<!-- Added Spanner Omni option -->
914914
<difference>
915915
<differenceType>7012</differenceType>
916916
<className>com/google/cloud/spanner/SpannerOptions$SpannerEnvironment</className>
917-
<method>com.google.auth.oauth2.GoogleCredentials getDefaultExperimentalHostCredentials()</method>
917+
<method>com.google.auth.oauth2.GoogleCredentials getDefaultSpannerOmniCredentials()</method>
918918
</difference>
919919
<difference>
920920
<differenceType>7002</differenceType>
921921
<className>com/google/cloud/spanner/SpannerOptions$SpannerEnvironment</className>
922-
<method>com.google.auth.oauth2.GoogleCredentials getDefaultExternalHostCredentials()</method>
922+
<method>com.google.auth.oauth2.GoogleCredentials getDefaultSpannerOmniCredentials()</method>
923923
</difference>
924924
<difference>
925925
<differenceType>7002</differenceType>
926926
<className>com/google/cloud/spanner/SpannerOptions</className>
927-
<method>com.google.auth.oauth2.GoogleCredentials getDefaultExternalHostCredentialsFromSysEnv()</method>
927+
<method>com.google.auth.oauth2.GoogleCredentials getDefaultSpannerOmniCredentialsFromSysEnv()</method>
928928
</difference>
929929

930930
<!-- Default sequence kind -->

0 commit comments

Comments
 (0)