Skip to content

perf: remove all calls to getSqlWithoutComments #3822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ <ResponseT, MetadataT> ResponseT getWithStatementTimeout(
} catch (TimeoutException e) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.DEADLINE_EXCEEDED,
"Statement execution timeout occurred for " + statement.getSqlWithoutComments(),
"Statement execution timeout occurred for " + statement.getSql(),
e);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
Expand All @@ -331,7 +331,7 @@ <ResponseT, MetadataT> ResponseT getWithStatementTimeout(
}
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.fromGrpcStatus(Status.fromThrowable(e)),
"Statement execution failed for " + statement.getSqlWithoutComments(),
"Statement execution failed for " + statement.getSql(),
e);
} catch (InterruptedException e) {
throw SpannerExceptionFactory.newSpannerException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,17 @@ Statement mergeQueryOptions(Statement statement, QueryOptions defaultQueryOption
.build();
}

/** @return the SQL statement with all comments removed from the SQL string. */
/** @return the original SQL statement */
@InternalApi
public String getSql() {
return statement.getSql();
}

/**
* @return the SQL statement with all comments removed from the SQL string.
* @deprecated use {@link #getSql()} instead
*/
@Deprecated
@InternalApi
public String getSqlWithoutComments() {
return sqlWithoutComments.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ class ClientSideStatementBeginExecutor implements ClientSideStatementExecutor {
@Override
public StatementResult execute(ConnectionStatementExecutor connection, ParsedStatement statement)
throws Exception {
return (StatementResult)
method.invoke(connection, getParameterValue(statement.getSqlWithoutComments()));
return (StatementResult) method.invoke(connection, getParameterValue(statement.getSql()));
}

IsolationLevel getParameterValue(String sql) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ class ClientSideStatementExplainExecutor implements ClientSideStatementExecutor
@Override
public StatementResult execute(ConnectionStatementExecutor connection, ParsedStatement statement)
throws Exception {
return (StatementResult)
method.invoke(connection, getParameterValue(statement.getSqlWithoutComments()));
return (StatementResult) method.invoke(connection, getParameterValue(statement.getSql()));
}

String getParameterValue(String sql) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public StatementResult execute(
}

String getParameterValue(ParsedStatement parsedStatement) {
Matcher matcher = statement.getPattern().matcher(parsedStatement.getSqlWithoutComments());
Matcher matcher = statement.getPattern().matcher(parsedStatement.getSql());
if (matcher.find() && matcher.groupCount() >= 2) {
String space = matcher.group(1);
String value = matcher.group(2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ class ClientSideStatementPgBeginExecutor implements ClientSideStatementExecutor
@Override
public StatementResult execute(ConnectionStatementExecutor connection, ParsedStatement statement)
throws Exception {
return (StatementResult)
method.invoke(connection, getParameterValue(statement.getSqlWithoutComments()));
return (StatementResult) method.invoke(connection, getParameterValue(statement.getSql()));
}

PgTransactionMode getParameterValue(String sql) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ String getParameterValue(ParsedStatement parsedStatement) {
// 2. If the matcher matches and returns zero groups, we know that the statement is valid, but
// that it does not contain a partition-id in the SQL statement. The partition-id must then
// be included in the statement as a query parameter.
Matcher matcher = statement.getPattern().matcher(parsedStatement.getSqlWithoutComments());
Matcher matcher = statement.getPattern().matcher(parsedStatement.getSql());
if (matcher.find() && matcher.groupCount() >= 1) {
String value = matcher.group(1);
if (!Strings.isNullOrEmpty(value)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public StatementResult execute(
}

String getParameterValue(ParsedStatement parsedStatement) {
Matcher matcher = statement.getPattern().matcher(parsedStatement.getSqlWithoutComments());
Matcher matcher = statement.getPattern().matcher(parsedStatement.getSql());
if (matcher.find() && matcher.groupCount() >= 2) {
// Include the spacing group in case the query is enclosed in parentheses like this:
// `run partitioned query(select * from foo)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.google.cloud.spanner.connection;

import com.google.cloud.Tuple;
import com.google.cloud.spanner.Dialect;
import com.google.cloud.spanner.ErrorCode;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.connection.AbstractStatementParser.ParsedStatement;
Expand All @@ -27,6 +28,7 @@
import com.google.common.util.concurrent.UncheckedExecutionException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.CharBuffer;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -104,8 +106,8 @@ public StatementResult execute(ConnectionStatementExecutor connection, ParsedSta
try {
value =
this.cache.get(
statement.getSqlWithoutComments(),
() -> getParameterValue(statement.getSqlWithoutComments()));
statement.getSql(),
() -> getParameterValue(connection.getDialect(), statement.getSql()));
} catch (ExecutionException | UncheckedExecutionException executionException) {
throw SpannerExceptionFactory.asSpannerException(executionException.getCause());
}
Expand All @@ -115,8 +117,13 @@ public StatementResult execute(ConnectionStatementExecutor connection, ParsedSta
return (StatementResult) method.invoke(connection, value.x());
}

Tuple<T, Boolean> getParameterValue(String sql) {
Matcher matcher = allowedValuesPattern.matcher(sql);
Tuple<T, Boolean> getParameterValue(Dialect dialect, String sql) {
// Get rid of any spaces/comments at the start of the string.
SimpleParser simpleParser = new SimpleParser(dialect, sql);
simpleParser.skipWhitespaces();
// Create a wrapper around the SQL string from the point after the first whitespace.
CharBuffer sqlAfterWhitespaces = CharBuffer.wrap(sql, simpleParser.getPos(), sql.length());
Matcher matcher = allowedValuesPattern.matcher(sqlAfterWhitespaces);
if (matcher.find() && matcher.groupCount() >= 2) {
boolean local = matcher.group(1) != null && "local".equalsIgnoreCase(matcher.group(1).trim());
String value = matcher.group(2);
Expand All @@ -130,7 +137,7 @@ Tuple<T, Boolean> getParameterValue(String sql) {
"Unknown value for %s: %s",
this.statement.getSetStatement().getPropertyName(), value));
} else {
Matcher invalidMatcher = this.statement.getPattern().matcher(sql);
Matcher invalidMatcher = this.statement.getPattern().matcher(sqlAfterWhitespaces);
int valueGroup = this.supportsLocal ? 2 : 1;
if (invalidMatcher.find() && invalidMatcher.groupCount() == valueGroup) {
String invalidValue = invalidMatcher.group(valueGroup);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ public Spanner getSpanner() {
private DdlClient createDdlClient() {
return DdlClient.newBuilder()
.setDatabaseAdminClient(spanner.getDatabaseAdminClient())
.setDialectSupplier(this::getDialect)
.setProjectId(options.getProjectId())
.setInstanceId(options.getInstanceId())
.setDatabaseName(options.getDatabaseName())
Expand Down Expand Up @@ -1424,8 +1425,7 @@ private StatementResult internalExecute(
default:
}
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Unknown statement: " + parsedStatement.getSqlWithoutComments());
ErrorCode.INVALID_ARGUMENT, "Unknown statement: " + parsedStatement.getSql());
}

@VisibleForTesting
Expand Down Expand Up @@ -1470,8 +1470,7 @@ private static ResultType getResultType(ParsedStatement parsedStatement) {
case UNKNOWN:
default:
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Unknown statement: " + parsedStatement.getSqlWithoutComments());
ErrorCode.INVALID_ARGUMENT, "Unknown statement: " + parsedStatement.getSql());
}
}

Expand Down Expand Up @@ -1503,8 +1502,7 @@ public AsyncStatementResult executeAsync(Statement statement) {
default:
}
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Unknown statement: " + parsedStatement.getSqlWithoutComments());
ErrorCode.INVALID_ARGUMENT, "Unknown statement: " + parsedStatement.getSql());
}

@Override
Expand Down Expand Up @@ -1699,7 +1697,7 @@ private ResultSet parseAndExecuteQuery(
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.FAILED_PRECONDITION,
"DML statement with returning clause cannot be executed in read-only mode: "
+ parsedStatement.getSqlWithoutComments());
+ parsedStatement.getSql());
}
return internalExecuteQuery(callType, parsedStatement, analyzeMode, options);
}
Expand All @@ -1710,8 +1708,7 @@ private ResultSet parseAndExecuteQuery(
}
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Statement is not a query or DML with returning clause: "
+ parsedStatement.getSqlWithoutComments());
"Statement is not a query or DML with returning clause: " + parsedStatement.getSql());
}

private AsyncResultSet parseAndExecuteQueryAsync(Statement query, QueryOption... options) {
Expand Down Expand Up @@ -1741,7 +1738,7 @@ private AsyncResultSet parseAndExecuteQueryAsync(Statement query, QueryOption...
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.FAILED_PRECONDITION,
"DML statement with returning clause cannot be executed in read-only mode: "
+ parsedStatement.getSqlWithoutComments());
+ parsedStatement.getSql());
}
return internalExecuteQueryAsync(
CallType.ASYNC, parsedStatement, AnalyzeMode.NONE, options);
Expand All @@ -1753,8 +1750,7 @@ private AsyncResultSet parseAndExecuteQueryAsync(Statement query, QueryOption...
}
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Statement is not a query or DML with returning clause: "
+ parsedStatement.getSqlWithoutComments());
"Statement is not a query or DML with returning clause: " + parsedStatement.getSql());
}

