Skip to content

Commit

Permalink
sql: add support for ANALYZE <tablename>
Browse files Browse the repository at this point in the history
This commit adds support for `ANALYZE <tablename>` by adding the
statement as syntactic sugar for the equivalent command
`CREATE STATISTICS "" FROM <tablename>`. This improves compatibility
with Postgres, and is needed to run the PostGIS tutorial as written.

Note that this commit does not add support for `ANALYZE` without a
table name. We can add support for that and other variants later if
needed, but it is not necessary for the PostGIS tutorial.

Fixes #49214

Release note (sql change): Added support for `ANALYZE <tablename>`,
which causes the database to collect statistics on the given table for
use by the optimizer. The functionality of this command is equivalent
to the existing command `CREATE STATISTICS "" FROM <tablename>`, but
it increases compatibility with Postgres by using the same syntax that
Postgres uses.
  • Loading branch information
rytaft committed Jun 2, 2020
1 parent a18b32f commit 871d1b3
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 2 deletions.
8 changes: 8 additions & 0 deletions docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ stmt_block ::=
stmt ::=
'HELPTOKEN'
| preparable_stmt
| analyze_stmt
| copy_from_stmt
| comment_stmt
| execute_stmt
Expand Down Expand Up @@ -42,6 +43,10 @@ preparable_stmt ::=
| update_stmt
| upsert_stmt

analyze_stmt ::=
'ANALYZE' analyze_target
| 'ANALYSE' analyze_target

copy_from_stmt ::=
'COPY' table_name opt_column_list 'FROM' 'STDIN' opt_with_options

Expand Down Expand Up @@ -206,6 +211,9 @@ update_stmt ::=
upsert_stmt ::=
opt_with_clause 'UPSERT' 'INTO' insert_target insert_rest returning_clause

analyze_target ::=
table_name

table_name ::=
db_object_name

Expand Down
8 changes: 8 additions & 0 deletions pkg/sql/create_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ func (p *planner) CreateStatistics(ctx context.Context, n *tree.CreateStats) (pl
}, nil
}

// Analyze is syntactic sugar for CreateStatistics.
func (p *planner) Analyze(ctx context.Context, n *tree.Analyze) (planNode, error) {
return &createStatsNode{
CreateStats: tree.CreateStats{Table: n.Table},
p: p,
}, nil
}

// createStatsNode is a planNode implemented in terms of a function. The
// startJob function starts a Job during Start, and the remainder of the
// CREATE STATISTICS planning and execution is performed within the jobs
Expand Down
27 changes: 27 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/distsql_stats
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,36 @@ NULL {b} 256 4 0 true
let $json_stats
SHOW STATISTICS USING JSON FOR TABLE data

# ANALYZE is syntactic sugar for CREATE STATISTICS with default columns.
statement ok
ANALYZE data

query TTIIIB colnames
SELECT
statistics_name,
column_names,
row_count,
distinct_count,
null_count,
histogram_id IS NOT NULL AS has_histogram
FROM
[SHOW STATISTICS FOR TABLE data];
----
statistics_name column_names row_count distinct_count null_count has_histogram
NULL {a} 256 4 0 true
NULL {a,b} 256 16 0 false
NULL {a,b,c} 256 64 0 false
NULL {a,b,c,d} 256 256 0 false
NULL {c} 256 4 0 true
NULL {c,d} 256 16 0 false
NULL {b} 256 4 0 false
NULL {d} 256 4 0 false
NULL {e} 256 2 0 true

statement ok
DELETE FROM system.table_statistics

# Restore the old stats.
statement ok
ALTER TABLE data INJECT STATISTICS '$json_stats'

