diff --git a/spanner/row.go b/spanner/row.go index adff50a4947a..4dca9be91f0e 100644 --- a/spanner/row.go +++ b/spanner/row.go @@ -174,6 +174,22 @@ func (r *Row) ColumnNames() []string { return n } +// ColumnType returns the Cloud Spanner Type of column i, or nil for invalid column. +func (r *Row) ColumnType(i int) *sppb.Type { + if i < 0 || i >= len(r.fields) { + return nil + } + return r.fields[i].Type +} + +// ColumnValue returns the Cloud Spanner Value of column i, or nil for invalid column. +func (r *Row) ColumnValue(i int) *proto3.Value { + if i < 0 || i >= len(r.vals) { + return nil + } + return r.vals[i] +} + // errColIdxOutOfRange returns error for requested column index is out of the // range of the target Row's columns. func errColIdxOutOfRange(i int, r *Row) error { diff --git a/spanner/row_test.go b/spanner/row_test.go index a4b8bf5fd0de..b4e7a2395635 100644 --- a/spanner/row_test.go +++ b/spanner/row_test.go @@ -1909,6 +1909,30 @@ func TestColumnNameAndIndex(t *testing.T) { } } +// Test helpers for getting column type and value. +func TestColumnTypeAndValue(t *testing.T) { + // Test Row.ColumnType() + for i, col := range row.fields { + if ct := row.ColumnType(i); ct != col.Type { + t.Errorf("row.ColumnType(%v) returns %q, want %q", i, ct, col.Type) + } + } + // Test Row.ColumnValue() + for i, val := range row.vals { + if cv := row.ColumnValue(i); cv != val { + t.Errorf("row.ColumnValue(%v) returns %q, want %q", i, cv, val) + } + } + // Test Row.ColumnType on empty Row. + if ct := (&Row{}).ColumnType(0); ct != nil { + t.Errorf("empty_row.ColumnType(%v) returns %v, want %v", 0, ct, nil) + } + // Test Row.ColumnValue on empty Row. + if cv := (&Row{}).ColumnValue(0); cv != nil { + t.Errorf("empty_row.ColumnValue(%v) returns %v, want %v", 0, cv, nil) + } +} + func TestNewRow(t *testing.T) { for _, test := range []struct { names []string