Skip to content

Commit ed6a34e

Browse files
committed
chore: rename sql statements + add tests for empty results
1 parent 3ae95e3 commit ed6a34e

File tree

8 files changed

+133
-68
lines changed

8 files changed

+133
-68
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ StatementResult statementSetPgSessionCharacteristicsTransactionMode(
131131

132132
StatementResult statementSetDataBoostEnabled(Boolean dataBoostEnabled);
133133

134-
StatementResult statementShowAlwaysUsePartitionedQueries();
134+
StatementResult statementShowAutoPartitionMode();
135135

136-
StatementResult statementSetAlwaysUsePartitionedQueries(Boolean alwaysUsePartitionedQueries);
136+
StatementResult statementSetAutoPartitionMode(Boolean autoPartitionMode);
137137

138138
StatementResult statementShowMaxPartitions();
139139

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/ConnectionStatementExecutorImpl.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.COMMIT;
2323
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.ROLLBACK;
2424
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.RUN_BATCH;
25-
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_ALWAYS_USE_PARTITIONED_QUERIES;
2625
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_AUTOCOMMIT;
2726
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_AUTOCOMMIT_DML_MODE;
27+
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_AUTO_PARTITION_MODE;
2828
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_DATA_BOOST_ENABLED;
2929
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_DEFAULT_TRANSACTION_ISOLATION;
3030
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_DELAY_TRANSACTION_START_UNTIL_FIRST_WRITE;
@@ -42,9 +42,9 @@
4242
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_STATEMENT_TIMEOUT;
4343
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_TRANSACTION_MODE;
4444
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SET_TRANSACTION_TAG;
45-
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_ALWAYS_USE_PARTITIONED_QUERIES;
4645
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_AUTOCOMMIT;
4746
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_AUTOCOMMIT_DML_MODE;
47+
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_AUTO_PARTITION_MODE;
4848
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_COMMIT_RESPONSE;
4949
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_COMMIT_TIMESTAMP;
5050
import static com.google.cloud.spanner.connection.StatementResult.ClientSideStatementType.SHOW_DATA_BOOST_ENABLED;
@@ -518,18 +518,17 @@ public StatementResult statementSetDataBoostEnabled(Boolean dataBoostEnabled) {
518518
}
519519

520520
@Override
521-
public StatementResult statementShowAlwaysUsePartitionedQueries() {
521+
public StatementResult statementShowAutoPartitionMode() {
522522
return resultSet(
523-
String.format("%sALWAYS_USE_PARTITIONED_QUERIES", getNamespace(connection.getDialect())),
523+
String.format("%sAUTO_PARTITION_MODE", getNamespace(connection.getDialect())),
524524
getConnection().isAutoPartitionMode(),
525-
SHOW_ALWAYS_USE_PARTITIONED_QUERIES);
525+
SHOW_AUTO_PARTITION_MODE);
526526
}
527527

528528
@Override
529-
public StatementResult statementSetAlwaysUsePartitionedQueries(
530-
Boolean alwaysUsePartitionedQueries) {
531-
getConnection().setAutoPartitionMode(Preconditions.checkNotNull(alwaysUsePartitionedQueries));
532-
return noResult(SET_ALWAYS_USE_PARTITIONED_QUERIES);
529+
public StatementResult statementSetAutoPartitionMode(Boolean autoPartitionMode) {
530+
getConnection().setAutoPartitionMode(Preconditions.checkNotNull(autoPartitionMode));
531+
return noResult(SET_AUTO_PARTITION_MODE);
533532
}
534533

535534
@Override

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/MergedResultSet.java

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,56 @@ boolean isFinished() {
149149
}
150150
}
151151

152-
static class RowProducer implements Supplier<Struct> {
152+
interface RowProducer extends Supplier<Struct> {
153+
boolean nextRow() throws Throwable;
154+
155+
void close();
156+
157+
Type getType();
158+
159+
ResultSetMetadata getMetadata();
160+
161+
int getNumPartitions();
162+
163+
int getParallelism();
164+
}
165+
166+
static class EmptyRowProducer implements RowProducer {
167+
@Override
168+
public Struct get() {
169+
return Struct.newBuilder().build();
170+
}
171+
172+
@Override
173+
public boolean nextRow() {
174+
return false;
175+
}
176+
177+
@Override
178+
public Type getType() {
179+
return Type.struct();
180+
}
181+
182+
@Override
183+
public ResultSetMetadata getMetadata() {
184+
return ResultSetMetadata.getDefaultInstance();
185+
}
186+
187+
@Override
188+
public int getNumPartitions() {
189+
return 0;
190+
}
191+
192+
@Override
193+
public int getParallelism() {
194+
return 0;
195+
}
196+
197+
@Override
198+
public void close() {}
199+
}
200+
201+
private static class RowProducerImpl implements RowProducer {
153202
/** The maximum number of rows that we will cache per thread that is fetching rows. */
154203
private static final int QUEUE_SIZE_PER_WORKER = 32;
155204

@@ -163,8 +212,10 @@ static class RowProducer implements Supplier<Struct> {
163212
private Struct currentRow;
164213
private Throwable exception;
165214

166-
RowProducer(Connection connection, List<String> partitions, int maxParallelism) {
215+
RowProducerImpl(Connection connection, List<String> partitions, int maxParallelism) {
167216
Preconditions.checkArgument(maxParallelism >= 0, "maxParallelism must be >= 0");
217+
Preconditions.checkArgument(
218+
!Preconditions.checkNotNull(partitions).isEmpty(), "partitions must not be empty");
168219
if (maxParallelism == 0) {
169220
// Dynamically determine parallelism.
170221
this.parallelism = Math.min(partitions.size(), Runtime.getRuntime().availableProcessors());
@@ -195,14 +246,16 @@ static class RowProducer implements Supplier<Struct> {
195246
this.executor.shutdown();
196247
}
197248

198-
void close() {
249+
@Override
250+
public void close() {
199251
this.partitionExecutors.forEach(partitionExecutor -> partitionExecutor.shouldStop.set(true));
200252
// shutdownNow will interrupt any running tasks and then shut down directly.
201253
// This will also cancel any queries that might be running.
202254
this.executor.shutdownNow();
203255
}
204256

205-
boolean nextRow() throws Throwable {
257+
@Override
258+
public boolean nextRow() throws Throwable {
206259
if (this.exception != null) {
207260
throw this.exception;
208261
}
@@ -255,6 +308,16 @@ public ResultSetMetadata getMetadata() {
255308
return metadata;
256309
}
257310

311+
@Override
312+
public int getNumPartitions() {
313+
return partitionExecutors.size();
314+
}
315+
316+
@Override
317+
public int getParallelism() {
318+
return parallelism;
319+
}
320+
258321
public Type getType() {
259322
checkState(type != null, "next() call required");
260323
return type;
@@ -266,10 +329,13 @@ public Type getType() {
266329
private boolean closed;
267330

268331
MergedResultSet(Connection connection, List<String> partitions, int maxParallelism) {
269-
this(new RowProducer(connection, partitions, maxParallelism));
332+
this(
333+
Preconditions.checkNotNull(partitions).isEmpty()
334+
? new EmptyRowProducer()
335+
: new RowProducerImpl(connection, partitions, maxParallelism));
270336
}
271337

272-
MergedResultSet(RowProducer rowProducer) {
338+
private MergedResultSet(RowProducer rowProducer) {
273339
super(rowProducer);
274340
this.rowProducer = rowProducer;
275341
}
@@ -323,11 +389,11 @@ public Type getType() {
323389

324390
@Override
325391
public int getNumPartitions() {
326-
return rowProducer.partitionExecutors.size();
392+
return rowProducer.getNumPartitions();
327393
}
328394

329395
@Override
330396
public int getParallelism() {
331-
return rowProducer.parallelism;
397+
return rowProducer.getParallelism();
332398
}
333399
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/StatementResult.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ enum ClientSideStatementType {
9191
SET_SAVEPOINT_SUPPORT,
9292
SHOW_DATA_BOOST_ENABLED,
9393
SET_DATA_BOOST_ENABLED,
94-
SHOW_ALWAYS_USE_PARTITIONED_QUERIES,
95-
SET_ALWAYS_USE_PARTITIONED_QUERIES,
94+
SHOW_AUTO_PARTITION_MODE,
95+
SET_AUTO_PARTITION_MODE,
9696
SHOW_MAX_PARTITIONS,
9797
SET_MAX_PARTITIONS,
9898
SHOW_MAX_PARTITIONED_PARALLELISM,

google-cloud-spanner/src/main/resources/com/google/cloud/spanner/connection/ClientSideStatements.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -527,24 +527,24 @@
527527
}
528528
},
529529
{
530-
"name": "SHOW VARIABLE ALWAYS_USE_PARTITIONED_QUERIES",
530+
"name": "SHOW VARIABLE AUTO_PARTITION_MODE",
531531
"executorName": "ClientSideStatementNoParamExecutor",
532532
"resultType": "RESULT_SET",
533-
"statementType": "SHOW_ALWAYS_USE_PARTITIONED_QUERIES",
534-
"regex": "(?is)\\A\\s*show\\s+variable\\s+always_use_partitioned_queries\\s*\\z",
535-
"method": "statementShowAlwaysUsePartitionedQueries",
536-
"exampleStatements": ["show variable always_use_partitioned_queries"]
533+
"statementType": "SHOW_AUTO_PARTITION_MODE",
534+
"regex": "(?is)\\A\\s*show\\s+variable\\s+auto_partition_mode\\s*\\z",
535+
"method": "statementShowAutoPartitionMode",
536+
"exampleStatements": ["show variable auto_partition_mode"]
537537
},
538538
{
539-
"name": "SET ALWAYS_USE_PARTITIONED_QUERIES = TRUE|FALSE",
539+
"name": "SET AUTO_PARTITION_MODE = TRUE|FALSE",
540540
"executorName": "ClientSideStatementSetExecutor",
541541
"resultType": "NO_RESULT",
542-
"statementType": "SET_ALWAYS_USE_PARTITIONED_QUERIES",
543-
"regex": "(?is)\\A\\s*set\\s+always_use_partitioned_queries\\s*(?:=)\\s*(.*)\\z",
544-
"method": "statementSetAlwaysUsePartitionedQueries",
545-
"exampleStatements": ["set always_use_partitioned_queries = true", "set always_use_partitioned_queries = false"],
542+
"statementType": "SET_AUTO_PARTITION_MODE",
543+
"regex": "(?is)\\A\\s*set\\s+auto_partition_mode\\s*(?:=)\\s*(.*)\\z",
544+
"method": "statementSetAutoPartitionMode",
545+
"exampleStatements": ["set auto_partition_mode = true", "set auto_partition_mode = false"],
546546
"setStatement": {
547-
"propertyName": "ALWAYS_USE_PARTITIONED_QUERIES",
547+
"propertyName": "AUTO_PARTITION_MODE",
548548
"separator": "=",
549549
"allowedValues": "(TRUE|FALSE)",
550550
"converterName": "ClientSideStatementValueConverters$BooleanConverter"

google-cloud-spanner/src/main/resources/com/google/cloud/spanner/connection/PG_ClientSideStatements.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -715,24 +715,24 @@
715715
}
716716
},
717717
{
718-
"name": "SHOW [VARIABLE] SPANNER.ALWAYS_USE_PARTITIONED_QUERIES",
718+
"name": "SHOW [VARIABLE] SPANNER.AUTO_PARTITION_MODE",
719719
"executorName": "ClientSideStatementNoParamExecutor",
720720
"resultType": "RESULT_SET",
721-
"statementType": "SHOW_ALWAYS_USE_PARTITIONED_QUERIES",
722-
"regex": "(?is)\\A\\s*show\\s+(?:variable\\s+)?spanner\\.always_use_partitioned_queries\\s*\\z",
723-
"method": "statementShowAlwaysUsePartitionedQueries",
724-
"exampleStatements": ["show spanner.always_use_partitioned_queries","show variable spanner.always_use_partitioned_queries"]
721+
"statementType": "SHOW_AUTO_PARTITION_MODE",
722+
"regex": "(?is)\\A\\s*show\\s+(?:variable\\s+)?spanner\\.auto_partition_mode\\s*\\z",
723+
"method": "statementShowAutoPartitionMode",
724+
"exampleStatements": ["show spanner.auto_partition_mode","show variable spanner.auto_partition_mode"]
725725
},
726726
{
727-
"name": "SET SPANNER.ALWAYS_USE_PARTITIONED_QUERIES = TRUE|FALSE",
727+
"name": "SET SPANNER.AUTO_PARTITION_MODE = TRUE|FALSE",
728728
"executorName": "ClientSideStatementSetExecutor",
729729
"resultType": "NO_RESULT",
730-
"statementType": "SET_ALWAYS_USE_PARTITIONED_QUERIES",
731-
"regex": "(?is)\\A\\s*set\\s+spanner\\.always_use_partitioned_queries(?:\\s*=\\s*|\\s+to\\s+)(.*)\\z",
732-
"method": "statementSetAlwaysUsePartitionedQueries",
733-
"exampleStatements": ["set spanner.always_use_partitioned_queries = true", "set spanner.always_use_partitioned_queries = false", "set spanner.always_use_partitioned_queries to true", "set spanner.always_use_partitioned_queries to false"],
730+
"statementType": "SET_AUTO_PARTITION_MODE",
731+
"regex": "(?is)\\A\\s*set\\s+spanner\\.auto_partition_mode(?:\\s*=\\s*|\\s+to\\s+)(.*)\\z",
732+
"method": "statementSetAutoPartitionMode",
733+
"exampleStatements": ["set spanner.auto_partition_mode = true", "set spanner.auto_partition_mode = false", "set spanner.auto_partition_mode to true", "set spanner.auto_partition_mode to false"],
734734
"setStatement": {
735-
"propertyName": "SPANNER.ALWAYS_USE_PARTITIONED_QUERIES",
735+
"propertyName": "SPANNER.AUTO_PARTITION_MODE",
736736
"separator": "(?:=|\\s+TO\\s+)",
737737
"allowedValues": "(TRUE|FALSE)",
738738
"converterName": "ClientSideStatementValueConverters$BooleanConverter"

google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/MergedResultSetTest.java

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ public boolean next() {
9191
@Parameters(name = "numPartitions = {0}, maxRowsPerPartition = {1}, maxParallelism = {2}")
9292
public static Collection<Object[]> parameters() {
9393
List<Object[]> params = new ArrayList<>();
94-
for (int numPartitions : new int[] {1, 2, 5, 8}) {
95-
for (int maxRowsPerPartition : new int[] {1, 5, 10, 20}) {
94+
for (int numPartitions : new int[] {0, 1, 2, 5, 8}) {
95+
for (int maxRowsPerPartition : new int[] {0, 1, 5, 10, 100}) {
9696
for (int maxParallelism : new int[] {0, 1, 2, 4, 8}) {
9797
params.add(new Object[] {numPartitions, maxRowsPerPartition, maxParallelism});
9898
}
@@ -110,12 +110,12 @@ private MockedResults setupResults(boolean withErrors) {
110110
for (int index = 0; index < numPartitions; index++) {
111111
String partition = String.valueOf(index);
112112
partitions.add(partition);
113-
int numRows = random.nextInt(maxRowsPerPartition) + 1;
113+
int numRows = maxRowsPerPartition == 0 ? 0 : random.nextInt(maxRowsPerPartition) + 1;
114114
RandomResultSetGenerator generator = new RandomResultSetGenerator(numRows);
115115
com.google.spanner.v1.ResultSet proto = generator.generate();
116116
if (withErrors) {
117117
// Add a random error somewhere in the result.
118-
int errorIndex = random.nextInt(numRows);
118+
int errorIndex = numRows == 0 ? 0 : random.nextInt(numRows);
119119
minErrorIndex = Math.min(minErrorIndex, errorIndex);
120120
when(connection.runPartition(partition))
121121
.thenReturn(new ResultSetWithError(ResultSetsHelper.fromProto(proto), errorIndex));
@@ -158,22 +158,24 @@ public void testResultSetStopsAfterFirstError() {
158158
MockedResults results = setupResults(true);
159159
try (MergedResultSet resultSet =
160160
new MergedResultSet(results.connection, results.partitions, maxParallelism)) {
161-
AtomicInteger rowCount = new AtomicInteger();
162-
SpannerException exception =
163-
assertThrows(
164-
SpannerException.class,
165-
() -> {
166-
while (resultSet.next()) {
167-
rowCount.getAndIncrement();
168-
}
169-
});
170-
assertEquals(ErrorCode.INTERNAL, exception.getErrorCode());
171-
assertTrue(exception.getMessage(), exception.getMessage().contains("test error"));
172-
// The result set should continue to throw the same error if we continue to call next().
173-
SpannerException nextException = assertThrows(SpannerException.class, resultSet::next);
174-
assertEquals(exception, nextException);
175-
// We should see at least minErrorIndex rows before an error.
176-
assertTrue(rowCount.get() >= results.minErrorIndex);
161+
if (numPartitions > 0) {
162+
AtomicInteger rowCount = new AtomicInteger();
163+
SpannerException exception =
164+
assertThrows(
165+
SpannerException.class,
166+
() -> {
167+
while (resultSet.next()) {
168+
rowCount.getAndIncrement();
169+
}
170+
});
171+
assertEquals(ErrorCode.INTERNAL, exception.getErrorCode());
172+
assertTrue(exception.getMessage(), exception.getMessage().contains("test error"));
173+
// The result set should continue to throw the same error if we continue to call next().
174+
SpannerException nextException = assertThrows(SpannerException.class, resultSet::next);
175+
assertEquals(exception, nextException);
176+
// We should see at least minErrorIndex rows before an error.
177+
assertTrue(rowCount.get() >= results.minErrorIndex);
178+
}
177179
}
178180
}
179181

google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/PartitionedQueryMockServerTest.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ public void testRunPartitionedQueryWithMaxParallelism() {
532532
}
533533

534534
@Test
535-
public void testAlwaysUsePartitionedQueries() {
535+
public void testAutoPartitionMode() {
536536
int generatedRowCount = 5;
537537
RandomResultSetGenerator generator = new RandomResultSetGenerator(generatedRowCount);
538538
Statement statement =
@@ -548,12 +548,10 @@ public void testAlwaysUsePartitionedQueries() {
548548
connection.setAutocommit(true);
549549
connection.setMaxPartitions(maxPartitions);
550550

551-
connection.execute(
552-
Statement.of(String.format("set %salways_use_partitioned_queries=true", prefix)));
551+
connection.execute(Statement.of(String.format("set %sauto_partition_mode=true", prefix)));
553552
try (ResultSet resultSet =
554553
connection.executeQuery(
555-
Statement.of(
556-
String.format("show variable %salways_use_partitioned_queries", prefix)))) {
554+
Statement.of(String.format("show variable %sauto_partition_mode", prefix)))) {
557555
assertTrue(resultSet.next());
558556
assertTrue(resultSet.getBoolean(0));
559557
assertFalse(resultSet.next());

0 commit comments

Comments
 (0)