Skip to content

Commit

Permalink
sql: add unimplemented support for drop type
Browse files Browse the repository at this point in the history
This PR adds unimplemented support for the DROP TYPE command,
as well as adding some missing help/annotations for the CREATE
TYPE command.

Release note: None
  • Loading branch information
rohany committed Apr 16, 2020
1 parent 1a51a57 commit 524cfda
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 10 deletions.
1 change: 1 addition & 0 deletions docs/generated/sql/bnf/drop_stmt.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ drop_stmt ::=
| drop_table_stmt
| drop_view_stmt
| drop_sequence_stmt
| drop_type_stmt
| drop_role_stmt
22 changes: 22 additions & 0 deletions docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ create_ddl_stmt ::=
| create_schema_stmt
| create_table_stmt
| create_table_as_stmt
| create_type_stmt
| create_view_stmt
| create_sequence_stmt

Expand Down Expand Up @@ -381,6 +382,7 @@ drop_ddl_stmt ::=
| drop_table_stmt
| drop_view_stmt
| drop_sequence_stmt
| drop_type_stmt

drop_role_stmt ::=
'DROP' role_or_group_or_user string_or_placeholder_list
Expand Down Expand Up @@ -1028,6 +1030,9 @@ create_table_as_stmt ::=
'CREATE' opt_temp_create_table 'TABLE' table_name create_as_opt_col_list 'AS' select_stmt
| 'CREATE' opt_temp_create_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name create_as_opt_col_list 'AS' select_stmt

create_type_stmt ::=
'CREATE' 'TYPE' type_name 'AS' 'ENUM' '(' opt_enum_val_list ')'

create_view_stmt ::=
'CREATE' opt_temp 'VIEW' view_name opt_column_list 'AS' select_stmt
| 'CREATE' 'OR' 'REPLACE' opt_temp 'VIEW' view_name opt_column_list 'AS' select_stmt
Expand Down Expand Up @@ -1093,6 +1098,10 @@ drop_sequence_stmt ::=
'DROP' 'SEQUENCE' table_name_list opt_drop_behavior
| 'DROP' 'SEQUENCE' 'IF' 'EXISTS' table_name_list opt_drop_behavior

drop_type_stmt ::=
'DROP' 'TYPE' type_name_list opt_drop_behavior
| 'DROP' 'TYPE' 'IF' 'EXISTS' type_name_list opt_drop_behavior

explain_option_name ::=
non_reserved_word

Expand Down Expand Up @@ -1439,6 +1448,13 @@ create_as_opt_col_list ::=
'(' create_as_table_defs ')'
|

type_name ::=
db_object_name

opt_enum_val_list ::=
enum_val_list
|

opt_temp ::=
'TEMPORARY'
| 'TEMP'
Expand Down Expand Up @@ -1491,6 +1507,9 @@ table_index_name_list ::=
table_name_list ::=
( table_name ) ( ( ',' table_name ) )*

type_name_list ::=
( type_name ) ( ( ',' type_name ) )*

non_reserved_word ::=
'identifier'
| unreserved_keyword
Expand Down Expand Up @@ -1789,6 +1808,9 @@ partition_by ::=
create_as_table_defs ::=
( column_name create_as_col_qual_list ) ( ( ',' column_name create_as_col_qual_list | ',' family_def | ',' create_as_constraint_def ) )*

enum_val_list ::=
( 'SCONST' ) ( ( ',' 'SCONST' ) )*

common_table_expr ::=
table_alias_name opt_column_list 'AS' '(' preparable_stmt ')'

