Skip to content

Commit d1f3bc1

Browse files
Merge branch 'main' into renovate/com.google.api.grpc-proto-google-cloud-monitoring-v3-3.x
2 parents df90a54 + db0ed07 commit d1f3bc1

File tree

15 files changed

+443
-545
lines changed

15 files changed

+443
-545
lines changed

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,4 +1008,24 @@
10081008
<className>com/google/cloud/spanner/TransactionManager</className>
10091009
<method>com.google.cloud.spanner.TransactionContext begin(com.google.cloud.spanner.AbortedException)</method>
10101010
</difference>
1011+
<difference>
1012+
<differenceType>7012</differenceType>
1013+
<className>com/google/cloud/spanner/StructReader</className>
1014+
<method>java.lang.Object getOrNull(int, java.util.function.BiFunction)</method>
1015+
</difference>
1016+
<difference>
1017+
<differenceType>7012</differenceType>
1018+
<className>com/google/cloud/spanner/StructReader</className>
1019+
<method>java.lang.Object getOrNull(java.lang.String, java.util.function.BiFunction)</method>
1020+
</difference>
1021+
<difference>
1022+
<differenceType>7012</differenceType>
1023+
<className>com/google/cloud/spanner/StructReader</className>
1024+
<method>java.lang.Object getOrDefault(int, java.util.function.BiFunction, java.lang.Object)</method>
1025+
</difference>
1026+
<difference>
1027+
<differenceType>7012</differenceType>
1028+
<className>com/google/cloud/spanner/StructReader</className>
1029+
<method>java.lang.Object getOrDefault(java.lang.String, java.util.function.BiFunction, java.lang.Object)</method>
1030+
</difference>
10111031
</differences>

