@@ -108,10 +108,12 @@ public static Object[] parameters() {
108108 @ Parameter
109109 public StatementExecutorType statementExecutorType ;
110110
111- protected ITConnection createConnection () {
111+ protected ITConnection createConnection (String additionalUrlOptions ) {
112+ String urlSuffix =
113+ ";trackSessionLeaks=false" + (additionalUrlOptions == null ? "" : additionalUrlOptions );
112114 ConnectionOptions options =
113115 ConnectionOptions .newBuilder ()
114- .setUri (getBaseUrl () + ";trackSessionLeaks=false" )
116+ .setUri (getBaseUrl () + urlSuffix )
115117 .setStatementExecutorType (statementExecutorType )
116118 .setConfigurator (
117119 optionsConfigurator -> {
@@ -135,6 +137,10 @@ protected ITConnection createConnection() {
135137 return createITConnection (options );
136138 }
137139
140+ protected ITConnection createConnection () {
141+ return createConnection ("" );
142+ }
143+
138144 @ Before
139145 public void setup () {
140146 // Set up a connection and get the dialect to ensure that the auto-detect-dialect query has
@@ -169,6 +175,22 @@ public void testTimeoutExceptionReadOnlyAutocommit() {
169175 }
170176 }
171177
178+ @ Test
179+ public void testUrlTimeoutExceptionReadOnlyAutocommit () {
180+ mockSpanner .setExecuteStreamingSqlExecutionTime (
181+ SimulatedExecutionTime .ofMinimumAndRandomTime (EXECUTION_TIME_SLOW_STATEMENT , 0 ));
182+
183+ try (Connection connection =
184+ createConnection (";statement_timeout='" + TIMEOUT_FOR_SLOW_STATEMENTS + "ms'" )) {
185+ connection .setAutocommit (true );
186+ connection .setReadOnly (true );
187+ SpannerException e =
188+ assertThrows (
189+ SpannerException .class , () -> connection .executeQuery (SELECT_RANDOM_STATEMENT ));
190+ assertEquals (ErrorCode .DEADLINE_EXCEEDED , e .getErrorCode ());
191+ }
192+ }
193+
172194 @ Test
173195 public void testTimeoutExceptionReadOnlyAutocommitMultipleStatements () {
174196 mockSpanner .setExecuteStreamingSqlExecutionTime (
@@ -277,6 +299,32 @@ public void testTimeoutExceptionReadWriteAutocommitMultipleStatements() {
277299 }
278300 }
279301
302+ @ Test
303+ public void testUrlStatementTimeoutOverrideToSucceed () {
304+ mockSpanner .setExecuteStreamingSqlExecutionTime (
305+ SimulatedExecutionTime .ofMinimumAndRandomTime (EXECUTION_TIME_SLOW_STATEMENT , 0 ));
306+
307+ try (Connection connection =
308+ createConnection (";statement_timeout='" + TIMEOUT_FOR_SLOW_STATEMENTS + "ms'" )) {
309+ connection .setAutocommit (true );
310+ for (int i = 0 ; i < 2 ; i ++) {
311+ SpannerException e =
312+ assertThrows (
313+ SpannerException .class , () -> connection .executeQuery (SELECT_RANDOM_STATEMENT ));
314+ assertEquals (ErrorCode .DEADLINE_EXCEEDED , e .getErrorCode ());
315+ }
316+
317+ // Remove slow behavior and verify a fast query succeeds after overriding the timeout.
318+ mockSpanner .removeAllExecutionTimes ();
319+ mockSpanner .setExecuteStreamingSqlExecutionTime (
320+ SimulatedExecutionTime .ofMinimumAndRandomTime (500 , 0 ));
321+ connection .setStatementTimeout (TIMEOUT_FOR_FAST_STATEMENTS , TimeUnit .MILLISECONDS );
322+ try (ResultSet rs = connection .executeQuery (SELECT_RANDOM_STATEMENT )) {
323+ assertNotNull (rs );
324+ }
325+ }
326+ }
327+
280328 @ Test
281329 public void testTimeoutExceptionReadWriteAutocommitSlowUpdate () {
282330 mockSpanner .setExecuteSqlExecutionTime (
0 commit comments