From 745912bb594612ea1e0b538315c92a24aa168ea8 Mon Sep 17 00:00:00 2001 From: Gagan Gupta Date: Mon, 28 Apr 2025 23:00:22 +0530 Subject: [PATCH 1/3] Add support for UUID in CloudClientExecutor --- .../executor/spanner/CloudClientExecutor.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java b/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java index f7fa02a9958..89f1910518f 100644 --- a/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java +++ b/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java @@ -176,6 +176,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; @@ -2898,6 +2899,9 @@ private com.google.spanner.executor.v1.ValueList buildStruct(StructReader struct case DATE: value.setDateDaysValue(daysFromDate(struct.getDate(i))); break; + case UUID: + value.setStringValue(struct.getUuid(i).toString()); + break; case NUMERIC: String ascii = struct.getBigDecimal(i).toPlainString(); value.setStringValue(ascii); @@ -3044,6 +3048,26 @@ private com.google.spanner.executor.v1.ValueList buildStruct(StructReader struct com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.DATE).build()); } break; + case UUID: + { + com.google.spanner.executor.v1.ValueList.Builder builder = + com.google.spanner.executor.v1.ValueList.newBuilder(); + List values = struct.getUuidList(i); + for (UUID uuidValue : values) { + com.google.spanner.executor.v1.Value.Builder valueProto = + com.google.spanner.executor.v1.Value.newBuilder(); + if (uuidValue == null) { + builder.addValue(valueProto.setIsNull(true).build()); + } else { + builder.addValue( + valueProto.setStringValue(uuidValue.toString()).build()); + } + } + value.setArrayValue(builder.build()); + value.setArrayType( + com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.UUID).build()); + } + break; case TIMESTAMP: { com.google.spanner.executor.v1.ValueList.Builder builder = @@ -3227,6 +3251,7 @@ private static com.google.cloud.spanner.Key keyProtoToCloudKey( case BYTES: case FLOAT64: case DATE: + case UUID: case TIMESTAMP: case NUMERIC: case JSON: @@ -3257,6 +3282,7 @@ private static com.google.cloud.spanner.Key keyProtoToCloudKey( ErrorCode.INVALID_ARGUMENT, "Unsupported key part type: " + type.getCode().name()); } } else if (part.hasStringValue()) { + // TODO: Handle UUID when it is part of the key. if (type.getCode() == TypeCode.NUMERIC) { String ascii = part.getStringValue(); cloudKey.append(new BigDecimal(ascii)); @@ -3314,6 +3340,9 @@ private static com.google.cloud.spanner.Value valueProtoToCloudValue( case DATE: return com.google.cloud.spanner.Value.date( value.hasIsNull() ? null : dateFromDays(value.getDateDaysValue())); + case UUID: + return com.google.cloud.spanner.Value.uuid( + value.hasIsNull() ? null : UUID.fromString(value.getStringValue())); case NUMERIC: { if (value.hasIsNull()) { @@ -3438,6 +3467,20 @@ private static com.google.cloud.spanner.Value valueProtoToCloudValue( .collect(Collectors.toList()), CloudClientExecutor::dateFromDays)); } + case UUID: + if (value.hasIsNull()) { + return com.google.cloud.spanner.Value.uuidArray(null); + } else { + return com.google.cloud.spanner.Value.uuidArray( + unmarshallValueList( + value.getArrayValue().getValueList().stream() + .map(com.google.spanner.executor.v1.Value::getIsNull) + .collect(Collectors.toList()), + value.getArrayValue().getValueList().stream() + .map(com.google.spanner.executor.v1.Value::getStringValue) + .collect(Collectors.toList()), + UUID::fromString)); + } case NUMERIC: { if (value.hasIsNull()) { @@ -3603,6 +3646,8 @@ private static com.google.cloud.spanner.Type typeProtoToCloudType( return com.google.cloud.spanner.Type.float64(); case DATE: return com.google.cloud.spanner.Type.date(); + case UUID: + return com.google.cloud.spanner.Type.uuid(); case TIMESTAMP: return com.google.cloud.spanner.Type.timestamp(); case NUMERIC: @@ -3659,6 +3704,8 @@ private static com.google.spanner.v1.Type cloudTypeToTypeProto(@Nonnull Type clo return com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.TIMESTAMP).build(); case DATE: return com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.DATE).build(); + case UUID: + return com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.UUID).build(); case NUMERIC: return com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.NUMERIC).build(); case PG_NUMERIC: From 65a2f0863868b106afc8029ef562906ef55b4257 Mon Sep 17 00:00:00 2001 From: Gagan Gupta Date: Tue, 29 Apr 2025 14:00:11 +0530 Subject: [PATCH 2/3] chore: handle keyProtoToCloudKey in CloudClientExecutor --- .../google/cloud/executor/spanner/CloudClientExecutor.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java b/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java index 89f1910518f..c6a07450f82 100644 --- a/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java +++ b/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java @@ -3282,11 +3282,12 @@ private static com.google.cloud.spanner.Key keyProtoToCloudKey( ErrorCode.INVALID_ARGUMENT, "Unsupported key part type: " + type.getCode().name()); } } else if (part.hasStringValue()) { - // TODO: Handle UUID when it is part of the key. if (type.getCode() == TypeCode.NUMERIC) { String ascii = part.getStringValue(); cloudKey.append(new BigDecimal(ascii)); - } else { + } if (type.getCode() == TypeCode.UUID) { + cloudKey.append(UUID.fromString(part.getStringValue())); + }else { cloudKey.append(part.getStringValue()); } } else if (part.hasTimestampValue()) { From be9bedbc1dbbef2cf6189f3d0134a18d30cf8c32 Mon Sep 17 00:00:00 2001 From: Gagan Gupta Date: Tue, 29 Apr 2025 14:10:47 +0530 Subject: [PATCH 3/3] style: as per plugin --- .../executor/spanner/CloudClientExecutor.java | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java b/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java index c6a07450f82..08cda1a8085 100644 --- a/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java +++ b/google-cloud-spanner-executor/src/main/java/com/google/cloud/executor/spanner/CloudClientExecutor.java @@ -3049,25 +3049,24 @@ private com.google.spanner.executor.v1.ValueList buildStruct(StructReader struct } break; case UUID: - { - com.google.spanner.executor.v1.ValueList.Builder builder = - com.google.spanner.executor.v1.ValueList.newBuilder(); - List values = struct.getUuidList(i); - for (UUID uuidValue : values) { - com.google.spanner.executor.v1.Value.Builder valueProto = - com.google.spanner.executor.v1.Value.newBuilder(); - if (uuidValue == null) { - builder.addValue(valueProto.setIsNull(true).build()); - } else { - builder.addValue( - valueProto.setStringValue(uuidValue.toString()).build()); + { + com.google.spanner.executor.v1.ValueList.Builder builder = + com.google.spanner.executor.v1.ValueList.newBuilder(); + List values = struct.getUuidList(i); + for (UUID uuidValue : values) { + com.google.spanner.executor.v1.Value.Builder valueProto = + com.google.spanner.executor.v1.Value.newBuilder(); + if (uuidValue == null) { + builder.addValue(valueProto.setIsNull(true).build()); + } else { + builder.addValue(valueProto.setStringValue(uuidValue.toString()).build()); + } } + value.setArrayValue(builder.build()); + value.setArrayType( + com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.UUID).build()); } - value.setArrayValue(builder.build()); - value.setArrayType( - com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.UUID).build()); - } - break; + break; case TIMESTAMP: { com.google.spanner.executor.v1.ValueList.Builder builder = @@ -3285,9 +3284,9 @@ private static com.google.cloud.spanner.Key keyProtoToCloudKey( if (type.getCode() == TypeCode.NUMERIC) { String ascii = part.getStringValue(); cloudKey.append(new BigDecimal(ascii)); - } if (type.getCode() == TypeCode.UUID) { + } else if (type.getCode() == TypeCode.UUID) { cloudKey.append(UUID.fromString(part.getStringValue())); - }else { + } else { cloudKey.append(part.getStringValue()); } } else if (part.hasTimestampValue()) {