The following fixes were incorporated in v1.57.0, but I think that the behavior of spanner:"" tag annotation still seems different from that of ToStruct.
spanner: SelectAll struct fields match should be case-insensitive (#9417) (7ff5356)
The current behavior of SelectAll for spanner tag annotations seems to be "accept only lowercase field names" instead of case-insensitive.
First, suppose I have the following test table
CREATE TABLE Singers (
ArtistId INT64 NOT NULL, Name
Name STRING(1024), Name
) PRIMARY KEY (ArtistId)
Also, the following data is submitted as test data.
Consider the case where the *spanner.RowIterator value obtained from the above table is set to a slice of a struct containing uppercase letters in the spanner tag annotation as follows.
type Singer struct {
ID int64 `spanner: "ArtistId"`
Name string `spanner: "Name"`
}
Expected behavior
The expected result is that SelectAll will set the value correctly, as well as ToStruct, even if the tag annotation contains uppercase letters.
Actual behavior
An error or panic will occur if the tag annotation contains uppercase letters. If spanner.WithLenient() option is not specified, an error will occur; if spanner.WithLenient() option is specified, panic will occur.
Error message if spanner.WithLenient() is not specified
Go struct {ID:0 Name:}(type reflect.Value) has no or duplicate fields for Cloud Spanner STRUCT field ArtistId
If spanner.WithLenient() is specified.
panic: reflect.Set: value of type string is not assignable to type int64
Additional context
I have investigated the possible cause of the problem.
In row.go, initFieldTag L564
name, keep, _, _ := spannerTagParser(fieldType.Tag)
if !keep {
continue
}
if name == "" {
name = strings.ToLower(fieldType.Name)
}
(*fieldTagMap)[name] = sliceItem.Field(i)
but this is probably because strings.ToLower is not applied to the spannerTagParser result.
I have tested the above test repository with the following changes to the row.go implementation and have confirmed that it works correctly.
name, keep, _, _ := spannerTagParser(fieldType.Tag)
if !keep {
continue
}
if name == "" {
name = fieldType.Name
}
(*fieldTagMap)[strings.ToLower(name)] = sliceItem.Field(i)
As this is my first contribution to this repository, I am not fully aware of the detailed testing procedures, but I will be able to issue a PR to correct the relevant areas.
The branch where we made the modifications is here.
Client
Spanner
Environment
Get this on all, tested on local mac PC with Docker
Go Environment
$ go version
$ go env
Code
I have created a sample repository where you can reproduce the issue. https://github.com/yukia3e/go-spanner-selectall-test/blob/main/internal/main.go#L115
The following fixes were incorporated in v1.57.0, but I think that the behavior of
spanner:""
tag annotation still seems different from that of ToStruct.The current behavior of SelectAll for spanner tag annotations seems to be "accept only lowercase field names" instead of case-insensitive.
First, suppose I have the following test table
Also, the following data is submitted as test data.
Consider the case where the *spanner.RowIterator value obtained from the above table is set to a slice of a struct containing uppercase letters in the spanner tag annotation as follows.
Expected behavior
The expected result is that SelectAll will set the value correctly, as well as ToStruct, even if the tag annotation contains uppercase letters.
Actual behavior
An error or panic will occur if the tag annotation contains uppercase letters. If
spanner.WithLenient()
option is not specified, an error will occur; ifspanner.WithLenient()
option is specified, panic will occur.Error message if
spanner.WithLenient()
is not specifiedIf
spanner.WithLenient()
is specified.Additional context
I have investigated the possible cause of the problem.
In row.go, initFieldTag L564
but this is probably because
strings.ToLower
is not applied to thespannerTagParser
result.I have tested the above test repository with the following changes to the row.go implementation and have confirmed that it works correctly.
As this is my first contribution to this repository, I am not fully aware of the detailed testing procedures, but I will be able to issue a PR to correct the relevant areas. The branch where we made the modifications is here.