Skip to content

Commit

Permalink
feat(bigquery): add support for explicit query parameter type (#6596)
Browse files Browse the repository at this point in the history
Allow users to pass query parameter with an explicit data types instead of relying just on type inference. 

Resolves #4704
  • Loading branch information
alvarowolfx committed Sep 16, 2022
1 parent ad01de9 commit d59b5b2
Show file tree
Hide file tree
Showing 4 changed files with 360 additions and 30 deletions.
168 changes: 155 additions & 13 deletions bigquery/integration_test.go
Expand Up @@ -1808,6 +1808,7 @@ func TestIntegration_QueryParameters(t *testing.T) {
dtm := civil.DateTime{Date: d, Time: tm}
ts := time.Date(2016, 3, 20, 15, 04, 05, 0, time.UTC)
rat := big.NewRat(13, 10)
bigRat := big.NewRat(12345, 10e10)

type ss struct {
String string
Expand All @@ -1828,73 +1829,73 @@ func TestIntegration_QueryParameters(t *testing.T) {
}{
{
"SELECT @val",
[]QueryParameter{{"val", 1}},
[]QueryParameter{{Name: "val", Value: 1}},
[]Value{int64(1)},
int64(1),
},
{
"SELECT @val",
[]QueryParameter{{"val", 1.3}},
[]QueryParameter{{Name: "val", Value: 1.3}},
[]Value{1.3},
1.3,
},
{
"SELECT @val",
[]QueryParameter{{"val", rat}},
[]QueryParameter{{Name: "val", Value: rat}},
[]Value{rat},
rat,
},
{
"SELECT @val",
[]QueryParameter{{"val", true}},
[]QueryParameter{{Name: "val", Value: true}},
[]Value{true},
true,
},
{
"SELECT @val",
[]QueryParameter{{"val", "ABC"}},
[]QueryParameter{{Name: "val", Value: "ABC"}},
[]Value{"ABC"},
"ABC",
},
{
"SELECT @val",
[]QueryParameter{{"val", []byte("foo")}},
[]QueryParameter{{Name: "val", Value: []byte("foo")}},
[]Value{[]byte("foo")},
[]byte("foo"),
},
{
"SELECT @val",
[]QueryParameter{{"val", ts}},
[]QueryParameter{{Name: "val", Value: ts}},
[]Value{ts},
ts,
},
{
"SELECT @val",
[]QueryParameter{{"val", []time.Time{ts, ts}}},
[]QueryParameter{{Name: "val", Value: []time.Time{ts, ts}}},
[]Value{[]Value{ts, ts}},
[]interface{}{ts, ts},
},
{
"SELECT @val",
[]QueryParameter{{"val", dtm}},
[]QueryParameter{{Name: "val", Value: dtm}},
[]Value{civil.DateTime{Date: d, Time: rtm}},
civil.DateTime{Date: d, Time: rtm},
},
{
"SELECT @val",
[]QueryParameter{{"val", d}},
[]QueryParameter{{Name: "val", Value: d}},
[]Value{d},
d,
},
{
"SELECT @val",
[]QueryParameter{{"val", tm}},
[]QueryParameter{{Name: "val", Value: tm}},
[]Value{rtm},
rtm,
},
{
"SELECT @val",
[]QueryParameter{{"val", s{ts, []string{"a", "b"}, ss{"c"}, []ss{{"d"}, {"e"}}}}},
[]QueryParameter{{Name: "val", Value: s{ts, []string{"a", "b"}, ss{"c"}, []ss{{"d"}, {"e"}}}}},
[]Value{[]Value{ts, []Value{"a", "b"}, []Value{"c"}, []Value{[]Value{"d"}, []Value{"e"}}}},
map[string]interface{}{
"Timestamp": ts,
Expand All @@ -1908,7 +1909,7 @@ func TestIntegration_QueryParameters(t *testing.T) {
},
{
"SELECT @val.Timestamp, @val.SubStruct.String",
[]QueryParameter{{"val", s{Timestamp: ts, SubStruct: ss{"a"}}}},
[]QueryParameter{{Name: "val", Value: s{Timestamp: ts, SubStruct: ss{"a"}}}},
[]Value{ts, "a"},
map[string]interface{}{
"Timestamp": ts,
Expand All @@ -1917,6 +1918,147 @@ func TestIntegration_QueryParameters(t *testing.T) {
"SubStructArray": nil,
},
},
{
"SELECT @val",
[]QueryParameter{
{
Name: "val",
Value: &QueryParameterValue{
Type: StandardSQLDataType{
TypeKind: "BIGNUMERIC",
},
Value: BigNumericString(bigRat),
},
},
},
[]Value{bigRat},
bigRat,
},
{
"SELECT @val",
[]QueryParameter{
{
Name: "val",
Value: &QueryParameterValue{
ArrayValue: []QueryParameterValue{
{Value: "a"},
{Value: "b"},
},
Type: StandardSQLDataType{
ArrayElementType: &StandardSQLDataType{
TypeKind: "STRING",
},
},
},
},
},
[]Value{[]Value{"a", "b"}},
[]interface{}{"a", "b"},
},
{
"SELECT @val",
[]QueryParameter{
{
Name: "val",
Value: &QueryParameterValue{
StructValue: map[string]QueryParameterValue{
"Timestamp": {
Value: ts,
},
"BigNumericArray": {
ArrayValue: []QueryParameterValue{
{Value: BigNumericString(bigRat)},
{Value: BigNumericString(rat)},
},
},
"ArraySingleValueStruct": {
ArrayValue: []QueryParameterValue{
{StructValue: map[string]QueryParameterValue{
"Number": {
Value: int64(42),
},
}},
{StructValue: map[string]QueryParameterValue{
"Number": {
Value: int64(43),
},
}},
},
},
"SubStruct": {
StructValue: map[string]QueryParameterValue{
"String": {
Value: "c",
},
},
},
},
Type: StandardSQLDataType{
StructType: &StandardSQLStructType{
Fields: []*StandardSQLField{
{
Name: "Timestamp",
Type: &StandardSQLDataType{
TypeKind: "TIMESTAMP",
},
},
{
Name: "BigNumericArray",
Type: &StandardSQLDataType{
ArrayElementType: &StandardSQLDataType{
TypeKind: "BIGNUMERIC",
},
},
},
{
Name: "ArraySingleValueStruct",
Type: &StandardSQLDataType{
ArrayElementType: &StandardSQLDataType{
StructType: &StandardSQLStructType{
Fields: []*StandardSQLField{
{
Name: "Number",
Type: &StandardSQLDataType{
TypeKind: "INT64",
},
},
},
},
},
},
},
{
Name: "SubStruct",
Type: &StandardSQLDataType{
StructType: &StandardSQLStructType{
Fields: []*StandardSQLField{
{
Name: "String",
Type: &StandardSQLDataType{
TypeKind: "STRING",
},
},
},
},
},
},
},
},
},
},
},
},
[]Value{[]Value{ts, []Value{bigRat, rat}, []Value{[]Value{int64(42)}, []Value{int64(43)}}, []Value{"c"}}},
map[string]interface{}{
"Timestamp": ts,
"BigNumericArray": []interface{}{bigRat, rat},
"ArraySingleValueStruct": []interface{}{
map[string]interface{}{"Number": int64(42)},
map[string]interface{}{"Number": int64(43)},
},
"SubStruct": map[string]interface{}{"String": "c"},
},
},
}
for _, c := range testCases {
q := client.Query(c.query)
Expand Down

0 comments on commit d59b5b2

Please sign in to comment.