googleapis / google-cloud-go

Google Cloud Client Libraries for Go.
https://cloud.google.com/go/docs/reference
Apache License 2.0
3.78k stars 1.3k forks source link

spanner: PROTO can't be decoded into []byte-based defined type #10993

Closed apstndb closed 4 weeks ago

apstndb commented 1 month ago

Client

Spanner

Environment

Code and Dependencies

package main

import (
    "cloud.google.com/go/spanner"
    "cloud.google.com/go/spanner/apiv1/spannerpb"
    "google.golang.org/protobuf/types/known/structpb"
    "testing"
)

type nullBytes []byte

func TestDecodeBytes(t *testing.T) {
    var b []byte
    var nb nullBytes

    gcv := &spanner.GenericColumnValue{
        Type: &spannerpb.Type{
            Code:             spannerpb.TypeCode_BYTES,
        },
        Value: structpb.NewStringValue("Zm9vCg=="),
    }
    // both success
    if err := gcv.Decode(&b); err != nil {
        t.Error(err)
    }
    if err := gcv.Decode(&nb); err != nil {
        t.Error(err)
    }
}

func TestDecodeProto(t *testing.T) {
    var b []byte
    var nb nullBytes

    gcv := &spanner.GenericColumnValue{
        Type: &spannerpb.Type{
            Code:             spannerpb.TypeCode_PROTO,
            ProtoTypeFqn: "examples.ProtoType",
        },
        Value: structpb.NewStringValue("Zm9vCg=="),
    }
    // fail only nullBytes
    if err := gcv.Decode(&b); err != nil {
        t.Error(err)
    }
    if err := gcv.Decode(&nb); err != nil {
        t.Error(err)
    }
}
go.mod ```text module sandbox go 1.21.5 require ( cloud.google.com/go/spanner v1.70.0 google.golang.org/protobuf v1.35.1 ) require ( cel.dev/expr v0.16.0 // indirect cloud.google.com/go v0.115.1 // indirect cloud.google.com/go/auth v0.9.3 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect cloud.google.com/go/compute/metadata v0.5.0 // indirect cloud.google.com/go/monitoring v1.21.0 // indirect github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.1 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cncf/xds/go v0.0.0-20240822171458-6449f94b4d59 // indirect github.com/envoyproxy/go-control-plane v0.13.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/s2a-go v0.1.8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.13.0 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.29.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect go.opentelemetry.io/otel v1.29.0 // indirect go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/sdk v1.29.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect go.opentelemetry.io/otel/trace v1.29.0 // indirect golang.org/x/crypto v0.27.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect google.golang.org/api v0.197.0 // indirect google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/grpc v1.66.2 // indirect ) ```

Expected behavior

Any PROTO values can be decoded into a defined type whose underlying type is []byte, without implementing spanner.Decoder interface.. It is consistent behavior with BYTES values.

Actual behavior

decode_test.go:47: spanner: code = "InvalidArgument", desc = "type *main.nullBytes cannot be used for decoding PROTO"
harshachinta commented 4 weeks ago

Working on it