private boolean isInternalMetadataQuery(QueryOption... options) {
Expand All @@ -1781,7 +1777,7 @@ public long executeUpdate(Statement update) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.FAILED_PRECONDITION,
"DML statement with returning clause cannot be executed using executeUpdate: "
+ parsedStatement.getSqlWithoutComments()
+ parsedStatement.getSql()
+ ". Please use executeQuery instead.");
}
return get(internalExecuteUpdateAsync(CallType.SYNC, parsedStatement));
Expand All @@ -1794,7 +1790,7 @@ public long executeUpdate(Statement update) {
}
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Statement is not an update statement: " + parsedStatement.getSqlWithoutComments());
"Statement is not an update statement: " + parsedStatement.getSql());
}

@Override
Expand All @@ -1809,7 +1805,7 @@ public ApiFuture<Long> executeUpdateAsync(Statement update) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.FAILED_PRECONDITION,
"DML statement with returning clause cannot be executed using executeUpdateAsync: "
+ parsedStatement.getSqlWithoutComments()
+ parsedStatement.getSql()
+ ". Please use executeQueryAsync instead.");
}
return internalExecuteUpdateAsync(CallType.ASYNC, parsedStatement);
Expand All @@ -1822,7 +1818,7 @@ public ApiFuture<Long> executeUpdateAsync(Statement update) {
}
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Statement is not an update statement: " + parsedStatement.getSqlWithoutComments());
"Statement is not an update statement: " + parsedStatement.getSql());
}

