Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for ARRAY<STRUCT> to CloudCilentExecutor #3544

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2842,61 +2842,75 @@ private Status processResults(
/** Convert a result row to a row proto(value list) for sending back to the client. */
private com.google.spanner.executor.v1.ValueList buildRow(
StructReader result, OutcomeSender sender) throws SpannerException {
com.google.spanner.executor.v1.ValueList.Builder rowBuilder =
com.google.spanner.executor.v1.ValueList.newBuilder();
sender.setRowType(buildStructType(result));
return buildStruct(result);
}

/** Construct a StructType for a given struct. This is used to set the row type. */
private com.google.spanner.v1.StructType buildStructType(StructReader struct) {
com.google.spanner.v1.StructType.Builder rowTypeBuilder =
com.google.spanner.v1.StructType.newBuilder();
for (int i = 0; i < result.getColumnCount(); ++i) {
com.google.cloud.spanner.Type columnType = result.getColumnType(i);
for (int i = 0; i < struct.getColumnCount(); ++i) {
com.google.cloud.spanner.Type columnType = struct.getColumnType(i);
rowTypeBuilder.addFields(
com.google.spanner.v1.StructType.Field.newBuilder()
.setName(result.getType().getStructFields().get(i).getName())
.setName(struct.getType().getStructFields().get(i).getName())
.setType(cloudTypeToTypeProto(columnType))
.build());
}
return rowTypeBuilder.build();
}

/** Convert a struct to a proto(value list) for constructing result rows and struct values. */
private com.google.spanner.executor.v1.ValueList buildStruct(StructReader struct) {
com.google.spanner.executor.v1.ValueList.Builder structBuilder =
com.google.spanner.executor.v1.ValueList.newBuilder();
for (int i = 0; i < struct.getColumnCount(); ++i) {
com.google.cloud.spanner.Type columnType = struct.getColumnType(i);
com.google.spanner.executor.v1.Value.Builder value =
com.google.spanner.executor.v1.Value.newBuilder();
if (result.isNull(i)) {
if (struct.isNull(i)) {
value.setIsNull(true);
} else {
switch (columnType.getCode()) {
case BOOL:
value.setBoolValue(result.getBoolean(i));
value.setBoolValue(struct.getBoolean(i));
break;
case FLOAT32:
value.setDoubleValue((double) result.getFloat(i));
value.setDoubleValue((double) struct.getFloat(i));
break;
case FLOAT64:
value.setDoubleValue(result.getDouble(i));
value.setDoubleValue(struct.getDouble(i));
break;
case INT64:
value.setIntValue(result.getLong(i));
value.setIntValue(struct.getLong(i));
break;
case STRING:
value.setStringValue(result.getString(i));
value.setStringValue(struct.getString(i));
break;
case BYTES:
value.setBytesValue(toByteString(result.getBytes(i)));
value.setBytesValue(toByteString(struct.getBytes(i)));
break;
case TIMESTAMP:
value.setTimestampValue(timestampToProto(result.getTimestamp(i)));
value.setTimestampValue(timestampToProto(struct.getTimestamp(i)));
break;
case DATE:
value.setDateDaysValue(daysFromDate(result.getDate(i)));
value.setDateDaysValue(daysFromDate(struct.getDate(i)));
break;
case NUMERIC:
String ascii = result.getBigDecimal(i).toPlainString();
String ascii = struct.getBigDecimal(i).toPlainString();
value.setStringValue(ascii);
break;
case JSON:
value.setStringValue(result.getJson(i));
value.setStringValue(struct.getJson(i));
break;
larkee marked this conversation as resolved.
Show resolved Hide resolved
case ARRAY:
switch (result.getColumnType(i).getArrayElementType().getCode()) {
switch (struct.getColumnType(i).getArrayElementType().getCode()) {
case BOOL:
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<Boolean> values = result.getBooleanList(i);
List<Boolean> values = struct.getBooleanList(i);
for (Boolean booleanValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -2915,7 +2929,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<Float> values = result.getFloatList(i);
List<Float> values = struct.getFloatList(i);
for (Float floatValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -2934,7 +2948,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<Double> values = result.getDoubleList(i);
List<Double> values = struct.getDoubleList(i);
for (Double doubleValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -2953,7 +2967,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<Long> values = result.getLongList(i);
List<Long> values = struct.getLongList(i);
for (Long longValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -2972,7 +2986,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<String> values = result.getStringList(i);
List<String> values = struct.getStringList(i);
for (String stringValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -2991,7 +3005,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<ByteArray> values = result.getBytesList(i);
List<ByteArray> values = struct.getBytesList(i);
for (ByteArray byteArrayValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -3013,7 +3027,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<Date> values = result.getDateList(i);
List<Date> values = struct.getDateList(i);
for (Date dateValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -3033,7 +3047,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<Timestamp> values = result.getTimestampList(i);
List<Timestamp> values = struct.getTimestampList(i);
for (Timestamp timestampValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -3053,7 +3067,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<BigDecimal> values = result.getBigDecimalList(i);
List<BigDecimal> values = struct.getBigDecimalList(i);
for (BigDecimal bigDec : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -3072,7 +3086,7 @@ private com.google.spanner.executor.v1.ValueList buildRow(
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<String> values = result.getJsonList(i);
List<String> values = struct.getJsonList(i);
for (String stringValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
Expand All @@ -3087,28 +3101,47 @@ private com.google.spanner.executor.v1.ValueList buildRow(
com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.JSON).build());
}
break;
case STRUCT:
{
com.google.spanner.executor.v1.ValueList.Builder builder =
com.google.spanner.executor.v1.ValueList.newBuilder();
List<Struct> values = struct.getStructList(i);
for (StructReader structValue : values) {
com.google.spanner.executor.v1.Value.Builder valueProto =
com.google.spanner.executor.v1.Value.newBuilder();
if (structValue == null) {
builder.addValue(valueProto.setIsNull(true).build());
} else {
builder.addValue(valueProto.setStructValue(buildStruct(structValue))).build();
}
}
value.setArrayValue(builder.build());
value.setArrayType(
com.google.spanner.v1.Type.newBuilder().setCode(TypeCode.STRUCT).build());
}
break;
default:
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Unsupported row array type: "
+ result.getColumnType(i)
+ struct.getColumnType(i)
+ " for result type "
+ result.getType().toString());
+ struct.getType().toString());
}
break;
default:
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Unsupported row type: "
+ result.getColumnType(i)
+ struct.getColumnType(i)
+ " for result type "
+ result.getType().toString());
+ struct.getType().toString());
}
}
rowBuilder.addValue(value.build());
structBuilder.addValue(value.build());
}
sender.setRowType(rowTypeBuilder.build());
return rowBuilder.build();
;
return structBuilder.build();
}

/** Convert a ListValue proto to a list of cloud Value. */
Expand Down
Loading