Skip to content

Commit

Permalink
Merge #36977
Browse files Browse the repository at this point in the history
36977: sql: restrict statements that can be used as row sources r=RaduBerinde a=RaduBerinde

We currently support all preparable statements as row sources using
the `SELECT FROM [ ... ]` syntax. Many of these statements are not
really useful here and each one will require work when we deprecate
the heuristic planner.

This change restricts the set of statements that can be used as row
sources to DML statements, SHOW statements, and EXPLAIN. There were no
specific tests for this functionality for any of the statements that
were removed. If we find that we need any of them, we can add them
back on a case-by-case basis.

Release note (sql change): Only SELECT, INSERT, UPDATE, UPSERT,
DELETE, SHOW, EXPLAIN are supported as data sources using the `SELECT
...  FROM [ ... ]` syntax.

Informs #34848.

Co-authored-by: Radu Berinde <radu@cockroachlabs.com>
  • Loading branch information
craig[bot] and RaduBerinde committed Apr 22, 2019
2 parents 47168df + c72e9bd commit 4e23bc0
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 29 deletions.
11 changes: 10 additions & 1 deletion docs/generated/sql/bnf/stmt_block.bnf
Expand Up @@ -1827,7 +1827,7 @@ table_ref ::=
| '(' joined_table ')' opt_ordinality alias_clause
| func_table opt_ordinality opt_alias_clause
| 'LATERAL' func_table opt_ordinality opt_alias_clause
| '[' preparable_stmt ']' opt_ordinality opt_alias_clause
| '[' row_source_extension_stmt ']' opt_ordinality opt_alias_clause

all_or_distinct ::=
'ALL'
Expand Down Expand Up @@ -2055,6 +2055,15 @@ func_table ::=
func_expr_windowless
| 'ROWS' 'FROM' '(' rowsfrom_list ')'

row_source_extension_stmt ::=
delete_stmt
| explain_stmt
| insert_stmt
| select_stmt
| show_stmt
| update_stmt
| upsert_stmt

opt_column ::=
'COLUMN'
|
Expand Down
2 changes: 1 addition & 1 deletion docs/generated/sql/bnf/table_ref.bnf
Expand Up @@ -6,4 +6,4 @@ table_ref ::=
| '(' joined_table ')' ( 'WITH' 'ORDINALITY' | ) ( ( 'AS' table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) | table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) ) | )
| func_application ( 'WITH' 'ORDINALITY' | ) ( ( 'AS' table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) | table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) ) | )
| 'LATERAL' func_application ( 'WITH' 'ORDINALITY' | ) ( ( 'AS' table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) | table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) ) | )
| '[' preparable_stmt ']' ( 'WITH' 'ORDINALITY' | ) ( ( 'AS' table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) | table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) ) | )
| '[' row_source_extension_stmt ']' ( 'WITH' 'ORDINALITY' | ) ( ( 'AS' table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) | table_alias_name ( '(' ( ( name ) ( ( ',' name ) )* ) ')' | ) ) | )
20 changes: 0 additions & 20 deletions pkg/sql/explain_test.go
Expand Up @@ -177,26 +177,6 @@ func TestStatementReuses(t *testing.T) {
})
}
})
t.Run("SELECT * FROM <src>", func(t *testing.T) {
for _, test := range testData {
t.Run(test, func(t *testing.T) {
rows, err := db.Query("EXPLAIN SELECT * FROM [" + test + "]")
if err != nil {
if testutils.IsError(err, "statement source .* does not return any columns") {
// This error is acceptable and does not constitute a test failure.
return
}
t.Fatal(err)
}
defer rows.Close()
for rows.Next() {
}
if err := rows.Err(); err != nil {
t.Fatal(err)
}
})
}
})
t.Run("PREPARE EXPLAIN", func(t *testing.T) {
for _, test := range testData {
t.Run(test, func(t *testing.T) {
Expand Down
6 changes: 0 additions & 6 deletions pkg/sql/opt/optbuilder/testdata/create_table
Expand Up @@ -54,12 +54,6 @@ CREATE TABLE ab (a, b) AS SELECT 1, 2, 3
----
error (42601): CREATE TABLE specifies 2 column names, but data source has 3 columns

# Try to use CREATE TABLE in FROM clause.
build
SELECT * FROM [CREATE TABLE ab (a, b) AS SELECT 1, 2]
----
error (42703): statement source "CREATE TABLE ab (a, b) AS SELECT 1, 2" does not return any columns

# Non-existent column.
build
CREATE TABLE ab (a, b) AS SELECT a
Expand Down
17 changes: 16 additions & 1 deletion pkg/sql/parser/sql.y
Expand Up @@ -685,6 +685,7 @@ func newNameFromStr(s string) *tree.Name {
%type <tree.Statement> explain_stmt
%type <tree.Statement> prepare_stmt
%type <tree.Statement> preparable_stmt
%type <tree.Statement> row_source_extension_stmt
%type <tree.Statement> export_stmt
%type <tree.Statement> execute_stmt
%type <tree.Statement> deallocate_stmt
Expand Down Expand Up @@ -2503,6 +2504,20 @@ preparable_stmt:
| update_stmt // EXTEND WITH HELP: UPDATE
| upsert_stmt // EXTEND WITH HELP: UPSERT
// These are statements that can be used as a data source using the special
// syntax with brackets. These are a subset of preparable_stmt.
row_source_extension_stmt:
delete_stmt // EXTEND WITH HELP: DELETE
| explain_stmt // EXTEND WITH HELP: EXPLAIN
| insert_stmt // EXTEND WITH HELP: INSERT
| select_stmt // help texts in sub-rule
{
$$.val = $1.slct()
}
| show_stmt // help texts in sub-rule
| update_stmt // EXTEND WITH HELP: UPDATE
| upsert_stmt // EXTEND WITH HELP: UPSERT
explain_option_list:
explain_option_name
{
Expand Down Expand Up @@ -6093,7 +6108,7 @@ table_ref:
// will know from the unusual choice that something rather different
// is going on and may be pushed by the unusual syntax to
// investigate further in the docs.
| '[' preparable_stmt ']' opt_ordinality opt_alias_clause
| '[' row_source_extension_stmt ']' opt_ordinality opt_alias_clause
{
$$.val = &tree.AliasedTableExpr{Expr: &tree.StatementSource{ Statement: $2.stmt() }, Ordinality: $4.bool(), As: $5.aliasClause() }
}
Expand Down

0 comments on commit 4e23bc0

Please sign in to comment.