or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
golangpkg:golang/cloud.google.com/go/spanner@v1.87.0

docs

client.mddml.mdindex.mdkeys.mdlow-level.mdprotobuf-types.mdreads.mdtesting.mdtransactions.mdtypes.mdwrites.md
tile.json

tessl/golang-cloud-google-com--go--spanner

tessl install tessl/golang-cloud-google-com--go--spanner@1.87.2

Official Google Cloud Spanner client library for Go providing comprehensive database operations, transactions, and admin functionality

types.mddocs/

Type System

Comprehensive guide to Spanner data types, null handling, encoding/decoding, and type conversions.

Type Mappings

Go to Spanner Type Mappings

// Scalar types
string, *string, NullString              → STRING
[]byte                                   → BYTES
int, int64, *int64, NullInt64           → INT64
bool, *bool, NullBool                   → BOOL
float64, *float64, NullFloat64          → FLOAT64
float32, *float32, NullFloat32          → FLOAT32
time.Time, *time.Time, NullTime         → TIMESTAMP
civil.Date, *civil.Date, NullDate       → DATE
big.Rat, *big.Rat, NullNumeric          → NUMERIC
uuid.UUID, *uuid.UUID, NullUUID         → UUID (GoogleSQL only)
NullJSON                                 → JSON
PGJsonB                                  → JSONB (PostgreSQL only)
PGNumeric                                → NUMERIC (PostgreSQL only)
protoreflect.Enum, NullProtoEnum        → ENUM
proto.Message, NullProtoMessage         → PROTO
Interval, NullInterval                   → INTERVAL

// Array types
[]string, []*string, []NullString        → ARRAY<STRING>
[][]byte                                 → ARRAY<BYTES>
[]int, []int64, []*int64, []NullInt64   → ARRAY<INT64>
[]bool, []*bool, []NullBool             → ARRAY<BOOL>
[]float64, []*float64, []NullFloat64    → ARRAY<FLOAT64>
[]float32, []*float32, []NullFloat32    → ARRAY<FLOAT32>
[]time.Time, []*time.Time, []NullTime   → ARRAY<TIMESTAMP>
[]civil.Date, []*civil.Date, []NullDate → ARRAY<DATE>
[]big.Rat, []*big.Rat, []NullNumeric    → ARRAY<NUMERIC>
[]uuid.UUID, []*uuid.UUID, []NullUUID   → ARRAY<UUID>
[]NullJSON                               → ARRAY<JSON>

Null Types

All nullable Spanner types use NullXXX wrappers:

NullString

type NullString struct {
    StringVal string
    Valid     bool
}

func (n *NullString) IsNull() bool
func (n *NullString) MarshalJSON() ([]byte, error)
func (n *NullString) UnmarshalJSON(payload []byte) error
func (n *NullString) Scan(value interface{}) error
func (n *NullString) Value() (driver.Value, error)
func (n *NullString) String() string
func (n *NullString) GormDataType() string

NullInt64

type NullInt64 struct {
    Int64 int64
    Valid bool
}

func (n *NullInt64) IsNull() bool
func (n *NullInt64) MarshalJSON() ([]byte, error)
func (n *NullInt64) UnmarshalJSON(payload []byte) error
func (n *NullInt64) Scan(value interface{}) error
func (n NullInt64) Value() (driver.Value, error)
func (n NullInt64) String() string
func (n NullInt64) GormDataType() string

NullFloat64

type NullFloat64 struct {
    Float64 float64
    Valid   bool
}

func (n *NullFloat64) IsNull() bool
func (n *NullFloat64) MarshalJSON() ([]byte, error)
func (n *NullFloat64) UnmarshalJSON(payload []byte) error
func (n *NullFloat64) Scan(value interface{}) error
func (n NullFloat64) Value() (driver.Value, error)
func (n NullFloat64) String() string
func (n NullFloat64) GormDataType() string

NullFloat32

type NullFloat32 struct {
    Float32 float32
    Valid   bool
}

func (n *NullFloat32) IsNull() bool
func (n *NullFloat32) MarshalJSON() ([]byte, error)
func (n *NullFloat32) UnmarshalJSON(payload []byte) error
func (n *NullFloat32) Scan(value interface{}) error
func (n NullFloat32) Value() (driver.Value, error)
func (n NullFloat32) String() string
func (n NullFloat32) GormDataType() string

NullBool

type NullBool struct {
    Bool  bool
    Valid bool
}

func (n *NullBool) IsNull() bool
func (n *NullBool) MarshalJSON() ([]byte, error)
func (n *NullBool) UnmarshalJSON(payload []byte) error
func (n *NullBool) Scan(value interface{}) error
func (n NullBool) Value() (driver.Value, error)
func (n NullBool) String() string
func (n NullBool) GormDataType() string

NullTime

type NullTime struct {
    Time  time.Time
    Valid bool
}

NullDate

type NullDate struct {
    Date  civil.Date
    Valid bool
}

NullNumeric

type NullNumeric struct {
    Numeric big.Rat
    Valid   bool
}

func NumericString(r *big.Rat) string

Constants:

const (
    NumericPrecisionDigits = 38  // Max digits
    NumericScaleDigits     = 9   // Max decimal digits
)

