Skip to content

Commit ce3d492

Browse files
authored
fix(bigquery): properly handle RANGE type arrays (#10883)
1 parent 0b3c268 commit ce3d492

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

bigquery/integration_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,7 @@ type TestStruct struct {
11751175
RangeDate *RangeValue `bigquery:"rangedate"` //TODO: remove tags when field normalization works
11761176
RangeDateTime *RangeValue `bigquery:"rangedatetime"`
11771177
RangeTimestamp *RangeValue `bigquery:"rangetimestamp"`
1178+
RangeArray []*RangeValue
11781179
StringArray []string
11791180
IntegerArray []int64
11801181
FloatArray []float64
@@ -1208,6 +1209,7 @@ func TestIntegration_InsertAndReadStructs(t *testing.T) {
12081209
11: DateFieldType,
12091210
12: DateTimeFieldType,
12101211
13: TimestampFieldType,
1212+
14: DateFieldType,
12111213
} {
12121214
if schema[idx].Type != RangeFieldType {
12131215
t.Fatalf("mismatch in expected RANGE element in schema field %d", idx)
@@ -1258,6 +1260,7 @@ func TestIntegration_InsertAndReadStructs(t *testing.T) {
12581260
rangedate,
12591261
rangedatetime,
12601262
rangetimestamp,
1263+
[]*RangeValue{rangedate},
12611264
[]string{"a", "b"},
12621265
[]int64{1, 2},
12631266
[]float64{1, 1.41},
@@ -1296,6 +1299,7 @@ func TestIntegration_InsertAndReadStructs(t *testing.T) {
12961299
RangeDate: rangedate,
12971300
RangeDateTime: rangedatetime,
12981301
RangeTimestamp: rangetimestamp,
1302+
RangeArray: []*RangeValue{rangedate},
12991303
},
13001304
}
13011305
var savers []*StructSaver
@@ -2317,6 +2321,31 @@ func initQueryParameterTestCases() {
23172321
[]Value{rangeTimestamp2},
23182322
rangeTimestamp2,
23192323
},
2324+
{
2325+
"RangeArray",
2326+
"SELECT @val",
2327+
[]QueryParameter{
2328+
{
2329+
Name: "val",
2330+
Value: &QueryParameterValue{
2331+
Type: StandardSQLDataType{
2332+
ArrayElementType: &StandardSQLDataType{
2333+
TypeKind: "RANGE",
2334+
RangeElementType: &StandardSQLDataType{
2335+
TypeKind: "TIMESTAMP",
2336+
},
2337+
},
2338+
},
2339+
ArrayValue: []QueryParameterValue{
2340+
{Value: rangeTimestamp1},
2341+
{Value: rangeTimestamp2},
2342+
},
2343+
},
2344+
},
2345+
},
2346+
[]Value{[]Value{rangeTimestamp1, rangeTimestamp2}},
2347+
[]interface{}{rangeTimestamp1, rangeTimestamp2},
2348+
},
23202349
{
23212350
"NestedStructParam",
23222351
"SELECT @val",

bigquery/value.go

+19-1
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ func convertRow(r *bq.TableRow, schema Schema) ([]Value, error) {
900900
if fs.RangeElementType == nil {
901901
return nil, errors.New("bigquery: incomplete range schema for conversion")
902902
}
903-
v, err = convertRangeValue(cell.V.(string), fs.RangeElementType.Type)
903+
v, err = convertRangeTableCell(cell, fs)
904904
} else {
905905
v, err = convertValue(cell.V, fs.Type, fs.Schema)
906906
}
@@ -1058,3 +1058,21 @@ func convertRangeValue(val string, elementType FieldType) (Value, error) {
10581058
}
10591059
return rv, nil
10601060
}
1061+
1062+
// convertRangeTableCell handles parsing of the API representation of the RANGE type,
1063+
// which can come as a single value or array.
1064+
func convertRangeTableCell(cell *bq.TableCell, fs *FieldSchema) (Value, error) {
1065+
if fs.Repeated {
1066+
rangeValues := []Value{}
1067+
for _, val := range cell.V.([]interface{}) {
1068+
rawRangeValue := val.(map[string]interface{})["v"]
1069+
rangeVal, err := convertRangeValue(rawRangeValue.(string), fs.RangeElementType.Type)
1070+
if err != nil {
1071+
return nil, err
1072+
}
1073+
rangeValues = append(rangeValues, rangeVal)
1074+
}
1075+
return rangeValues, nil
1076+
}
1077+
return convertRangeValue(cell.V.(string), fs.RangeElementType.Type)
1078+
}

0 commit comments

Comments
 (0)