diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml
index b10b734b90..3406b7a1cd 100644
--- a/doc/src/sgml/perform.sgml
+++ b/doc/src/sgml/perform.sgml
@@ -1132,7 +1132,7 @@ WHERE tablename = 'road';
To inspect functional dependencies on a statistics
stts, you may do this:
-CREATE STATISTICS stts WITH (dependencies)
+CREATE STATISTICS stts USING (dependencies)
ON (zip, city) FROM zipcodes;
ANALYZE zipcodes;
SELECT stxname, stxkeys, stxdependencies
@@ -1219,7 +1219,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 10;
Continuing the above example, the n-distinct coefficients in a ZIP
code table may look like the following:
-CREATE STATISTICS stts2 WITH (ndistinct)
+CREATE STATISTICS stts2 USING (ndistinct)
ON (zip, state, city) FROM zipcodes;
ANALYZE zipcodes;
SELECT stxkeys AS k, stxndistinct AS nd
diff --git a/doc/src/sgml/planstats.sgml b/doc/src/sgml/planstats.sgml
index f4430eb23c..16c433c3a2 100644
--- a/doc/src/sgml/planstats.sgml
+++ b/doc/src/sgml/planstats.sgml
@@ -526,7 +526,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
multivariate statistics on the two columns:
-CREATE STATISTICS stts WITH (dependencies) ON (a, b) FROM t;
+CREATE STATISTICS stts USING (dependencies) ON (a, b) FROM t;
ANALYZE t;
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
QUERY PLAN
@@ -569,7 +569,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
calculation, the estimate is much improved:
DROP STATISTICS stts;
-CREATE STATISTICS stts WITH (dependencies, ndistinct) ON (a, b) FROM t;
+CREATE STATISTICS stts USING (dependencies, ndistinct) ON (a, b) FROM t;
ANALYZE t;
EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
QUERY PLAN
diff --git a/doc/src/sgml/ref/create_statistics.sgml b/doc/src/sgml/ref/create_statistics.sgml
index edbcf5840b..ff6ed0668f 100644
--- a/doc/src/sgml/ref/create_statistics.sgml
+++ b/doc/src/sgml/ref/create_statistics.sgml
@@ -22,7 +22,7 @@ PostgreSQL documentation
CREATE STATISTICS [ IF NOT EXISTS ] statistics_name
- WITH ( option [= value] [, ... ] )
+ USING ( statistic_type [, ... ] )
ON ( column_name, column_name [, ...])
FROM table_name
@@ -103,14 +103,14 @@ CREATE STATISTICS [ IF NOT EXISTS ] statistics_na
- The WITH> clause can specify options>
- for the statistics. Available options are listed below.
+ The USING> clause can specify types of statistics
+ to be enabled. Available types are listed below.
- dependencies> (boolean>)
+ dependencies>
Enables functional dependencies for the statistics.
@@ -119,7 +119,7 @@ CREATE STATISTICS [ IF NOT EXISTS ] statistics_na
- ndistinct> (boolean>)
+ ndistinct>
Enables ndistinct coefficients for the statistics.
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index 0b9c33e30a..f4d1712091 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -194,23 +194,22 @@ CreateStatistics(CreateStatsStmt *stmt)
stxkeys = buildint2vector(attnums, numcols);
/*
- * Parse the statistics options. Currently only statistics types are
- * recognized.
+ * Parse the statistic type options.
*/
build_ndistinct = false;
build_dependencies = false;
- foreach(l, stmt->options)
+ foreach(l, stmt->stat_options)
{
DefElem *opt = (DefElem *) lfirst(l);
if (strcmp(opt->defname, "ndistinct") == 0)
{
- build_ndistinct = defGetBoolean(opt);
+ build_ndistinct = true;
requested_type = true;
}
else if (strcmp(opt->defname, "dependencies") == 0)
{
- build_dependencies = defGetBoolean(opt);
+ build_dependencies = true;
requested_type = true;
}
else
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 35a237a000..01c57e4783 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3391,7 +3391,7 @@ _copyCreateStatsStmt(const CreateStatsStmt *from)
COPY_NODE_FIELD(defnames);
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(keys);
- COPY_NODE_FIELD(options);
+ COPY_NODE_FIELD(stat_options);
COPY_SCALAR_FIELD(if_not_exists);
return newnode;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 21dfbb0d75..01e2124883 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1351,7 +1351,7 @@ _equalCreateStatsStmt(const CreateStatsStmt *a, const CreateStatsStmt *b)
COMPARE_NODE_FIELD(defnames);
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(keys);
- COMPARE_NODE_FIELD(options);
+ COMPARE_NODE_FIELD(stat_options);
COMPARE_SCALAR_FIELD(if_not_exists);
return true;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 98f67681a7..015537a4c8 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -2641,7 +2641,7 @@ _outCreateStatsStmt(StringInfo str, const CreateStatsStmt *node)
WRITE_NODE_FIELD(defnames);
WRITE_NODE_FIELD(relation);
WRITE_NODE_FIELD(keys);
- WRITE_NODE_FIELD(options);
+ WRITE_NODE_FIELD(stat_options);
WRITE_BOOL_FIELD(if_not_exists);
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 818d2c29d4..a3467f1c47 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -371,6 +371,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
OptTableElementList TableElementList OptInherit definition
OptTypedTableElementList TypedTableElementList
reloptions opt_reloptions
+ stat_option_list opt_stat_option_list
OptWith distinct_clause opt_all_clause opt_definition func_args func_args_list
func_args_with_defaults func_args_with_defaults_list
aggr_args aggr_args_list
@@ -464,6 +465,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type TableElement TypedTableElement ConstraintElem TableFuncElement
%type columnDef columnOptions
%type def_elem reloption_elem old_aggr_elem operator_def_elem
+ stat_option_elem
%type def_arg columnElem where_clause where_or_current_clause
a_expr b_expr c_expr AexprConst indirection_el opt_slice_bound
columnref in_expr having_clause func_table xmltable array_expr
@@ -3828,32 +3830,59 @@ ExistingIndex: USING INDEX index_name { $$ = $3; }
/*****************************************************************************
*
* QUERY :
- * CREATE STATISTICS stats_name WITH (options) ON (columns) FROM relname
+ * CREATE STATISTICS stats_name [USING (stat_options)]
+ * ON (columns) FROM relname
*
*****************************************************************************/
-CreateStatsStmt: CREATE STATISTICS any_name opt_reloptions ON '(' columnList ')' FROM qualified_name
- {
- CreateStatsStmt *n = makeNode(CreateStatsStmt);
- n->defnames = $3;
- n->relation = $10;
- n->keys = $7;
- n->options = $4;
- n->if_not_exists = false;
- $$ = (Node *)n;
- }
- | CREATE STATISTICS IF_P NOT EXISTS any_name opt_reloptions ON '(' columnList ')' FROM qualified_name
- {
- CreateStatsStmt *n = makeNode(CreateStatsStmt);
- n->defnames = $6;
- n->relation = $13;
- n->keys = $10;
- n->options = $7;
- n->if_not_exists = true;
- $$ = (Node *)n;
- }
- ;
+opt_stat_option_list:
+ USING '(' stat_option_list ')' { $$ = $3; }
+ | /* EMPTY */ { $$ = NIL; }
+ ;
+
+stat_option_list:
+ stat_option_elem
+ {
+ $$ = list_make1($1);
+ }
+ | stat_option_list ',' stat_option_elem
+ {
+ $$ = lappend($1, $3);
+ }
+ ;
+
+stat_option_elem:
+ ColLabel
+ {
+ $$ = makeDefElem($1, NULL, @1);
+ }
+ ;
+
+CreateStatsStmt:
+ CREATE STATISTICS any_name opt_stat_option_list
+ ON '(' columnList ')' FROM qualified_name
+ {
+ CreateStatsStmt *n = makeNode(CreateStatsStmt);
+ n->defnames = $3;
+ n->relation = $10;
+ n->keys = $7;
+ n->stat_options = $4;
+ n->if_not_exists = false;
+ $$ = (Node *)n;
+ }
+ | CREATE STATISTICS IF_P NOT EXISTS any_name opt_stat_option_list
+ ON '(' columnList ')' FROM qualified_name
+ {
+ CreateStatsStmt *n = makeNode(CreateStatsStmt);
+ n->defnames = $6;
+ n->relation = $13;
+ n->keys = $10;
+ n->stat_options = $7;
+ n->if_not_exists = true;
+ $$ = (Node *)n;
+ }
+ ;
/*****************************************************************************
*
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index cbde1fff01..cdc1712928 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -1479,7 +1479,7 @@ pg_get_statisticsext_worker(Oid statextid, bool missing_ok)
NameStr(statextrec->stxname)));
/*
- * Lookup the stxkind column so that we know how to handle the WITH
+ * Lookup the stxkind column so that we know how to handle the USING
* clause.
*/
datum = SysCacheGetAttr(STATEXTOID, statexttup,
@@ -1504,15 +1504,15 @@ pg_get_statisticsext_worker(Oid statextid, bool missing_ok)
}
/*
- * If any option is disabled, then we'll need to append a WITH clause to
- * show which options are enabled. We omit the WITH clause on purpose
+ * If any option is disabled, then we'll need to append a USING clause to
+ * show which options are enabled. We omit the USING clause on purpose
* when all options are enabled, so a pg_dump/pg_restore will create all
* statistics types on a newer postgres version, if the statistics had all
* options enabled on the original version.
*/
if (!ndistinct_enabled || !dependencies_enabled)
{
- appendStringInfoString(&buf, " WITH (");
+ appendStringInfoString(&buf, " USING (");
if (ndistinct_enabled)
appendStringInfoString(&buf, "ndistinct");
else if (dependencies_enabled)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index dbfc7339e5..dbea7fa677 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -2385,7 +2385,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, " ");
/* statistics name (qualified with namespace) */
- appendPQExpBuffer(&buf, "\"%s.%s\" WITH (",
+ appendPQExpBuffer(&buf, "\"%s.%s\" USING (",
PQgetvalue(result, i, 1),
PQgetvalue(result, i, 2));
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index e1d454a07d..0409f9d814 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2691,7 +2691,7 @@ typedef struct CreateStatsStmt
List *defnames; /* qualified name (list of Value strings) */
RangeVar *relation; /* relation to build statistics on */
List *keys; /* String nodes naming referenced columns */
- List *options; /* list of DefElem */
+ List *stat_options; /* list of name-only DefElem for stat types */
bool if_not_exists; /* do nothing if statistics already exists */
} CreateStatsStmt;
diff --git a/src/test/regress/expected/stats_ext.out b/src/test/regress/expected/stats_ext.out
index 92ac84ac67..e756f58e2d 100644
--- a/src/test/regress/expected/stats_ext.out
+++ b/src/test/regress/expected/stats_ext.out
@@ -31,7 +31,7 @@ ALTER TABLE ab1 DROP COLUMN a;
b | integer | | |
c | integer | | |
Statistics:
- "public.ab1_b_c_stats" WITH (ndistinct, dependencies) ON (b, c)
+ "public.ab1_b_c_stats" USING (ndistinct, dependencies) ON (b, c)
DROP TABLE ab1;
-- Ensure things work sanely with SET STATISTICS 0
@@ -389,7 +389,7 @@ EXPLAIN (COSTS OFF)
(2 rows)
-- create statistics
-CREATE STATISTICS func_deps_stat WITH (dependencies) ON (a, b, c) FROM functional_dependencies;
+CREATE STATISTICS func_deps_stat USING (dependencies) ON (a, b, c) FROM functional_dependencies;
ANALYZE functional_dependencies;
EXPLAIN (COSTS OFF)
SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1';
@@ -432,7 +432,7 @@ EXPLAIN (COSTS OFF)
(2 rows)
-- create statistics
-CREATE STATISTICS func_deps_stat WITH (dependencies) ON (a, b, c) FROM functional_dependencies;
+CREATE STATISTICS func_deps_stat USING (dependencies) ON (a, b, c) FROM functional_dependencies;
ANALYZE functional_dependencies;
EXPLAIN (COSTS OFF)
SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1';
diff --git a/src/test/regress/sql/stats_ext.sql b/src/test/regress/sql/stats_ext.sql
index 72c7659c4b..15f863f3e0 100644
--- a/src/test/regress/sql/stats_ext.sql
+++ b/src/test/regress/sql/stats_ext.sql
@@ -233,7 +233,7 @@ EXPLAIN (COSTS OFF)
SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1;
-- create statistics
-CREATE STATISTICS func_deps_stat WITH (dependencies) ON (a, b, c) FROM functional_dependencies;
+CREATE STATISTICS func_deps_stat USING (dependencies) ON (a, b, c) FROM functional_dependencies;
ANALYZE functional_dependencies;
@@ -259,7 +259,7 @@ EXPLAIN (COSTS OFF)
SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1;
-- create statistics
-CREATE STATISTICS func_deps_stat WITH (dependencies) ON (a, b, c) FROM functional_dependencies;
+CREATE STATISTICS func_deps_stat USING (dependencies) ON (a, b, c) FROM functional_dependencies;
ANALYZE functional_dependencies;