Problem
gcvctor has an asymmetry between bytes-backed and string-backed wire payloads:
This leaves no constructor for string-payload values whose Type is not a bare code — most concretely PG-dialect annotated scalars. spanner.PGNumeric carries a raw wire string (not *big.Rat), so spanenc has to hand-assemble the GCV literal today:
// spanenc encode.go — the only hand-built GCV in the package
return gcv{
Type: typector.PGNumeric(),
Value: structpb.NewStringValue(v.Numeric),
}
Suggested fix
Add the parallel constructor:
// StringBasedValueOf constructs a GenericColumnValue with an arbitrary
// string-compatible Type and the wire string stored as-is (no validation),
// like BytesBasedValueOf for base64 payloads.
func StringBasedValueOf(typ *sppb.Type, v string) spanner.GenericColumnValue
with the same no-validation caveats as StringBasedValueFromCode (caller supplies the canonical wire form). StringBasedValueFromCode then reads as the simple-code convenience over it.
This also unblocks the spanner.PGNumeric counterpart discussed in #207 (its FromNullable needs a raw-string path, not PGNumericValue(*big.Rat)).
Related
Feedback from building spanenc's encodeValue mirror on gcvctor.
Problem
gcvctorhas an asymmetry between bytes-backed and string-backed wire payloads:BytesBasedValueOf(typ *sppb.Type, v []byte)accepts an arbitrary Type, which is whatProtoValuebuilds on.StringBasedValueFromCode(code sppb.TypeCode, v string), limited to simple scalar type codes (and gcvctor: doc clarifications for known traps (BytesValue vs BytesFromSlice, ArrayValue spread, StringBasedValueFromCode scope) #222 already tracks documenting that ARRAY/STRUCT codes produce malformed Types).This leaves no constructor for string-payload values whose Type is not a bare code — most concretely PG-dialect annotated scalars.
spanner.PGNumericcarries a raw wire string (not*big.Rat), so spanenc has to hand-assemble the GCV literal today:Suggested fix
Add the parallel constructor:
with the same no-validation caveats as
StringBasedValueFromCode(caller supplies the canonical wire form).StringBasedValueFromCodethen reads as the simple-code convenience over it.This also unblocks the
spanner.PGNumericcounterpart discussed in #207 (itsFromNullableneeds a raw-string path, notPGNumericValue(*big.Rat)).Related
Feedback from building spanenc's encodeValue mirror on gcvctor.