@Override
Expand All @@ -1845,7 +1841,7 @@ public ResultSetStats analyzeUpdate(Statement update, QueryAnalyzeMode analyzeMo
}
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Statement is not an update statement: " + parsedStatement.getSqlWithoutComments());
"Statement is not an update statement: " + parsedStatement.getSql());
}

@Override
Expand All @@ -1867,7 +1863,7 @@ public ResultSet analyzeUpdateStatement(
}
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Statement is not an update statement: " + parsedStatement.getSqlWithoutComments());
"Statement is not an update statement: " + parsedStatement.getSql());
}

@Override
Expand Down Expand Up @@ -1899,7 +1895,7 @@ private List<ParsedStatement> parseUpdateStatements(Iterable<Statement> updates)
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"The batch update list contains a statement that is not an update statement: "
+ parsedStatement.getSqlWithoutComments());
+ parsedStatement.getSql());
}
}
return parsedStatements;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.cloud.spanner.connection;

import com.google.cloud.spanner.Dialect;
import com.google.cloud.spanner.Options.RpcPriority;
import com.google.cloud.spanner.Statement;
import com.google.cloud.spanner.TimestampBound;
Expand All @@ -36,6 +37,7 @@
* <p>The client side statements are defined in the ClientSideStatements.json file.
*/
interface ConnectionStatementExecutor {
Dialect getDialect();

StatementResult statementSetAutocommit(Boolean autocommit);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ ConnectionImpl getConnection() {
return connection;
}

@Override
public Dialect getDialect() {
return getConnection().getDialect();
}

@Override
public StatementResult statementSetAutocommit(Boolean autocommit) {
Preconditions.checkNotNull(autocommit);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,11 @@ public ApiFuture<Void> executeDdlAsync(CallType callType, ParsedStatement ddl) {
"The batch is no longer active and cannot be used for further statements");
Preconditions.checkArgument(
ddl.getType() == StatementType.DDL,
"Only DDL statements are allowed. \""
+ ddl.getSqlWithoutComments()
+ "\" is not a DDL-statement.");
"Only DDL statements are allowed. \"" + ddl.getSql() + "\" is not a DDL-statement.");
Preconditions.checkArgument(
!DdlClient.isCreateDatabaseStatement(ddl.getSqlWithoutComments()),
!DdlClient.isCreateDatabaseStatement(dbClient.getDialect(), ddl.getSql()),
"CREATE DATABASE is not supported in DDL batches.");
statements.add(ddl.getSqlWithoutComments());
statements.add(ddl.getSql());
return ApiFutures.immediateFuture(null);
}

Expand Down
Loading
Loading