Skip to content

Commit ded663c

Browse files
committed
fix(spanner): Fix the start timestamp > end timestamp issue for change
stream initial query.
1 parent 8139b1e commit ded663c

1 file changed

Lines changed: 23 additions & 4 deletions

File tree

java-spanner/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,14 +2462,19 @@ private Status executeExecuteChangeStreamQuery(
24622462
// For initial partition query (no partition token) we simulate precision of the timestamp
24632463
// in nanoseconds as that's closer inlined with the production client code.
24642464

2465-
String startTime =
2466-
timestampToString(
2465+
com.google.protobuf.Timestamp startTimestamp =
2466+
timestampFromMicrosOrNanos(
24672467
!action.hasPartitionToken(), Timestamps.toMicros(action.getStartTime()));
2468+
String startTime = String.format("\"%s\"", Timestamps.toString(startTimestamp));
24682469
String endTime = "null";
24692470
if (action.hasEndTime()) {
2470-
endTime =
2471-
timestampToString(
2471+
com.google.protobuf.Timestamp endTimestamp =
2472+
timestampFromMicrosOrNanos(
24722473
!action.hasPartitionToken(), Timestamps.toMicros(action.getEndTime()));
2474+
// Guarantees that the end timestamp is not before the start timestamp.
2475+
endTimestamp =
2476+
Timestamps.compare(endTimestamp, startTimestamp) >= 0 ? endTimestamp : startTimestamp;
2477+
endTime = String.format("\"%s\"", Timestamps.toString(endTimestamp));
24732478
}
24742479
String heartbeat = "null";
24752480
if (action.hasHeartbeatMilliseconds()) {
@@ -3948,6 +3953,20 @@ private <T extends Serializable> ByteString marshall(T object) throws IOExceptio
39483953
return output.toByteString();
39493954
}
39503955

3956+
/**
3957+
* Converts timestamp microseconds to Timestamp. If useNanosPrecision is set to true, it pads
3958+
* input timestamp with 3 random digits (less than 1 microsecond) treating it as timestamp
3959+
* nanoseconds. This simulates the production client code send Timestamp in nanoseconds precision.
3960+
*/
3961+
private static com.google.protobuf.Timestamp timestampFromMicrosOrNanos(
3962+
boolean useNanosPrecision, long timestampInMicros) {
3963+
com.google.protobuf.Timestamp timestamp =
3964+
useNanosPrecision
3965+
? Timestamps.fromNanos(timestampInMicros * 1000 + System.nanoTime() % 1000)
3966+
: Timestamps.fromMicros(timestampInMicros);
3967+
return timestamp;
3968+
}
3969+
39513970
/** Build Timestamp from micros. */
39523971
private Timestamp timestampFromMicros(long micros) {
39533972
long seconds = TimeUnit.MICROSECONDS.toSeconds(micros);

0 commit comments

Comments
 (0)