var LossOfPrecisionHandling LossOfPrecisionHandlingOption

type LossOfPrecisionHandlingOption int
const (
    NumericRound LossOfPrecisionHandlingOption = iota
    NumericError
)

NullJSON

type NullJSON struct {
    Value interface{}
    Valid bool
}

func UseNumberWithJSONDecoderEncoder(useNumber bool)

NullUUID

type NullUUID struct {
    UUID  uuid.UUID
    Valid bool
}

NullInterval

type Interval struct {
    Months int32
    Days   int32
    Nanos  *big.Int
}

func ParseInterval(s string) (Interval, error)
func (i *Interval) String() string

type NullInterval struct {
    Interval Interval
    Valid    bool
}

NullProtoEnum, NullProtoMessage

type NullProtoEnum struct {
    ProtoEnumVal protoreflect.Enum
    Valid        bool
}

type NullProtoMessage struct {
    ProtoMessageVal proto.Message
    Valid           bool
}

PGJsonB, PGNumeric

PostgreSQL-specific types:

type PGJsonB struct {
    Value interface{}
    Valid bool
}

type PGNumeric struct {
    Numeric string
    Valid   bool
}

NullableValue Interface

All null value wrapper types implement this interface:

type NullableValue interface {
    IsNull() bool
}

Row Decoding

Row Type

type Row struct {
    // Has unexported fields
}

func NewRow(columnNames []string, columnValues []interface{}) (*Row, error)

Row Methods

func (r *Row) Column(i int, ptr interface{}) error
func (r *Row) ColumnByName(name string, ptr interface{}) error
func (r *Row) Columns(ptrs ...interface{}) error
func (r *Row) ToStruct(p interface{}) error
func (r *Row) ToStructLenient(p interface{}) error
func (r *Row) Size() int
func (r *Row) ColumnNames() []string
func (r *Row) ColumnName(i int) string
func (r *Row) ColumnIndex(name string) (int, error)
func (r *Row) ColumnType(i int) *sppb.Type
func (r *Row) ColumnValue(i int) *proto3.Value
func (r *Row) String() string

Decoding Examples:

// By position
var name string
var age int64
err := row.Columns(&name, &age)

// By name
var email string
err := row.ColumnByName("email", &email)

// To struct
type User struct {
    Name  string `spanner:"name"`
    Email string `spanner:"email"`
    Age   int64  `spanner:"age"`
}
var user User
err := row.ToStruct(&user)

// Lenient decode (ignore extra columns)
err := row.ToStructLenient(&user)

Custom Encoding/Decoding

Encoder Interface

type Encoder interface {
    EncodeSpanner() (interface{}, error)
}

Example:

type CustomField struct {
    Prefix string
    Suffix string
}

func (cf CustomField) EncodeSpanner() (interface{}, error) {
    return fmt.Sprintf("%s-%s", cf.Prefix, cf.Suffix), nil
}

Decoder Interface

type Decoder interface {
    DecodeSpanner(input interface{}) error
}

Example:

func (cf *CustomField) DecodeSpanner(val interface{}) error {
    strVal, ok := val.(string)
    if !ok {
        return fmt.Errorf("expected string, got %T", val)
    }
    
    parts := strings.Split(strVal, "-")
    if len(parts) != 2 {
        return fmt.Errorf("invalid format")
    }
    
    cf.Prefix = parts[0]
    cf.Suffix = parts[1]
    return nil
}

GenericColumnValue

For dynamic typing:

type GenericColumnValue struct {
    Type  *sppb.Type
    Value *proto3.Value
}

func (g *GenericColumnValue) Decode(ptr interface{}) error

Example:

var gcv spanner.GenericColumnValue
err := row.Column(0, &gcv)

// Decode to specific type
var str string
err = gcv.Decode(&str)

NullRow

For STRUCT types:

type NullRow struct {
    Row   Row
    Valid bool
}

Decode Options

type DecodeOptions interface {
    Apply(s *decodeSetting)
}

func WithLenient() DecodeOptions

SelectAll Helper

func SelectAll(rows rowIterator, destination interface{}, options ...DecodeOptions) error

Example:

var users []User
stmt := spanner.NewStatement("SELECT * FROM Users")
iter := client.Single().Query(ctx, stmt)
err := spanner.SelectAll(iter, &users)

Struct Tags

type User struct {
    ID        int64  `spanner:"user_id"`     // Map to user_id column
    Name      string `spanner:"full_name"`   // Map to full_name column
    Email     string                         // Maps to "email" (lowercase field name)
    Internal  string `spanner:"-"`           // Ignore field
}

Best Practices

  1. Use NullXXX for nullable columns: Prevents errors
  2. Use structs for complex data: Cleaner code
  3. Implement Encoder/Decoder: For custom types
  4. Use GenericColumnValue: When type unknown at compile time
  5. Handle JSON numbers carefully: Set UseNumberWithJSONDecoderEncoder
  6. Validate NUMERIC precision: Check before writing
  7. Use civil.Date: For DATE columns
  8. Handle UUID properly: Use uuid.UUID type
  9. Use struct tags: For column name mapping
  10. Test type conversions: Especially for custom types