Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions spanner/spannertest/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"cloud.google.com/go/civil"
"cloud.google.com/go/spanner/spansql"
"github.com/google/uuid"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
Expand Down Expand Up @@ -212,6 +213,8 @@ func convert(val interface{}, tp spansql.Type) (interface{}, error) {
res, convertErr, err = convertToTimestamp(val)
case spansql.Numeric:
case spansql.JSON:
case spansql.UUID:
res, convertErr, err = convertToUUID(val)
}
if err != nil {
return nil, err
Expand Down Expand Up @@ -312,6 +315,20 @@ func convertToTimestamp(val interface{}) (res time.Time, convertErr error, err e
return time.Time{}, nil, status.Errorf(codes.Unimplemented, "unsupported conversion for %v to TIMESTAMP", val)
}

func convertToUUID(val interface{}) (res uuid.UUID, convertErr error, err error) {
switch v := val.(type) {
case uuid.UUID:
return v, nil, nil
case string:
id, parseErr := uuid.Parse(v)
if parseErr != nil {
return uuid.UUID{}, status.Errorf(codes.InvalidArgument, "invalid value for UUID: %q", v), nil
}
return id, nil, nil
}
return uuid.UUID{}, nil, status.Errorf(codes.Unimplemented, "unsupported conversion for %v to UUID", val)
}

type aggregateFunc struct {
// Whether the function can take a * arg (only COUNT).
AcceptStar bool
Expand Down
1 change: 1 addition & 0 deletions spanner/spansql/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3404,6 +3404,7 @@ var baseTypes = map[string]TypeBase{
"PROTO": Proto, // for use in CAST
"ENUM": Enum, // for use in CAST
"TOKENLIST": Tokenlist,
"UUID": UUID,
}

func (p *parser) parseBaseType() (Type, *parseError) {
Expand Down
31 changes: 27 additions & 4 deletions spanner/spansql/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2610,6 +2610,26 @@ func TestParseDDL(t *testing.T) {
},
},
},
{
`CREATE TABLE tname (id UUID) PRIMARY KEY (id)`,
&DDL{
Filename: "filename",
List: []DDLStmt{
&CreateTable{
Name: "tname",
Columns: []ColumnDef{
{
Name: "id",
Type: Type{Base: UUID},
Position: line(1),
},
},
PrimaryKey: []KeyPart{{Column: "id"}},
Position: line(1),
},
},
},
},
}
for _, test := range tests {
got, err := ParseDDL("filename", test.in)
Expand Down Expand Up @@ -2682,7 +2702,9 @@ func TestParseDML(t *testing.T) {
INSERT FooBar (ID, Name) VALUES (0, 'foo');
DELETE FROM FooBar WHERE Name = "foo"; -- This is another comment.
-- This is an isolated comment.
`, &DML{Filename: "filename", List: []DMLStmt{
`, &DML{
Filename: "filename",
List: []DMLStmt{
&Update{
Table: "FooBar",
Items: []UpdateItem{
Expand All @@ -2706,7 +2728,8 @@ func TestParseDML(t *testing.T) {
Table: "FooBar",
Where: ComparisonOp{Op: 4, LHS: ID("Name"), RHS: StringLiteral("foo"), RHS2: nil},
},
}, Comments: []*Comment{
},
Comments: []*Comment{
{
Marker: "#", Start: line(2), End: line(2),
Text: []string{"This is a comment."},
Expand All @@ -2726,8 +2749,8 @@ func TestParseDML(t *testing.T) {
Text: []string{"This is an isolated comment."},
Isolated: true,
},
}},
},
},
}},
// No trailing comma:
{`Update FooBar SET Name = "foo" WHERE ID = 0`, &DML{
Filename: "filename", List: []DMLStmt{
Expand Down
2 changes: 2 additions & 0 deletions spanner/spansql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,8 @@ func (tb TypeBase) SQL() string {
return "ENUM"
case Tokenlist:
return "TOKENLIST"
case UUID:
return "UUID"
}

panic("unknown TypeBase")
Expand Down
2 changes: 2 additions & 0 deletions spanner/spansql/sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func TestSQL(t *testing.T) {
{Name: "Cn", Type: Type{Base: JSON}, Position: line(15)},
{Name: "Co", Type: Type{Base: Int64}, Default: IntegerLiteral(1), Position: line(16)},
{Name: "Cp", Type: Type{Base: Proto, ProtoRef: "a.b.c"}, Position: line(17)},
{Name: "Cq", Type: Type{Base: UUID}, Position: line(18)},
},
PrimaryKey: []KeyPart{
{Column: "Ca"},
Expand All @@ -119,6 +120,7 @@ func TestSQL(t *testing.T) {
Cn JSON,
Co INT64 DEFAULT (1),
Cp ` + "`a.b.c`" + `,
Cq UUID,
) PRIMARY KEY(Ca, Cb DESC)`,
reparseDDL,
},
Expand Down
1 change: 1 addition & 0 deletions spanner/spansql/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ const (
Proto
Enum // Enum used in CAST expressions
Tokenlist
UUID
)

type PrivilegeType int
Expand Down
Loading