google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,12 +1088,20 @@ void appendToOptions(Options options) {
10881088

10891089
@Override
10901090
public int hashCode() {
1091-
return RequestIdOption.class.hashCode();
1091+
return this.reqId.hashCode();
10921092
}
10931093

10941094
@Override
10951095
public boolean equals(Object o) {
1096-
return o instanceof RequestIdOption;
1096+
// instanceof for a null object returns false.
1097+
if (!(o instanceof RequestIdOption)) {
1098+
return false;
1099+
}
1100+
RequestIdOption other = (RequestIdOption) o;
1101+
if (this.reqId == null || other.reqId == null) {
1102+
return this.reqId == null && other.reqId == null;
1103+
}
1104+
return this.reqId.equals(other.reqId);
10971105
}
10981106
}
10991107
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ public CommitResponse writeAtLeastOnceWithOptions(
319319
private XGoogSpannerRequestId reqIdOrFresh(Options options) {
320320
XGoogSpannerRequestId reqId = options.reqId();
321321
if (reqId == null) {
322-
reqId = this.getRequestIdCreator().nextRequestId(1 /* TODO: channelId */, 1);
322+
reqId = this.getRequestIdCreator().nextRequestId(this.getChannel(), 1);
323323
}
324324
return reqId;
325325
}
@@ -464,17 +464,15 @@ public AsyncTransactionManagerImpl transactionManagerAsync(TransactionOption...
464464

465465
@Override
466466
public ApiFuture<Empty> asyncClose() {
467-
XGoogSpannerRequestId reqId =
468-
this.getRequestIdCreator().nextRequestId(1 /* TODO: channelId */, 0);
467+
XGoogSpannerRequestId reqId = this.getRequestIdCreator().nextRequestId(this.getChannel(), 0);
469468
return spanner.getRpc().asyncDeleteSession(getName(), reqId.withOptions(getOptions()));
470469
}
471470

472471
@Override
473472
public void close() {
474473
ISpan span = tracer.spanBuilder(SpannerImpl.DELETE_SESSION);
475474
try (IScope s = tracer.withSpan(span)) {
476-
XGoogSpannerRequestId reqId =
477-
this.getRequestIdCreator().nextRequestId(1 /* TODO: channelId */, 0);
475+
XGoogSpannerRequestId reqId = this.getRequestIdCreator().nextRequestId(this.getChannel(), 0);
478476
spanner.getRpc().deleteSession(getName(), reqId.withOptions(getOptions()));
479477
} catch (RuntimeException e) {
480478
span.setStatus(e);
@@ -505,8 +503,7 @@ ApiFuture<Transaction> beginTransactionAsync(
505503
}
506504
final BeginTransactionRequest request = requestBuilder.build();
507505
final ApiFuture<Transaction> requestFuture;
508-
XGoogSpannerRequestId reqId =
509-
this.getRequestIdCreator().nextRequestId(1 /* TODO: channelId */, 1);
506+
XGoogSpannerRequestId reqId = this.getRequestIdCreator().nextRequestId(this.getChannel(), 1);
510507
try (IScope ignore = tracer.withSpan(span)) {
511508
requestFuture =
512509
spanner
@@ -597,4 +594,12 @@ public void setRequestIdCreator(XGoogSpannerRequestId.RequestIdCreator creator)
597594
public XGoogSpannerRequestId.RequestIdCreator getRequestIdCreator() {
598595
return this.requestIdCreator;
599596
}
597+
598+
int getChannel() {
599+
if (getIsMultiplexed()) {
600+
return 0;
601+
}
602+
Long channelHint = (Long) this.getOptions().get(SpannerRpc.Option.CHANNEL_HINT);
603+
return (int) (channelHint % this.spanner.getOptions().getNumChannels());
604+
}
600605
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/StructReader.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.math.BigDecimal;
2525
import java.util.List;
2626
import java.util.UUID;
27+
import java.util.function.BiFunction;
2728
import java.util.function.Function;
2829

2930
/**
@@ -176,6 +177,60 @@ default float getFloat(String columnName) {
176177
*/
177178
String getString(String columnName);
178179

180+
/**
181+
* @param columnIndex index of the column
182+
* @return the value of a column with type T or null if the column contains a null value
183+
* <p>Example
184+
* <pre>{@code
185+
* Struct row = ...
186+
* String name = row.getOrNull(1, StructReader::getString)
187+
* }</pre>
188+
*/
189+
default <T> T getOrNull(int columnIndex, BiFunction<StructReader, Integer, T> function) {
190+
return isNull(columnIndex) ? null : function.apply(this, columnIndex);
191+
}
192+
193+
/**
194+
* @param columnName index of the column
195+
* @return the value of a column with type T or null if the column contains a null value
196+
* <p>Example
197+
* <pre>{@code
198+
* Struct row = ...
199+
* String name = row.getOrNull("name", StructReader::getString)
200+
* }</pre>
201+
*/
202+
default <T> T getOrNull(String columnName, BiFunction<StructReader, String, T> function) {
203+
return isNull(columnName) ? null : function.apply(this, columnName);
204+
}
205+
206+
/**
207+
* @param columnIndex index of the column
208+
* @return the value of a column with type T, or the given default if the column value is null
209+
* <p>Example
210+
* <pre>{@code
211+
* Struct row = ...
212+
* String name = row.getOrDefault(1, StructReader::getString, "")
213+
* }</pre>
214+
*/
215+
default <T> T getOrDefault(
216+
int columnIndex, BiFunction<StructReader, Integer, T> function, T defaultValue) {
217+
return isNull(columnIndex) ? defaultValue : function.apply(this, columnIndex);
218+
}
219+
220+
/**
221+
* @param columnName name of the column
222+
* @return the value of a column with type T, or the given default if the column value is null
223+
* <p>Example
224+
* <pre>{@code
225+
* Struct row = ...
226+
* String name = row.getOrDefault("name", StructReader::getString, "")
227+
* }</pre>
228+
*/
229+
default <T> T getOrDefault(
230+
String columnName, BiFunction<StructReader, String, T> function, T defaultValue) {
231+
return isNull(columnName) ? defaultValue : function.apply(this, columnName);
232+
}
233+
179234
/**
180235
* @param columnIndex index of the column
181236
* @return the value of a non-{@code NULL} column with type {@link Type#json()}.

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,8 @@ public Duration convert(String value) {
248248
} else {
249249
duration = Duration.ofMillis(Long.parseLong(value.trim()));
250250
}
251-
if (duration.isZero()) {
251+
// Converters should return null for invalid values.
252+
if (duration.isNegative()) {
252253
return null;
253254
}
254255
return duration;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ public StatementResult statementShowReturnCommitStats() {
361361

362362
@Override
363363
public StatementResult statementSetMaxCommitDelay(Duration duration) {
364-
getConnection().setMaxCommitDelay(duration == null || duration.isZero() ? null : duration);
364+
getConnection().setMaxCommitDelay(duration);
365365
return noResult(SET_MAX_COMMIT_DELAY);
366366
}
367367

google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,22 @@ public void testRequestId() {
900900
assertThat(option3.toString()).doesNotContain("requestId");
901901
}
902902

903+
@Test
904+
public void testRequestIdOptionEqualsAndHashCode() {
905+
XGoogSpannerRequestId reqId1 = XGoogSpannerRequestId.of(1, 2, 3, 4);
906+
XGoogSpannerRequestId reqId2 = XGoogSpannerRequestId.of(2, 3, 4, 5);
907+
Options.RequestIdOption opt1 = Options.requestId(reqId1);
908+
Options.RequestIdOption opt1Prime = Options.requestId(reqId1);
909+
Options.RequestIdOption opt2 = Options.requestId(reqId2);
910+
911+
assertTrue(opt1.equals(opt1));
912+
assertTrue(opt1.equals(opt1Prime));
913+
assertEquals(opt1.hashCode(), opt1Prime.hashCode());
914+
assertFalse(opt1.equals(opt2));
915+
assertNotEquals(opt1, opt2);
916+
assertNotEquals(opt1.hashCode(), opt2.hashCode());
917+
}
918+
903919
@Test
904920
public void testOptions_WithMultipleDifferentRequestIds() {
905921
XGoogSpannerRequestId reqId1 = XGoogSpannerRequestId.of(1, 1, 1, 1);

google-cloud-spanner/src/test/java/com/google/cloud/spanner/StructTest.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,48 @@ public void builder() {
5757
assertThat(struct.getLong(1)).isEqualTo(2);
5858
}
5959

60+
@Test
61+
public void getOrNullTests() {
62+
Struct struct =
63+
Struct.newBuilder()
64+
.set("f1")
65+
.to("x")
66+
.set("f2")
67+
.to(2)
68+
.set("f3")
69+
.to(Value.bool(null))
70+
.build();
71+
String column1 = struct.getOrNull(0, StructReader::getString);
72+
assertThat(column1).isEqualTo("x");
73+
74+
Long column2 = struct.getOrNull(1, StructReader::getLong);
75+
assertThat(column2).isEqualTo(2);
76+
77+
String column3 = struct.getOrNull("f3", StructReader::getString);
78+
assertThat(column3).isNull();
79+
}
80+
81+
@Test
82+
public void getOrDefaultTests() {
83+
Struct struct =
84+
Struct.newBuilder()
85+
.set("f1")
86+
.to("x")
87+
.set("f2")
88+
.to(2)
89+
.set("f3")
90+
.to(Value.bool(null))
91+
.build();
92+
String column1 = struct.getOrDefault(0, StructReader::getString, "");
93+
assertThat(column1).isEqualTo("x");
94+
95+
Long column2 = struct.getOrDefault("f2", StructReader::getLong, -1L);
96+
assertThat(column2).isEqualTo(2);
97+
98+
String column3 = struct.getOrDefault(2, StructReader::getString, "");
99+
assertThat(column3).isEqualTo("");
100+
}
101+
60102
@Test
61103
public void duplicateFields() {
62104
// Duplicate fields are allowed - some SQL queries produce this type of value.

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,14 @@ public void testSetStatementTimeout() {
276276
assertThat(connection.hasStatementTimeout(), is(false));
277277
boolean gotException = false;
278278
try {
279-
log("@EXPECT EXCEPTION INVALID_ARGUMENT");
279+
// log("@EXPECT EXCEPTION INVALID_ARGUMENT");
280280
log(String.format("SET STATEMENT_TIMEOUT='0%s';", getTimeUnitAbbreviation(unit)));
281-
connection.setStatementTimeout(0L, unit);
281+
connection.clearStatementTimeout();
282+
// connection.setStatementTimeout(0L, unit);
282283
} catch (IllegalArgumentException e) {
283284
gotException = true;
284285
}
285-
assertThat(gotException, is(true));
286+
assertThat(gotException, is(false));
286287
log(
287288
String.format(
288289
"@EXPECT RESULT_SET 'STATEMENT_TIMEOUT',%s",

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void testConvert() throws CompileException {
4242
DurationConverter converter = new DurationConverter(allowedValues);
4343
assertThat(converter.convert("'100ms'"), is(equalTo(Duration.ofMillis(100L))));
4444
assertThat(converter.convert("100"), is(equalTo(Duration.ofMillis(100))));
45-
assertThat(converter.convert("'0ms'"), is(nullValue()));
45+
assertThat(converter.convert("'0ms'"), is(Duration.ZERO));
4646
assertThat(converter.convert("'-100ms'"), is(nullValue()));
4747
assertThat(
4848
converter.convert("'315576000000000ms'"), is(equalTo(Duration.ofSeconds(315576000000L))));

0 commit comments

Comments
 (0)