Skip to content

Commit

Permalink
fix(bigquery): properly handle RANGE type arrays (#10883)
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarowolfx authored Sep 18, 2024
1 parent 0b3c268 commit ce3d492
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
29 changes: 29 additions & 0 deletions bigquery/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,7 @@ type TestStruct struct {
RangeDate *RangeValue `bigquery:"rangedate"` //TODO: remove tags when field normalization works
RangeDateTime *RangeValue `bigquery:"rangedatetime"`
RangeTimestamp *RangeValue `bigquery:"rangetimestamp"`
RangeArray []*RangeValue
StringArray []string
IntegerArray []int64
FloatArray []float64
Expand Down Expand Up @@ -1208,6 +1209,7 @@ func TestIntegration_InsertAndReadStructs(t *testing.T) {
11: DateFieldType,
12: DateTimeFieldType,
13: TimestampFieldType,
14: DateFieldType,
} {
if schema[idx].Type != RangeFieldType {
t.Fatalf("mismatch in expected RANGE element in schema field %d", idx)
Expand Down Expand Up @@ -1258,6 +1260,7 @@ func TestIntegration_InsertAndReadStructs(t *testing.T) {
rangedate,
rangedatetime,
rangetimestamp,
[]*RangeValue{rangedate},
[]string{"a", "b"},
[]int64{1, 2},
[]float64{1, 1.41},
Expand Down Expand Up @@ -1296,6 +1299,7 @@ func TestIntegration_InsertAndReadStructs(t *testing.T) {
RangeDate: rangedate,
RangeDateTime: rangedatetime,
RangeTimestamp: rangetimestamp,
RangeArray: []*RangeValue{rangedate},
},
}
var savers []*StructSaver
Expand Down Expand Up @@ -2317,6 +2321,31 @@ func initQueryParameterTestCases() {
[]Value{rangeTimestamp2},
rangeTimestamp2,
},
{
"RangeArray",
"SELECT @val",
[]QueryParameter{
{
Name: "val",
Value: &QueryParameterValue{
Type: StandardSQLDataType{
ArrayElementType: &StandardSQLDataType{
TypeKind: "RANGE",
RangeElementType: &StandardSQLDataType{
TypeKind: "TIMESTAMP",
},
},
},
ArrayValue: []QueryParameterValue{
{Value: rangeTimestamp1},
{Value: rangeTimestamp2},
},
},
},
},
[]Value{[]Value{rangeTimestamp1, rangeTimestamp2}},
[]interface{}{rangeTimestamp1, rangeTimestamp2},
},
{
"NestedStructParam",
"SELECT @val",
Expand Down
20 changes: 19 additions & 1 deletion bigquery/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ func convertRow(r *bq.TableRow, schema Schema) ([]Value, error) {
if fs.RangeElementType == nil {
return nil, errors.New("bigquery: incomplete range schema for conversion")
}
v, err = convertRangeValue(cell.V.(string), fs.RangeElementType.Type)
v, err = convertRangeTableCell(cell, fs)
} else {
v, err = convertValue(cell.V, fs.Type, fs.Schema)
}
Expand Down Expand Up @@ -1058,3 +1058,21 @@ func convertRangeValue(val string, elementType FieldType) (Value, error) {
}
return rv, nil
}

// convertRangeTableCell handles parsing of the API representation of the RANGE type,
// which can come as a single value or array.
func convertRangeTableCell(cell *bq.TableCell, fs *FieldSchema) (Value, error) {
if fs.Repeated {
rangeValues := []Value{}
for _, val := range cell.V.([]interface{}) {
rawRangeValue := val.(map[string]interface{})["v"]
rangeVal, err := convertRangeValue(rawRangeValue.(string), fs.RangeElementType.Type)
if err != nil {
return nil, err
}
rangeValues = append(rangeValues, rangeVal)
}
return rangeValues, nil
}
return convertRangeValue(cell.V.(string), fs.RangeElementType.Type)
}

0 comments on commit ce3d492

Please sign in to comment.