-
Notifications
You must be signed in to change notification settings - Fork 1.5k
spanner: SelectAll with annotations is broken #13299
Copy link
Copy link
Closed
Labels
api: spannerIssues related to the Spanner API.Issues related to the Spanner API.triage meI really want to be triaged.I really want to be triaged.
Description
Client
Spanner
Environment
go 1.25.1
commit 6e77e86
Code and Dependencies
diff --git a/spanner/row_test.go b/spanner/row_test.go
index 0b84e82f51..313da1074a 100644
--- a/spanner/row_test.go
+++ b/spanner/row_test.go
@@ -2288,6 +2288,13 @@ func TestSelectAll(t *testing.T) {
Col3 string `spanner:"taG3"`
Col4 time.Time `spanner:"TAG4"`
}
+
+ type testStructWithSimpleTag struct {
+ Col1 int64 `spanner:"tag1"`
+ Col2 int64 `spanner:"tag2"`
+ Col3 int64 `spanner:"tag3"`
+ Col4 int64 `spanner:"tag4"`
+ }
tests := []struct {
name string
args args
@@ -2523,6 +2530,78 @@ func TestSelectAll(t *testing.T) {
{Col1: 2, Col2: 2.2, Col3: "value2", Col4: tm.Add(24 * time.Hour)},
},
},
+ {
+ name: "success: using slice of structs with simple spanner tag annotations in different order",
+ args: args{
+ destination: &[]testStructWithSimpleTag{},
+ mock: newMockIterator(
+ &Row{
+ []*sppb.StructType_Field{
+ {Name: "Tag2", Type: intType()},
+ {Name: "Tag1", Type: intType()},
+ {Name: "Tag4", Type: intType()},
+ {Name: "Tag3", Type: intType()},
+ },
+ []*proto3.Value{intProto(2), intProto(1), intProto(4), intProto(3)},
+ },
+ &Row{
+ []*sppb.StructType_Field{
+ {Name: "Tag1", Type: intType()},
+ {Name: "Tag2", Type: intType()},
+ {Name: "Tag3", Type: intType()},
+ {Name: "Tag4", Type: intType()},
+ },
+ []*proto3.Value{intProto(1), intProto(2), intProto(3), intProto(4)},
+ },
+ &Row{
+ []*sppb.StructType_Field{
+ {Name: "Tag2", Type: intType()},
+ {Name: "Tag1", Type: intType()},
+ {Name: "Tag4", Type: intType()},
+ {Name: "Tag3", Type: intType()},
+ },
+ []*proto3.Value{intProto(2), intProto(1), intProto(4), intProto(3)},
+ },
+ iterator.Done,
+ ),
+ },
+ want: &[]testStructWithSimpleTag{
+ {Col1: 1, Col2: 2, Col3: 3, Col4: 4},
+ {Col1: 1, Col2: 2, Col3: 3, Col4: 4},
+ {Col1: 1, Col2: 2, Col3: 3, Col4: 4},
+ },
+ },
+ {
+ name: "success: using slice of structs with spanner tag annotations in different order",
+ args: args{
+ destination: &[]testStructWithTag{},
+ mock: newMockIterator(
+ &Row{
+ []*sppb.StructType_Field{
+ {Name: "Tag2", Type: floatType()},
+ {Name: "Tag1", Type: intType()},
+ {Name: "Tag4", Type: timeType()},
+ {Name: "Tag3", Type: stringType()},
+ },
+ []*proto3.Value{floatProto(1.1), intProto(1), timeProto(tm), stringProto("value")},
+ },
+ &Row{
+ []*sppb.StructType_Field{
+ {Name: "Tag2", Type: floatType()},
+ {Name: "Tag1", Type: intType()},
+ {Name: "Tag4", Type: timeType()},
+ {Name: "Tag3", Type: stringType()},
+ },
+ []*proto3.Value{floatProto(2.2), intProto(2), timeProto(tm.Add(24 * time.Hour)), stringProto("value2")},
+ },
+ iterator.Done,
+ ),
+ },
+ want: &[]testStructWithTag{
+ {Col1: 1, Col2: 1.1, Col3: "value", Col4: tm},
+ {Col1: 2, Col2: 2.2, Col3: "value2", Col4: tm.Add(24 * time.Hour)},
+ },
+ },
{
name: "failure: in case of error destination will have the partial result",
args: args{
Expected behavior
The unit tests added should pass - I believe the order of the tags should have no impact on the decoding? I may be misunderstanding how this function is supposed to work though.
basically if I have
type rowStruct struct {
b int64 `spanner:"b"`
a int64 `spanner:"a"`
}
and I do
Select b, a from foo
The resulting row should properly decode into rowStruct. The current behaviour is unexpected.
Actual behavior
Output of testcases added
--- FAIL: TestSelectAll (0.00s)
--- FAIL: TestSelectAll/success:_using_slice_of_structs_with_simple_spanner_tag_annotations_in_different_order (0.00s)
google-cloud-go/spanner/row_test.go:2702: SelectAll() = &[{2 2 4 4} {1 2 3 4} {2 1 4 3}], want &[{1 2 3 4} {1 2 3 4} {1 2 3 4}]
--- FAIL: TestSelectAll/success:_using_slice_of_structs_with_spanner_tag_annotations_in_different_order (0.00s)
panic: reflect.Set: value of type float64 is not assignable to type int64 [recovered, repanicked]
Note that in the test case we do (Tag2, Tag1, Tag4, Tag3) then (Tag1, Tag2, Tag3, Tag4) then (Tag2, Tag1, Tag4, Tag3) again, but we end up with [{2 2 4 4} {1 2 3 4} {2 1 4 3}]somehow.
(output edited to hide local user details in the path)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
api: spannerIssues related to the Spanner API.Issues related to the Spanner API.triage meI really want to be triaged.I really want to be triaged.