Skip to content

Commit

Permalink
sql: Added CREATE SEQ AS <typename> postgres compatibility
Browse files Browse the repository at this point in the history
Previously, unimplementedWithIssueDetail error was thrown
when an AS in CREATE SEQ AS was encountered.

Now we support the AS option for creating sequences. Valid
option values are bigint/int8, int/integer/int4, and
smallint/int2. The typename value determines the min
and max values a sequence can take.

Release note (sql change): Enabled CREATE SEQ AS <typename> functionality.
  • Loading branch information
mokaixu committed Dec 1, 2020
1 parent 8a54c58 commit a9de7d9
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 6 deletions.
4 changes: 2 additions & 2 deletions docs/generated/sql/bnf/alter_sequence_options_stmt.bnf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
alter_sequence_options_stmt ::=
'ALTER' 'SEQUENCE' sequence_name ( ( ( 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) ( ( ( 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) )* )
| 'ALTER' 'SEQUENCE' 'IF' 'EXISTS' sequence_name ( ( ( 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) ( ( ( 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) )* )
'ALTER' 'SEQUENCE' sequence_name ( ( ( 'AS' typename | 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) ( ( ( 'AS' typename | 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) )* )
| 'ALTER' 'SEQUENCE' 'IF' 'EXISTS' sequence_name ( ( ( 'AS' typename | 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) ( ( ( 'AS' typename | 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) )* )
4 changes: 2 additions & 2 deletions docs/generated/sql/bnf/create_sequence_stmt.bnf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
create_sequence_stmt ::=
'CREATE' opt_temp 'SEQUENCE' sequence_name ( ( ( ( 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) ( ( ( 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) )* ) | )
| 'CREATE' opt_temp 'SEQUENCE' 'IF' 'NOT' 'EXISTS' sequence_name ( ( ( ( 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) ( ( ( 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) )* ) | )
'CREATE' opt_temp 'SEQUENCE' sequence_name ( ( ( ( 'AS' typename | 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) ( ( ( 'AS' typename | 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) )* ) | )
| 'CREATE' opt_temp 'SEQUENCE' 'IF' 'NOT' 'EXISTS' sequence_name ( ( ( ( 'AS' typename | 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) ( ( ( 'AS' typename | 'NO' 'CYCLE' | 'OWNED' 'BY' 'NONE' | 'OWNED' 'BY' column_name | 'INCREMENT' integer | 'INCREMENT' 'BY' integer | 'MINVALUE' integer | 'NO' 'MINVALUE' | 'MAXVALUE' integer | 'NO' 'MAXVALUE' | 'START' integer | 'START' 'WITH' integer | 'VIRTUAL' ) ) )* ) | )
3 changes: 2 additions & 1 deletion docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -2482,7 +2482,8 @@ alter_index_cmd ::=
partition_by

sequence_option_elem ::=
'NO' 'CYCLE'
'AS' typename
| 'NO' 'CYCLE'
| 'OWNED' 'BY' 'NONE'
| 'OWNED' 'BY' column_path
| 'INCREMENT' signed_iconst64
Expand Down
41 changes: 41 additions & 0 deletions pkg/ccl/importccl/import_stmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,47 @@ func TestImportUserDefinedTypes(t *testing.T) {
}
}

func TestCreateSequenceAs(t *testing.T) {
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)
ctx := context.Background()
baseDir, cleanup := testutils.TempDir(t)
defer cleanup()
tc := testcluster.StartTestCluster(
t, 1, base.TestClusterArgs{ServerArgs: base.TestServerArgs{ExternalIODir: baseDir}})
defer tc.Stopper().Stop(ctx)
conn := tc.Conns[0]
sqlDB := sqlutils.MakeSQLRunner(conn)

var data string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
_, _ = w.Write([]byte(data))
}
}))
defer srv.Close()

t.Run("pgdump sequence as", func(t *testing.T) {

sqlDB.Exec(t, `DROP SEQUENCE IF EXISTS blah`)

data = `
CREATE SEQUENCE public.blah
AS integer
START WITH 1
INCREMENT BY 1
CACHE 1;`

// Import sequence from dump format.
importDumpQuery := fmt.Sprintf(`IMPORT PGDUMP ($1)`)
sqlDB.Exec(t, importDumpQuery, srv.URL)

res := sqlDB.QueryStr(t, `SELECT * FROM blah`)

sqlDB.Exec(t, `DROP SEQUENCE blah`)
})
}

func TestImportRowLimit(t *testing.T) {
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)
Expand Down
3 changes: 2 additions & 1 deletion pkg/sql/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -6446,6 +6446,7 @@ reference_action:
// %Category: DDL
// %Text:
// CREATE [TEMPORARY | TEMP] SEQUENCE <seqname>
// [AS <typename>]
// [INCREMENT <increment>]
// [MINVALUE <minvalue> | NO MINVALUE]
// [MAXVALUE <maxvalue> | NO MAXVALUE]
Expand Down Expand Up @@ -6485,7 +6486,7 @@ sequence_option_list:
| sequence_option_list sequence_option_elem { $$.val = append($1.seqOpts(), $2.seqOpt()) }

sequence_option_elem:
AS typename { return unimplementedWithIssueDetail(sqllex, 25110, $2.typeReference().SQLString()) }
AS typename { $$.val = tree.SequenceOption{Name: tree.SeqOptAs, AsTypename: $2.colType()}}
| CYCLE { /* SKIP DOC */
$$.val = tree.SequenceOption{Name: tree.SeqOptCycle} }
| NO CYCLE { $$.val = tree.SequenceOption{Name: tree.SeqOptNoCycle} }
Expand Down
7 changes: 7 additions & 0 deletions pkg/sql/sem/tree/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,11 @@ func (node *SequenceOptions) Format(ctx *FmtCtx) {
option := &(*node)[i]
ctx.WriteByte(' ')
switch option.Name {
case SeqOptAs:
ctx.WriteString(option.Name)
ctx.WriteByte(' ')
ctx.WriteString(option.AsTypename.Name())
// TODO(monicax): Test this.
case SeqOptCycle, SeqOptNoCycle:
ctx.WriteString(option.Name)
case SeqOptCache:
Expand Down Expand Up @@ -1442,6 +1447,8 @@ func (node *SequenceOptions) Format(ctx *FmtCtx) {
type SequenceOption struct {
Name string

AsTypename *types.T

IntVal *int64

OptionalWord bool
Expand Down
18 changes: 18 additions & 0 deletions pkg/sql/sequence.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/privilege"
"github.com/cockroachdb/cockroach/pkg/sql/sem/builtins"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/sql/types"
"github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented"
"github.com/cockroachdb/cockroach/pkg/util/log"
"github.com/cockroachdb/cockroach/pkg/util/sequence"
Expand Down Expand Up @@ -275,6 +276,23 @@ func assignSequenceOptions(
optionsSeen[option.Name] = true

switch option.Name {
case tree.SeqOptAs:
typename := option.AsTypename
switch typename {
case types.Int2:
// TODO(monicax): refactor this
if isAscending {
opts.MinValue = 1
opts.MaxValue = math.MaxInt16
opts.Start = opts.MinValue
} else {
opts.MinValue = math.MinInt16
opts.MaxValue = -1
opts.Start = opts.MaxValue
}
case types.Int: // this is what integer AND bigint map to
// Do nothing; this is the default.
}
case tree.SeqOptCycle:
return unimplemented.NewWithIssue(20961,
"CYCLE option is not supported")
Expand Down

0 comments on commit a9de7d9

Please sign in to comment.