Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(spanner/spansql): add support for bit functions, sequence functions and GENERATE_UUID #8482

Merged
merged 3 commits into from
Aug 24, 2023
Merged
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
14 changes: 14 additions & 0 deletions spanner/spansql/keywords.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ func init() {
// Spacial case of INTERVAL arg for TIMESTAMP_ADD, TIMESTAMP_SUB
funcArgParsers["TIMESTAMP_ADD"] = timestampIntervalArgParser
funcArgParsers["TIMESTAMP_SUB"] = timestampIntervalArgParser
// Special case of SEQUENCE arg for GET_NEXT_SEQUENCE_VALUE, GET_INTERNAL_SEQUENCE_STATE
funcArgParsers["GET_NEXT_SEQUENCE_VALUE"] = sequenceArgParser
funcArgParsers["GET_INTERNAL_SEQUENCE_STATE"] = sequenceArgParser
}

var allFuncs = []string{
Expand Down Expand Up @@ -280,4 +283,15 @@ var allFuncs = []string{

// JSON functions.
"JSON_VALUE",

// Bit functions.
"BIT_COUNT",
"BIT_REVERSE",

// Sequence functions.
"GET_NEXT_SEQUENCE_VALUE",
"GET_INTERNAL_SEQUENCE_STATE",

// Utility functions.
"GENERATE_UUID",
}
11 changes: 11 additions & 0 deletions spanner/spansql/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3386,6 +3386,17 @@ var dateIntervalArgParser = intervalArgParser((*parser).parseDateIntervalDatePar
// Special argument parser for TIMESTAMP_ADD, TIMESTAMP_SUB
var timestampIntervalArgParser = intervalArgParser((*parser).parseTimestampIntervalDatePart)

var sequenceArgParser = func(p *parser) (Expr, *parseError) {
if p.eat("SEQUENCE") {
name, err := p.parseTableOrIndexOrColumnName()
if err != nil {
return nil, err
}
return SequenceExpr{Name: name}, nil
}
return p.parseExpr()
}

/*
Expressions

Expand Down
2 changes: 2 additions & 0 deletions spanner/spansql/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ func TestParseExpr(t *testing.T) {
{`GENERATE_DATE_ARRAY('2022-01-01', CURRENT_DATE(), INTERVAL 1 MONTH)`, Func{Name: "GENERATE_DATE_ARRAY", Args: []Expr{StringLiteral("2022-01-01"), Func{Name: "CURRENT_DATE"}, IntervalExpr{Expr: IntegerLiteral(1), DatePart: "MONTH"}}}},
{`TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)`, Func{Name: "TIMESTAMP_ADD", Args: []Expr{Func{Name: "CURRENT_TIMESTAMP"}, IntervalExpr{Expr: IntegerLiteral(1), DatePart: "HOUR"}}}},
{`TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 MINUTE)`, Func{Name: "TIMESTAMP_SUB", Args: []Expr{Func{Name: "CURRENT_TIMESTAMP"}, IntervalExpr{Expr: IntegerLiteral(1), DatePart: "MINUTE"}}}},
{`GET_NEXT_SEQUENCE_VALUE(SEQUENCE MySequence)`, Func{Name: "GET_NEXT_SEQUENCE_VALUE", Args: []Expr{SequenceExpr{Name: ID("MySequence")}}}},
{`GET_INTERNAL_SEQUENCE_STATE(SEQUENCE MySequence)`, Func{Name: "GET_INTERNAL_SEQUENCE_STATE", Args: []Expr{SequenceExpr{Name: ID("MySequence")}}}},

// Conditional expressions
{
Expand Down
6 changes: 6 additions & 0 deletions spanner/spansql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,12 @@ func (ie IntervalExpr) addSQL(sb *strings.Builder) {
sb.WriteString(ie.DatePart)
}

func (se SequenceExpr) SQL() string { return buildSQL(se) }
func (se SequenceExpr) addSQL(sb *strings.Builder) {
sb.WriteString("SEQUENCE ")
sb.WriteString(se.Name.SQL())
}

func idList(l []ID, join string) string {
var ss []string
for _, s := range l {
Expand Down
6 changes: 6 additions & 0 deletions spanner/spansql/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,12 @@ type IntervalExpr struct {
func (IntervalExpr) isBoolExpr() {} // possibly bool
func (IntervalExpr) isExpr() {}

type SequenceExpr struct {
Name ID
}

func (SequenceExpr) isExpr() {}

// Paren represents a parenthesised expression.
type Paren struct {
Expr Expr
Expand Down
Loading