From 759c6638e66f53e49b44b5027eadc8e6e67b09a3 Mon Sep 17 00:00:00 2001 From: toga4 <81744248+toga4@users.noreply.github.com> Date: Thu, 24 Aug 2023 22:27:45 +0900 Subject: [PATCH 1/2] feat(spanner/spansql): add support for bit functions and sequence functions --- spanner/spansql/keywords.go | 11 +++++++++++ spanner/spansql/parser.go | 11 +++++++++++ spanner/spansql/parser_test.go | 2 ++ spanner/spansql/sql.go | 6 ++++++ spanner/spansql/types.go | 6 ++++++ 5 files changed, 36 insertions(+) diff --git a/spanner/spansql/keywords.go b/spanner/spansql/keywords.go index 7fee1134fe2a..a4ad911afaa4 100644 --- a/spanner/spansql/keywords.go +++ b/spanner/spansql/keywords.go @@ -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{ @@ -280,4 +283,12 @@ var allFuncs = []string{ // JSON functions. "JSON_VALUE", + + // Bit functions. + "BIT_COUNT", + "BIT_REVERSE", + + // Sequence functions. + "GET_NEXT_SEQUENCE_VALUE", + "GET_INTERNAL_SEQUENCE_STATE", } diff --git a/spanner/spansql/parser.go b/spanner/spansql/parser.go index f33cbbd690d4..f258cdfb0494 100644 --- a/spanner/spansql/parser.go +++ b/spanner/spansql/parser.go @@ -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 diff --git a/spanner/spansql/parser_test.go b/spanner/spansql/parser_test.go index 0f3a2ee13f8e..9214fbc10f58 100644 --- a/spanner/spansql/parser_test.go +++ b/spanner/spansql/parser_test.go @@ -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 { diff --git a/spanner/spansql/sql.go b/spanner/spansql/sql.go index 39b317e91521..92e8ae05af8a 100644 --- a/spanner/spansql/sql.go +++ b/spanner/spansql/sql.go @@ -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 { diff --git a/spanner/spansql/types.go b/spanner/spansql/types.go index b7be8f5aba1f..60084f258cb7 100644 --- a/spanner/spansql/types.go +++ b/spanner/spansql/types.go @@ -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 From 1432585ee5ae5414dee973e770e9c61312505eb5 Mon Sep 17 00:00:00 2001 From: toga4 <81744248+toga4@users.noreply.github.com> Date: Thu, 24 Aug 2023 22:42:40 +0900 Subject: [PATCH 2/2] feat(spanner/spansql): add support for function GENERATE_UUID --- spanner/spansql/keywords.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spanner/spansql/keywords.go b/spanner/spansql/keywords.go index a4ad911afaa4..a66d24e21825 100644 --- a/spanner/spansql/keywords.go +++ b/spanner/spansql/keywords.go @@ -291,4 +291,7 @@ var allFuncs = []string{ // Sequence functions. "GET_NEXT_SEQUENCE_VALUE", "GET_INTERNAL_SEQUENCE_STATE", + + // Utility functions. + "GENERATE_UUID", }