Skip to content

Commit b881e80

Browse files
committed
feat: add support for ARRAY<STRUCT> to CloudCilentExecutor
1 parent 2a962a7 commit b881e80

File tree

1 file changed

+71
-39
lines changed

1 file changed

+71
-39
lines changed

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

+71-39
Original file line numberDiff line numberDiff line change
@@ -2840,61 +2840,75 @@ private Status processResults(
28402840
/** Convert a result row to a row proto(value list) for sending back to the client. */
28412841
private com.google.spanner.executor.v1.ValueList buildRow(
28422842
StructReader result, OutcomeSender sender) throws SpannerException {
2843-
com.google.spanner.executor.v1.ValueList.Builder rowBuilder =
2844-
com.google.spanner.executor.v1.ValueList.newBuilder();
2843+
sender.setRowType(buildStructType(result));
2844+
return buildStruct(result);
2845+
}
2846+
2847+
/** Construct a StructType for a given struct. This is used to set the row type. */
2848+
private com.google.spanner.v1.StructType buildStructType(StructReader struct) {
28452849
com.google.spanner.v1.StructType.Builder rowTypeBuilder =
2846-
com.google.spanner.v1.StructType.newBuilder();
2847-
for (int i = 0; i < result.getColumnCount(); ++i) {
2848-
com.google.cloud.spanner.Type columnType = result.getColumnType(i);
2850+
com.google.spanner.v1.StructType.newBuilder();
2851+
for (int i = 0; i < struct.getColumnCount(); ++i) {
2852+
com.google.cloud.spanner.Type columnType = struct.getColumnType(i);
28492853
rowTypeBuilder.addFields(
2850-
com.google.spanner.v1.StructType.Field.newBuilder()
2851-
.setName(result.getType().getStructFields().get(i).getName())
2852-
.setType(cloudTypeToTypeProto(columnType))
2853-
.build());
2854+
com.google.spanner.v1.StructType.Field.newBuilder()
2855+
.setName(struct.getType().getStructFields().get(i).getName())
2856+
.setType(cloudTypeToTypeProto(columnType))
2857+
.build());
2858+
}
2859+
return rowTypeBuilder.build();
2860+
}
2861+
2862+
/** Convert a struct to a proto(value list) for constructing result rows and struct values. */
2863+
private com.google.spanner.executor.v1.ValueList buildStruct(StructReader struct) {
2864+
com.google.spanner.executor.v1.ValueList.Builder structBuilder =
2865+
com.google.spanner.executor.v1.ValueList.newBuilder();
2866+
for (int i = 0; i < struct.getColumnCount(); ++i) {
2867+
com.google.cloud.spanner.Type columnType = struct.getColumnType(i);
28542868
com.google.spanner.executor.v1.Value.Builder value =
28552869
com.google.spanner.executor.v1.Value.newBuilder();
2856-
if (result.isNull(i)) {
2870+
if (struct.isNull(i)) {
28572871
value.setIsNull(true);
28582872
} else {
28592873
switch (columnType.getCode()) {
28602874
case BOOL:
2861-
value.setBoolValue(result.getBoolean(i));
2875+
value.setBoolValue(struct.getBoolean(i));
28622876
break;
28632877
case FLOAT32:
2864-
value.setDoubleValue((double) result.getFloat(i));
2878+
value.setDoubleValue((double) struct.getFloat(i));
28652879
break;
28662880
case FLOAT64:
2867-
value.setDoubleValue(result.getDouble(i));
2881+
value.setDoubleValue(struct.getDouble(i));
28682882
break;
28692883
case INT64:
2870-
value.setIntValue(result.getLong(i));
2884+
value.setIntValue(struct.getLong(i));
28712885
break;
28722886
case STRING:
2873-
value.setStringValue(result.getString(i));
2887+
value.setStringValue(struct.getString(i));
28742888
break;
28752889
case BYTES:
2876-
value.setBytesValue(toByteString(result.getBytes(i)));
2890+
value.setBytesValue(toByteString(struct.getBytes(i)));
28772891
break;
28782892
case TIMESTAMP:
2879-
value.setTimestampValue(timestampToProto(result.getTimestamp(i)));
2893+
value.setTimestampValue(timestampToProto(struct.getTimestamp(i)));
28802894
break;
28812895
case DATE:
2882-
value.setDateDaysValue(daysFromDate(result.getDate(i)));
2896+
value.setDateDaysValue(daysFromDate(struct.getDate(i)));
28832897
break;
28842898
case NUMERIC:
2885-
String ascii = result.getBigDecimal(i).toPlainString();
2899+
String ascii = struct.getBigDecimal(i).toPlainString();
28862900
value.setStringValue(ascii);
28872901
break;
28882902
case JSON:
2889-
value.setStringValue(result.getJson(i));
2903+
value.setStringValue(struct.getJson(i));
28902904
break;
28912905
case ARRAY:
2892-
switch (result.getColumnType(i).getArrayElementType().getCode()) {
2906+
switch (struct.getColumnType(i).getArrayElementType().getCode()) {
28932907
case BOOL:
28942908
{
28952909
com.google.spanner.executor.v1.ValueList.Builder builder =
28962910
com.google.spanner.executor.v1.ValueList.newBuilder();
2897-
List<Boolean> values = result.getBooleanList(i);
2911+
List<Boolean> values = struct.getBooleanList(i);
28982912
for (Boolean booleanValue : values) {
28992913
com.google.spanner.executor.v1.Value.Builder valueProto =
29002914
com.google.spanner.executor.v1.Value.newBuilder();
@@ -2913,7 +2927,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
29132927
{
29142928
com.google.spanner.executor.v1.ValueList.Builder builder =
29152929
com.google.spanner.executor.v1.ValueList.newBuilder();
2916-
List<Float> values = result.getFloatList(i);
2930+
List<Float> values = struct.getFloatList(i);
29172931
for (Float floatValue : values) {
29182932
com.google.spanner.executor.v1.Value.Builder valueProto =
29192933
com.google.spanner.executor.v1.Value.newBuilder();
@@ -2932,7 +2946,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
29322946
{
29332947
com.google.spanner.executor.v1.ValueList.Builder builder =
29342948
com.google.spanner.executor.v1.ValueList.newBuilder();
2935-
List<Double> values = result.getDoubleList(i);
2949+
List<Double> values = struct.getDoubleList(i);
29362950
for (Double doubleValue : values) {
29372951
com.google.spanner.executor.v1.Value.Builder valueProto =
29382952
com.google.spanner.executor.v1.Value.newBuilder();
@@ -2951,7 +2965,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
29512965
{
29522966
com.google.spanner.executor.v1.ValueList.Builder builder =
29532967
com.google.spanner.executor.v1.ValueList.newBuilder();
2954-
List<Long> values = result.getLongList(i);
2968+
List<Long> values = struct.getLongList(i);
29552969
for (Long longValue : values) {
29562970
com.google.spanner.executor.v1.Value.Builder valueProto =
29572971
com.google.spanner.executor.v1.Value.newBuilder();
@@ -2970,7 +2984,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
29702984
{
29712985
com.google.spanner.executor.v1.ValueList.Builder builder =
29722986
com.google.spanner.executor.v1.ValueList.newBuilder();
2973-
List<String> values = result.getStringList(i);
2987+
List<String> values = struct.getStringList(i);
29742988
for (String stringValue : values) {
29752989
com.google.spanner.executor.v1.Value.Builder valueProto =
29762990
com.google.spanner.executor.v1.Value.newBuilder();
@@ -2989,7 +3003,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
29893003
{
29903004
com.google.spanner.executor.v1.ValueList.Builder builder =
29913005
com.google.spanner.executor.v1.ValueList.newBuilder();
2992-
List<ByteArray> values = result.getBytesList(i);
3006+
List<ByteArray> values = struct.getBytesList(i);
29933007
for (ByteArray byteArrayValue : values) {
29943008
com.google.spanner.executor.v1.Value.Builder valueProto =
29953009
com.google.spanner.executor.v1.Value.newBuilder();
@@ -3011,7 +3025,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
30113025
{
30123026
com.google.spanner.executor.v1.ValueList.Builder builder =
30133027
com.google.spanner.executor.v1.ValueList.newBuilder();
3014-
List<Date> values = result.getDateList(i);
3028+
List<Date> values = struct.getDateList(i);
30153029
for (Date dateValue : values) {
30163030
com.google.spanner.executor.v1.Value.Builder valueProto =
30173031
com.google.spanner.executor.v1.Value.newBuilder();
@@ -3031,7 +3045,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
30313045
{
30323046
com.google.spanner.executor.v1.ValueList.Builder builder =
30333047
com.google.spanner.executor.v1.ValueList.newBuilder();
3034-
List<Timestamp> values = result.getTimestampList(i);
3048+
List<Timestamp> values = struct.getTimestampList(i);
30353049
for (Timestamp timestampValue : values) {
30363050
com.google.spanner.executor.v1.Value.Builder valueProto =
30373051
com.google.spanner.executor.v1.Value.newBuilder();
@@ -3051,7 +3065,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
30513065
{
30523066
com.google.spanner.executor.v1.ValueList.Builder builder =
30533067
com.google.spanner.executor.v1.ValueList.newBuilder();
3054-
List<BigDecimal> values = result.getBigDecimalList(i);
3068+
List<BigDecimal> values = struct.getBigDecimalList(i);
30553069
for (BigDecimal bigDec : values) {
30563070
com.google.spanner.executor.v1.Value.Builder valueProto =
30573071
com.google.spanner.executor.v1.Value.newBuilder();
@@ -3070,7 +3084,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
30703084
{
30713085
com.google.spanner.executor.v1.ValueList.Builder builder =
30723086
com.google.spanner.executor.v1.ValueList.newBuilder();
3073-
List<String> values = result.getJsonList(i);
3087+
List<String> values = struct.getJsonList(i);
30743088
for (String stringValue : values) {
30753089
com.google.spanner.executor.v1.Value.Builder valueProto =
30763090
com.google.spanner.executor.v1.Value.newBuilder();
@@ -3085,28 +3099,46 @@ private com.google.spanner.executor.v1.ValueList buildRow(
30853099
com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.JSON).build());
30863100
}
30873101
break;
3102+
case STRUCT:
3103+
{
3104+
com.google.spanner.executor.v1.ValueList.Builder builder =
3105+
com.google.spanner.executor.v1.ValueList.newBuilder();
3106+
List<Struct> values = struct.getStructList(i);
3107+
for (StructReader structValue : values) {
3108+
com.google.spanner.executor.v1.Value.Builder valueProto =
3109+
com.google.spanner.executor.v1.Value.newBuilder();
3110+
if (structValue == null) {
3111+
builder.addValue(valueProto.setIsNull(true).build());
3112+
} else {
3113+
builder.addValue(valueProto.setStructValue(buildStruct(structValue))).build();
3114+
}
3115+
}
3116+
value.setArrayValue(builder.build());
3117+
value.setArrayType(
3118+
com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.JSON).build());
3119+
}
3120+
break;
30883121
default:
30893122
throw SpannerExceptionFactory.newSpannerException(
30903123
ErrorCode.INVALID_ARGUMENT,
30913124
"Unsupported row array type: "
3092-
+ result.getColumnType(i)
3125+
+ struct.getColumnType(i)
30933126
+ " for result type "
3094-
+ result.getType().toString());
3127+
+ struct.getType().toString());
30953128
}
30963129
break;
30973130
default:
30983131
throw SpannerExceptionFactory.newSpannerException(
30993132
ErrorCode.INVALID_ARGUMENT,
31003133
"Unsupported row type: "
3101-
+ result.getColumnType(i)
3134+
+ struct.getColumnType(i)
31023135
+ " for result type "
3103-
+ result.getType().toString());
3136+
+ struct.getType().toString());
31043137
}
31053138
}
3106-
rowBuilder.addValue(value.build());
3107-
}
3108-
sender.setRowType(rowTypeBuilder.build());
3109-
return rowBuilder.build();
3139+
structBuilder.addValue(value.build());
3140+
};
3141+
return structBuilder.build();
31103142
}
31113143

31123144
/** Convert a ListValue proto to a list of cloud Value. */

0 commit comments

Comments
 (0)