diff --git a/spanner/value.go b/spanner/value.go index 9d763be55719..3f806f8b7657 100644 --- a/spanner/value.go +++ b/spanner/value.go @@ -1265,6 +1265,15 @@ func decodeValue(v *proto3.Value, t *sppb.Type, ptr interface{}, opts ...DecodeO acode = t.ArrayElementType.Code atypeAnnotation = t.ArrayElementType.TypeAnnotation } + + if code == sppb.TypeCode_PROTO && reflect.TypeOf(ptr).Elem().Kind() == reflect.Ptr { + pve := reflect.ValueOf(ptr).Elem() + if pve.IsNil() { + pve.Set(reflect.New(pve.Type().Elem())) + } + ptr = pve.Interface() + } + _, isNull := v.Kind.(*proto3.Value_NullValue) // Do the decoding based on the type of ptr. diff --git a/spanner/value_test.go b/spanner/value_test.go index 1c7902fbc9e1..95d12643c812 100644 --- a/spanner/value_test.go +++ b/spanner/value_test.go @@ -1982,6 +1982,14 @@ func TestDecodeValue(t *testing.T) { }, {desc: "decode ENUM to protoreflect.Enum", proto: protoEnumProto(pb.Genre_ROCK), protoType: protoEnumType(protoEnumfqn), want: singerEnumValue}, {desc: "decode PROTO to NullProto", proto: protoMessageProto(&singerProtoMsg), protoType: protoMessageType(protoMessagefqn), want: NullProtoMessage{&singerProtoMsg, true}}, + {desc: "decode PROTO to *pb.SingerInfo", proto: protoMessageProto(&singerProtoMsg), protoType: protoMessageType(protoMessagefqn), + want: &pb.SingerInfo{ + SingerId: proto.Int64(1), + BirthDate: proto.String("January"), + Nationality: proto.String("Country1"), + Genre: &singerEnumValue, + }, + }, {desc: "decode NULL to NullProto", proto: nullProto(), protoType: protoMessageType(protoMessagefqn), want: NullProtoMessage{}}, {desc: "decode ENUM to NullEnum", proto: protoEnumProto(pb.Genre_ROCK), protoType: protoEnumType(protoEnumfqn), want: NullProtoEnum{&singerEnumValue, true}}, {desc: "decode NULL to NullEnum", proto: nullProto(), protoType: protoEnumType(protoEnumfqn), want: NullProtoEnum{}},