Expand Down
3 changes: 3 additions & 0 deletions pkg/sql/opaque.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ func buildOpaque(
plan, err = p.AlterRole(ctx, n)
case *tree.AlterSequence:
plan, err = p.AlterSequence(ctx, n)
case *tree.Analyze:
plan, err = p.Analyze(ctx, n)
case *tree.CommentOnColumn:
plan, err = p.CommentOnColumn(ctx, n)
case *tree.CommentOnDatabase:
Expand Down Expand Up @@ -169,6 +171,7 @@ func init() {
&tree.AlterType{},
&tree.AlterSequence{},
&tree.AlterRole{},
&tree.Analyze{},
&tree.CommentOnColumn{},
&tree.CommentOnDatabase{},
&tree.CommentOnIndex{},
Expand Down
34 changes: 32 additions & 2 deletions pkg/sql/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,7 @@ func (u *sqlSymUnion) alterTypeAddValuePlacement() *tree.AlterTypeAddValuePlacem
%type <tree.Statement> drop_view_stmt
%type <tree.Statement> drop_sequence_stmt

%type <tree.Statement> analyze_stmt
%type <tree.Statement> explain_stmt
%type <tree.Statement> prepare_stmt
%type <tree.Statement> preparable_stmt
Expand Down Expand Up @@ -887,7 +888,7 @@ func (u *sqlSymUnion) alterTypeAddValuePlacement() *tree.AlterTypeAddValuePlacem
%type <str> schema_name
%type <*tree.UnresolvedName> table_pattern complex_table_pattern
%type <*tree.UnresolvedName> column_path prefixed_column_path column_path_with_star
%type <tree.TableExpr> insert_target create_stats_target
%type <tree.TableExpr> insert_target create_stats_target analyze_target

%type <*tree.TableIndexName> table_index_name
%type <tree.TableIndexNames> table_index_name_list
Expand Down Expand Up @@ -1169,7 +1170,8 @@ stmt_block:

stmt:
HELPTOKEN { return helpWith(sqllex, "") }
| preparable_stmt // help texts in sub-rule
| preparable_stmt // help texts in sub-rule
| analyze_stmt // EXTEND WITH HELP: ANALYZE
| copy_from_stmt
| comment_stmt
| execute_stmt // EXTEND WITH HELP: EXECUTE
Expand Down Expand Up @@ -2844,6 +2846,34 @@ table_name_list:
$$.val = append($1.tableNames(), name)
}

// %Help: ANALYZE - collect table statistics
// %Category: Misc
// %Text:
// ANALYZE <tablename>
//
// %SeeAlso: CREATE STATISTICS
analyze_stmt:
ANALYZE analyze_target
{
$$.val = &tree.Analyze{
Table: $2.tblExpr(),
}
}
| ANALYZE error // SHOW HELP: ANALYZE
| ANALYSE analyze_target
{
$$.val = &tree.Analyze{
Table: $2.tblExpr(),
}
}
| ANALYSE error // SHOW HELP: ANALYZE

analyze_target:
table_name
{
$$.val = $1.unresolvedObjectName()
}

// %Help: EXPLAIN - show the logical plan of a query
// %Category: Misc
// %Text:
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/plan_opt.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func (p *planner) prepareUsingOptimizer(ctx context.Context) (planFlags, error)

switch stmt.AST.(type) {
case *tree.AlterIndex, *tree.AlterTable, *tree.AlterSequence,
*tree.Analyze,
*tree.BeginTransaction,
*tree.CommentOnColumn, *tree.CommentOnDatabase, *tree.CommentOnIndex, *tree.CommentOnTable,
*tree.CommitTransaction,
Expand Down
22 changes: 22 additions & 0 deletions pkg/sql/sem/tree/analyze.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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 tree

// Analyze represents an ANALYZE statement.
type Analyze struct {
Table TableExpr
}

// Format implements the NodeFormatter interface.
func (node *Analyze) Format(ctx *FmtCtx) {
ctx.WriteString("ANALYZE ")
ctx.FormatNode(node.Table)
}
7 changes: 7 additions & 0 deletions pkg/sql/sem/tree/stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ func (*AlterRole) cclOnlyStatement() {}

func (*AlterRole) hiddenFromShowQueries() {}

// StatementType implements the Statement interface.
func (*Analyze) StatementType() StatementType { return DDL }

// StatementTag returns a short string identifying the type of statement.
func (*Analyze) StatementTag() string { return "ANALYZE" }

// StatementType implements the Statement interface.
func (*Backup) StatementType() StatementType { return Rows }

Expand Down Expand Up @@ -919,6 +925,7 @@ func (n *AlterTableSetNotNull) String() string { return AsString(n) }
func (n *AlterType) String() string { return AsString(n) }
func (n *AlterRole) String() string { return AsString(n) }
func (n *AlterSequence) String() string { return AsString(n) }
func (n *Analyze) String() string { return AsString(n) }
func (n *Backup) String() string { return AsString(n) }
func (n *BeginTransaction) String() string { return AsString(n) }
func (n *ControlJobs) String() string { return AsString(n) }
Expand Down

0 comments on commit 871d1b3

Please sign in to comment.