Expand Down
1 change: 1 addition & 0 deletions pkg/sql/create_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ func (n *createTypeNode) startExec(params runParams) error {
func (n *createTypeNode) Next(params runParams) (bool, error) { return false, nil }
func (n *createTypeNode) Values() tree.Datums { return tree.Datums{} }
func (n *createTypeNode) Close(ctx context.Context) {}
func (n *createTypeNode) ReadingOwnWrites() {}
41 changes: 41 additions & 0 deletions pkg/sql/drop_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package sql

import (
"context"

"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented"
"github.com/cockroachdb/errors"
)

type dropTypeNode struct {
n *tree.DropType
}

// Use to satisfy the linter.
var _ planNode = &dropTypeNode{n: nil}

func (p *planner) DropType(ctx context.Context, n *tree.DropType) (planNode, error) {
return nil, unimplemented.NewWithIssue(27793, "DROP TYPE")
}

func (n *dropTypeNode) startExec(params runParams) error {
return errors.AssertionFailedf(
"should not be calling startExec on DROP TYPE node",
)
}

func (n *dropTypeNode) Next(params runParams) (bool, error) { return false, nil }
func (n *dropTypeNode) Values() tree.Datums { return tree.Datums{} }
func (n *dropTypeNode) Close(ctx context.Context) {}
func (n *dropTypeNode) ReadingOwnWrites() {}
6 changes: 6 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/enums
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
statement error pq: unimplemented: CREATE TYPE
CREATE TYPE mytype AS ENUM ('val1', 'val2')

statement error pq: unimplemented: DROP TYPE
DROP TYPE mytype

statement error pq: unimplemented: DROP TYPE
DROP TYPE IF EXISTS mytype
3 changes: 3 additions & 0 deletions pkg/sql/opaque.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ func buildOpaque(
plan, err = p.DropRole(ctx, n)
case *tree.DropTable:
plan, err = p.DropTable(ctx, n)
case *tree.DropType:
plan, err = p.DropType(ctx, n)
case *tree.DropView:
plan, err = p.DropView(ctx, n)
case *tree.DropSequence:
Expand Down Expand Up @@ -180,6 +182,7 @@ func init() {
&tree.DropDatabase{},
&tree.DropIndex{},
&tree.DropTable{},
&tree.DropType{},
&tree.DropView{},
&tree.DropRole{},
&tree.DropSequence{},
Expand Down
3 changes: 3 additions & 0 deletions pkg/sql/parser/help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ func TestContextualHelp(t *testing.T) {
{`CREATE TABLE blah AS (SELECT 1) ??`, `CREATE TABLE`},
{`CREATE TABLE blah AS SELECT 1 ??`, `SELECT`},

{`CREATE TYPE blah AS ENUM ??`, `CREATE TYPE`},
{`DROP TYPE ??`, `DROP TYPE`},

{`CREATE SCHEMA IF ??`, `CREATE SCHEMA`},
{`CREATE SCHEMA IF NOT ??`, `CREATE SCHEMA`},
{`CREATE SCHEMA bli ??`, `CREATE SCHEMA`},
Expand Down
9 changes: 8 additions & 1 deletion pkg/sql/parser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,14 @@ func TestParse(t *testing.T) {
{`CREATE TYPE a.b AS ENUM ('a', 'b', 'c')`},
{`CREATE TYPE a.b.c AS ENUM ('a', 'b', 'c')`},

{`DROP TYPE a`},
{`DROP TYPE a, b, c`},
{`DROP TYPE db.sc.a, sc.a`},
{`DROP TYPE IF EXISTS db.sc.a, sc.a`},
{`DROP TYPE db.sc.a, sc.a CASCADE`},
{`DROP TYPE IF EXISTS db.sc.a, sc.a CASCADE`},
{`DROP TYPE IF EXISTS db.sc.a, sc.a RESTRICT`},

{`DELETE FROM a`},
{`EXPLAIN DELETE FROM a`},
{`DELETE FROM a.b`},
Expand Down Expand Up @@ -3210,7 +3218,6 @@ func TestUnimplementedSyntax(t *testing.T) {
{`DROP SUBSCRIPTION a`, 0, `drop subscription`, ``},
{`DROP TEXT SEARCH a`, 7821, `drop text`, ``},
{`DROP TRIGGER a`, 28296, `drop`, ``},
{`DROP TYPE a`, 27793, `drop type`, ``},

{`DISCARD PLANS`, 0, `discard plans`, ``},
{`DISCARD SEQUENCES`, 0, `discard sequences`, ``},
Expand Down
62 changes: 53 additions & 9 deletions pkg/sql/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ func (u *sqlSymUnion) unresolvedName() *tree.UnresolvedName {
func (u *sqlSymUnion) unresolvedObjectName() *tree.UnresolvedObjectName {
return u.val.(*tree.UnresolvedObjectName)
}
func (u *sqlSymUnion) unresolvedObjectNames() []*tree.UnresolvedObjectName {
return u.val.([]*tree.UnresolvedObjectName)
}
func (u *sqlSymUnion) functionReference() tree.FunctionReference {
return u.val.(tree.FunctionReference)
}
Expand Down Expand Up @@ -743,6 +746,7 @@ func newNameFromStr(s string) *tree.Name {
%type <tree.Statement> drop_index_stmt
%type <tree.Statement> drop_role_stmt
%type <tree.Statement> drop_table_stmt
%type <tree.Statement> drop_type_stmt
%type <tree.Statement> drop_view_stmt
%type <tree.Statement> drop_sequence_stmt

Expand Down Expand Up @@ -867,6 +871,7 @@ func newNameFromStr(s string) *tree.Name {
%type <str> family_name opt_family_name table_alias_name constraint_name target_name zone_name partition_name collation_name
%type <str> db_object_name_component
%type <*tree.UnresolvedObjectName> table_name standalone_index_name sequence_name type_name view_name db_object_name simple_db_object_name complex_db_object_name
%type <[]*tree.UnresolvedObjectName> type_name_list
%type <str> schema_name
%type <*tree.UnresolvedName> table_pattern complex_table_pattern
%type <*tree.UnresolvedName> column_path prefixed_column_path column_path_with_star
Expand Down Expand Up @@ -2268,7 +2273,7 @@ comment_text:
// %Text:
// CREATE DATABASE, CREATE TABLE, CREATE INDEX, CREATE TABLE AS,
// CREATE USER, CREATE VIEW, CREATE SEQUENCE, CREATE STATISTICS,
// CREATE ROLE
// CREATE ROLE, CREATE TYPE
create_stmt:
create_role_stmt // EXTEND WITH HELP: CREATE ROLE
| create_ddl_stmt // help texts in sub-rule
Expand Down Expand Up @@ -2329,7 +2334,6 @@ drop_unsupported:
| DROP SERVER error { return unimplemented(sqllex, "drop server") }
| DROP SUBSCRIPTION error { return unimplemented(sqllex, "drop subscription") }
| DROP TEXT error { return unimplementedWithIssueDetail(sqllex, 7821, "drop text") }
| DROP TYPE error { return unimplementedWithIssueDetail(sqllex, 27793, "drop type") }
| DROP TRIGGER error { return unimplementedWithIssueDetail(sqllex, 28296, "drop") }

create_ddl_stmt:
Expand All @@ -2341,7 +2345,7 @@ create_ddl_stmt:
| create_table_as_stmt // EXTEND WITH HELP: CREATE TABLE
// Error case for both CREATE TABLE and CREATE TABLE ... AS in one
| CREATE opt_temp_create_table TABLE error // SHOW HELP: CREATE TABLE
| create_type_stmt { /* SKIP DOC */ }
| create_type_stmt // EXTEND WITH HELP: CREATE TYPE
| create_view_stmt // EXTEND WITH HELP: CREATE VIEW
| create_sequence_stmt // EXTEND WITH HELP: CREATE SEQUENCE

Expand Down Expand Up @@ -2534,7 +2538,7 @@ discard_stmt:
// %Category: Group
// %Text:
// DROP DATABASE, DROP INDEX, DROP TABLE, DROP VIEW, DROP SEQUENCE,
// DROP USER, DROP ROLE
// DROP USER, DROP ROLE, DROP TYPE
drop_stmt:
drop_ddl_stmt // help texts in sub-rule
| drop_role_stmt // EXTEND WITH HELP: DROP ROLE
Expand All @@ -2547,6 +2551,7 @@ drop_ddl_stmt:
| drop_table_stmt // EXTEND WITH HELP: DROP TABLE
| drop_view_stmt // EXTEND WITH HELP: DROP VIEW
| drop_sequence_stmt // EXTEND WITH HELP: DROP SEQUENCE
| drop_type_stmt // EXTEND WITH HELP: DROP TYPE

// %Help: DROP VIEW - remove a view
// %Category: DDL
Expand Down Expand Up @@ -2641,6 +2646,41 @@ drop_database_stmt:
}
| DROP DATABASE error // SHOW HELP: DROP DATABASE

// %Help: DROP TYPE - remove a type
// %Category: DDL
// %Text: DROP TYPE [IF EXISTS] <type_name> [, ...] [CASCASE | RESTRICT]
// %SeeAlso: WEBDOCS/drop-type.html
drop_type_stmt:
DROP TYPE type_name_list opt_drop_behavior
{
$$.val = &tree.DropType{
Names: $3.unresolvedObjectNames(),
IfExists: false,
DropBehavior: $4.dropBehavior(),
}
}
| DROP TYPE IF EXISTS type_name_list opt_drop_behavior
{
$$.val = &tree.DropType{
Names: $5.unresolvedObjectNames(),
IfExists: true,
DropBehavior: $6.dropBehavior(),
}
}
| DROP TYPE error // SHOW HELP: DROP TYPE


type_name_list:
type_name
{
$$.val = []*tree.UnresolvedObjectName{$1.unresolvedObjectName()}
}
| type_name_list ',' type_name
{
$$.val = append($1.unresolvedObjectNames(), $3.unresolvedObjectName())
}


// %Help: DROP ROLE - remove a user
// %Category: Priv
// %Text: DROP ROLE [IF EXISTS] <user> [, ...]
Expand Down Expand Up @@ -5412,20 +5452,24 @@ opt_view_recursive:
/* EMPTY */ { /* no error */ }
| RECURSIVE { return unimplemented(sqllex, "create recursive view") }

// CREATE TYPE/DOMAIN is not yet supported by CockroachDB but we
// want to report it with the right issue number.

// %Help: CREATE TYPE -- create a type
// %Category: DDL
// %Text: CREATE TYPE <type_name> AS ENUM (...)
// %SeeAlso: WEBDOCS/create-type.html
create_type_stmt:
// Record/Composite types.
CREATE TYPE type_name AS '(' error { return unimplementedWithIssue(sqllex, 27792) }
// Enum types.
| CREATE TYPE type_name AS ENUM '(' opt_enum_val_list ')'
CREATE TYPE type_name AS ENUM '(' opt_enum_val_list ')'
{
$$.val = &tree.CreateType{
TypeName: $3.unresolvedObjectName(),
Variety: tree.Enum,
EnumLabels: $7.strs(),
}
}
| CREATE TYPE error // SHOW HELP: CREATE TYPE
// Record/Composite types.
| CREATE TYPE type_name AS '(' error { return unimplementedWithIssue(sqllex, 27792) }
// Range types.
| CREATE TYPE type_name AS RANGE error { return unimplementedWithIssue(sqllex, 27791) }
// Base (primitive) types.
Expand Down
4 changes: 4 additions & 0 deletions pkg/sql/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ var _ planNode = &createIndexNode{}
var _ planNode = &createSequenceNode{}
var _ planNode = &createStatsNode{}
var _ planNode = &createTableNode{}
var _ planNode = &createTypeNode{}
var _ planNode = &CreateRoleNode{}
var _ planNode = &createViewNode{}
var _ planNode = &delayedNode{}
Expand All @@ -177,6 +178,7 @@ var _ planNode = &dropDatabaseNode{}
var _ planNode = &dropIndexNode{}
var _ planNode = &dropSequenceNode{}
var _ planNode = &dropTableNode{}
var _ planNode = &dropTypeNode{}
var _ planNode = &DropRoleNode{}
var _ planNode = &dropViewNode{}
var _ planNode = &errorIfRowsNode{}
Expand Down Expand Up @@ -237,8 +239,10 @@ var _ planNodeReadingOwnWrites = &alterTableNode{}
var _ planNodeReadingOwnWrites = &createIndexNode{}
var _ planNodeReadingOwnWrites = &createSequenceNode{}
var _ planNodeReadingOwnWrites = &createTableNode{}
var _ planNodeReadingOwnWrites = &createTypeNode{}
var _ planNodeReadingOwnWrites = &createViewNode{}
var _ planNodeReadingOwnWrites = &changePrivilegesNode{}
var _ planNodeReadingOwnWrites = &dropTypeNode{}
var _ planNodeReadingOwnWrites = &setZoneConfigNode{}

// planNodeRequireSpool serves as marker for nodes whose parent must
Expand Down
27 changes: 27 additions & 0 deletions pkg/sql/sem/tree/drop.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,30 @@ func (node *DropRole) Format(ctx *FmtCtx) {
}
ctx.FormatNode(&node.Names)
}

// DropType represents a DROP TYPE command.
type DropType struct {
Names []*UnresolvedObjectName
IfExists bool
DropBehavior DropBehavior
}

var _ Statement = &DropType{}

// Format implements the NodeFormatter interface.
func (node *DropType) Format(ctx *FmtCtx) {
ctx.WriteString("DROP TYPE ")
if node.IfExists {
ctx.WriteString("IF EXISTS ")
}
for i := range node.Names {
if i > 0 {
ctx.WriteString(", ")
}
ctx.FormatNode(node.Names[i])
}
if node.DropBehavior != DropDefault {
ctx.WriteByte(' ')
ctx.WriteString(node.DropBehavior.String())
}
}
Loading

0 comments on commit 524cfda

Please sign in to comment.