*** a/doc/src/sgml/perform.sgml
--- b/doc/src/sgml/perform.sgml
***************
*** 1132,1138 **** WHERE tablename = 'road';
       To inspect functional dependencies on a statistics
       <literal>stts</literal>, you may do this:
  <programlisting>
! CREATE STATISTICS stts WITH (dependencies)
                 ON (zip, city) FROM zipcodes;
  ANALYZE zipcodes;
  SELECT stxname, stxkeys, stxdependencies
--- 1132,1138 ----
       To inspect functional dependencies on a statistics
       <literal>stts</literal>, you may do this:
  <programlisting>
! CREATE STATISTICS stts (dependencies)
                 ON (zip, city) FROM zipcodes;
  ANALYZE zipcodes;
  SELECT stxname, stxkeys, stxdependencies
***************
*** 1219,1225 **** 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:
  <programlisting>
! CREATE STATISTICS stts2 WITH (ndistinct)
                 ON (zip, state, city) FROM zipcodes;
  ANALYZE zipcodes;
  SELECT stxkeys AS k, stxndistinct AS nd
--- 1219,1225 ----
       Continuing the above example, the n-distinct coefficients in a ZIP
       code table may look like the following:
  <programlisting>
! CREATE STATISTICS stts2 (ndistinct)
                 ON (zip, state, city) FROM zipcodes;
  ANALYZE zipcodes;
  SELECT stxkeys AS k, stxndistinct AS nd
*** a/doc/src/sgml/planstats.sgml
--- b/doc/src/sgml/planstats.sgml
***************
*** 526,532 **** EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
      multivariate statistics on the two columns:
  
  <programlisting>
! CREATE STATISTICS stts WITH (dependencies) ON (a, b) FROM t;
  ANALYZE t;
  EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
                                    QUERY PLAN                                   
--- 526,532 ----
      multivariate statistics on the two columns:
  
  <programlisting>
! CREATE STATISTICS stts (dependencies) ON (a, b) FROM t;
  ANALYZE t;
  EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
                                    QUERY PLAN                                   
***************
*** 569,575 **** EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
      calculation, the estimate is much improved:
  <programlisting>
  DROP STATISTICS stts;
! CREATE STATISTICS stts WITH (dependencies, ndistinct) ON (a, b) FROM t;
  ANALYZE t;
  EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
                                         QUERY PLAN                                        
--- 569,575 ----
      calculation, the estimate is much improved:
  <programlisting>
  DROP STATISTICS stts;
! CREATE STATISTICS stts (dependencies, ndistinct) ON (a, b) FROM t;
  ANALYZE t;
  EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
                                         QUERY PLAN                                        
*** a/doc/src/sgml/ref/create_statistics.sgml
--- b/doc/src/sgml/ref/create_statistics.sgml
***************
*** 22,28 **** PostgreSQL documentation
   <refsynopsisdiv>
  <synopsis>
  CREATE STATISTICS [ IF NOT EXISTS ] <replaceable class="PARAMETER">statistics_name</replaceable>
!     WITH ( <replaceable class="PARAMETER">option</replaceable> [= <replaceable class="PARAMETER">value</replaceable>] [, ... ] )
      ON ( <replaceable class="PARAMETER">column_name</replaceable>, <replaceable class="PARAMETER">column_name</replaceable> [, ...])
      FROM <replaceable class="PARAMETER">table_name</replaceable>
  </synopsis>
--- 22,28 ----
   <refsynopsisdiv>
  <synopsis>
  CREATE STATISTICS [ IF NOT EXISTS ] <replaceable class="PARAMETER">statistics_name</replaceable>
!     [ ( <replaceable class="PARAMETER">statistic_type</replaceable> [, ... ] ) ]
      ON ( <replaceable class="PARAMETER">column_name</replaceable>, <replaceable class="PARAMETER">column_name</replaceable> [, ...])
      FROM <replaceable class="PARAMETER">table_name</replaceable>
  </synopsis>
***************
*** 75,80 **** CREATE STATISTICS [ IF NOT EXISTS ] <replaceable class="PARAMETER">statistics_na
--- 75,93 ----
     </varlistentry>
  
     <varlistentry>
+     <term><replaceable class="PARAMETER">statistic_type</replaceable></term>
+     <listitem>
+      <para>
+       A statistic type to be enabled for this statistics.  Currently
+       supported types are <literal>ndistinct</literal>, which enables
+       n-distinct coefficient tracking,
+       and <literal>dependencies</literal>, which enables functional
+       dependencies.
+      </para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
      <term><replaceable class="PARAMETER">column_name</replaceable></term>
      <listitem>
       <para>
***************
*** 94,135 **** CREATE STATISTICS [ IF NOT EXISTS ] <replaceable class="PARAMETER">statistics_na
     </varlistentry>
  
    </variablelist>
- 
-   <refsect2 id="SQL-CREATESTATISTICS-parameters">
-    <title id="SQL-CREATESTATISTICS-parameters-title">Parameters</title>
- 
-  <indexterm zone="sql-createstatistics-parameters">
-   <primary>statistics parameters</primary>
-  </indexterm>
- 
-    <para>
-     The <literal>WITH</> clause can specify <firstterm>options</>
-     for the statistics. Available options are listed below.
-    </para>
- 
-    <variablelist>
- 
-    <varlistentry>
-     <term><literal>dependencies</> (<type>boolean</>)</term>
-     <listitem>
-      <para>
-       Enables functional dependencies for the statistics.
-      </para>
-     </listitem>
-    </varlistentry>
- 
-    <varlistentry>
-     <term><literal>ndistinct</> (<type>boolean</>)</term>
-     <listitem>
-      <para>
-       Enables ndistinct coefficients for the statistics.
-      </para>
-     </listitem>
-    </varlistentry>
- 
-    </variablelist>
- 
-   </refsect2>
   </refsect1>
  
   <refsect1>
--- 107,112 ----
*** a/src/backend/commands/statscmds.c
--- b/src/backend/commands/statscmds.c
***************
*** 199,223 **** CreateStatistics(CreateStatsStmt *stmt)
  	 */
  	build_ndistinct = false;
  	build_dependencies = false;
! 	foreach(l, stmt->options)
  	{
! 		DefElem    *opt = (DefElem *) lfirst(l);
  
! 		if (strcmp(opt->defname, "ndistinct") == 0)
  		{
! 			build_ndistinct = defGetBoolean(opt);
  			requested_type = true;
  		}
! 		else if (strcmp(opt->defname, "dependencies") == 0)
  		{
! 			build_dependencies = defGetBoolean(opt);
  			requested_type = true;
  		}
  		else
  			ereport(ERROR,
  					(errcode(ERRCODE_SYNTAX_ERROR),
! 					 errmsg("unrecognized STATISTICS option \"%s\"",
! 							opt->defname)));
  	}
  	/* If no statistic type was specified, build them all. */
  	if (!requested_type)
--- 199,223 ----
  	 */
  	build_ndistinct = false;
  	build_dependencies = false;
! 	foreach(l, stmt->stat_types)
  	{
! 		char    *type = strVal((Value *) lfirst(l));
  
! 		if (strcmp(type, "ndistinct") == 0)
  		{
! 			build_ndistinct = true;
  			requested_type = true;
  		}
! 		else if (strcmp(type, "dependencies") == 0)
  		{
! 			build_dependencies = true;
  			requested_type = true;
  		}
  		else
  			ereport(ERROR,
  					(errcode(ERRCODE_SYNTAX_ERROR),
! 					 errmsg("unrecognized statistics type \"%s\"",
! 							type)));
  	}
  	/* If no statistic type was specified, build them all. */
  	if (!requested_type)
*** a/src/backend/nodes/copyfuncs.c
--- b/src/backend/nodes/copyfuncs.c
***************
*** 3397,3402 **** _copyCreateStatsStmt(const CreateStatsStmt *from)
--- 3397,3413 ----
  	return newnode;
  }
  
+ static CreateStatsArgument *
+ _copyCreateStatsArgument(const CreateStatsArgument *from)
+ {
+ 	CreateStatsArgument *newnode = makeNode(CreateStatsArgument);
+ 
+ 	COPY_SCALAR_FIELD(subtype);
+ 	COPY_NODE_FIELD(elements);
+ 
+ 	return newnode;
+ }
+ 
  static CreateFunctionStmt *
  _copyCreateFunctionStmt(const CreateFunctionStmt *from)
  {
***************
*** 5121,5126 **** copyObjectImpl(const void *from)
--- 5132,5140 ----
  		case T_CreateStatsStmt:
  			retval = _copyCreateStatsStmt(from);
  			break;
+ 		case T_CreateStatsArgument:
+ 			retval = _copyCreateStatsArgument(from);
+ 			break;
  		case T_CreateFunctionStmt:
  			retval = _copyCreateFunctionStmt(from);
  			break;
*** a/src/backend/nodes/equalfuncs.c
--- b/src/backend/nodes/equalfuncs.c
***************
*** 1358,1363 **** _equalCreateStatsStmt(const CreateStatsStmt *a, const CreateStatsStmt *b)
--- 1358,1372 ----
  }
  
  static bool
+ _equalCreateStatsArgument(const CreateStatsArgument *a, const CreateStatsArgument *b)
+ {
+ 	COMPARE_SCALAR_FIELD(subtype);
+ 	COMPARE_NODE_FIELD(elements);
+ 
+ 	return true;
+ }
+ 
+ static bool
  _equalCreateFunctionStmt(const CreateFunctionStmt *a, const CreateFunctionStmt *b)
  {
  	COMPARE_SCALAR_FIELD(replace);
***************
*** 3270,3275 **** equal(const void *a, const void *b)
--- 3279,3287 ----
  		case T_CreateStatsStmt:
  			retval = _equalCreateStatsStmt(a, b);
  			break;
+ 		case T_CreateStatsArgument:
+ 			retval = _equalCreateStatsArgument(a, b);
+ 			break;
  		case T_CreateFunctionStmt:
  			retval = _equalCreateFunctionStmt(a, b);
  			break;
*** a/src/backend/nodes/outfuncs.c
--- b/src/backend/nodes/outfuncs.c
***************
*** 2646,2651 **** _outCreateStatsStmt(StringInfo str, const CreateStatsStmt *node)
--- 2646,2660 ----
  }
  
  static void
+ _outCreateStatsArgument(StringInfo str, const CreateStatsArgument *node)
+ {
+ 	WRITE_NODE_TYPE("CREATESTATSARG");
+ 
+ 	WRITE_INT_FIELD(subtype);
+ 	WRITE_NODE_FIELD(elements);
+ }
+ 
+ static void
  _outNotifyStmt(StringInfo str, const NotifyStmt *node)
  {
  	WRITE_NODE_TYPE("NOTIFY");
***************
*** 4051,4056 **** outNode(StringInfo str, const void *obj)
--- 4060,4068 ----
  			case T_CreateStatsStmt:
  				_outCreateStatsStmt(str, obj);
  				break;
+ 			case T_CreateStatsArgument:
+ 				_outCreateStatsArgument(str, obj);
+ 				break;
  			case T_NotifyStmt:
  				_outNotifyStmt(str, obj);
  				break;
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 183,188 **** static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_
--- 183,189 ----
  static void SplitColQualList(List *qualList,
  							 List **constraintList, CollateClause **collClause,
  							 core_yyscan_t yyscanner);
+ static void SplitStatsArgList(CreateStatsStmt *stmt, List *arguments);
  static void processCASbits(int cas_bits, int location, const char *constrType,
  			   bool *deferrable, bool *initdeferred, bool *not_valid,
  			   bool *no_inherit, core_yyscan_t yyscanner);
***************
*** 236,241 **** static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
--- 237,243 ----
  	AccessPriv			*accesspriv;
  	struct ImportQual	*importqual;
  	InsertStmt			*istmt;
+ 	CreateStatsArgument *cstatarg;
  	VariableSetStmt		*vsetstmt;
  	PartitionElem		*partelem;
  	PartitionSpec		*partspec;
***************
*** 397,402 **** static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
--- 399,406 ----
  				transform_element_list transform_type_list
  				TriggerTransitions TriggerReferencing
  				publication_name_list
+ 				opt_stats_type_list stats_type_list StatisticArgList
+ %type <cstatarg> StatisticArgument
  
  %type <list>	group_by_list
  %type <node>	group_by_item empty_grouping_set rollup_clause cube_clause
***************
*** 3828,3860 **** ExistingIndex:   USING INDEX index_name				{ $$ = $3; }
  /*****************************************************************************
   *
   *		QUERY :
!  *				CREATE STATISTICS stats_name WITH (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;
! 						}
  			;
  
  /*****************************************************************************
   *
   *		QUERY :
--- 3832,3905 ----
  /*****************************************************************************
   *
   *		QUERY :
!  *				CREATE STATISTICS stats_name [(stat types)] arguments
! 
!  *			where 'arguments' can be one or more of:
!  *					{ ON (columns)
!  *					  | FROM relations
!  *					  | WITH (options)
!  *					  | WHERE expression }
   *
   *****************************************************************************/
  
+ CreateStatsStmt:
+ 			CREATE opt_if_not_exists STATISTICS any_name
+ 			opt_stats_type_list StatisticArgList
+ 				{
+ 					CreateStatsStmt *n = makeNode(CreateStatsStmt);
+ 					n->defnames = $4;
+ 					n->stat_types = $5;
+ 					n->if_not_exists = $2;
  
! 					SplitStatsArgList(n, $6);
! 					$$ = (Node *)n;
! 				}
  			;
  
+ opt_stats_type_list:
+ 			'(' stats_type_list ')'			{ $$ = $2; }
+ 			| /* EMPTY */					{ $$ = NULL; }
+ 		;
+ 
+ stats_type_list:
+ 			ColId							{ $$ = list_make1(makeString($1)); }
+ 			| stats_type_list ',' ColId		{ $$ = lappend($1, makeString($3)); }
+ 		;
+ 
+ StatisticArgList:
+ 			StatisticArgument 						{ $$ = list_make1($1); }
+ 			| StatisticArgList StatisticArgument	{ $$ = lappend($1, $2); }
+ 		;
+ 
+ StatisticArgument:
+ 			ON '(' name_list ')'
+ 				{
+ 					CreateStatsArgument *n = makeNode(CreateStatsArgument);
+ 					n->subtype = CSA_Expressions;
+ 					n->elements = $3;
+ 					$$ = n;
+ 				}
+ 			| FROM qualified_name_list
+ 				{
+ 					CreateStatsArgument *n = makeNode(CreateStatsArgument);
+ 					n->subtype = CSA_Relations;
+ 					n->elements = $2;
+ 					$$ = n;
+ 				}
+ 			| WITH reloptions
+ 				{
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 							 errmsg("WITH clause is not yet implemented")));
+ 				}
+ 			| WHERE a_expr
+ 				{
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 							 errmsg("WHERE clause is not yet implemented")));
+ 				}
+ 		;
+ 
  /*****************************************************************************
   *
   *		QUERY :
***************
*** 15872,15877 **** processCASbits(int cas_bits, int location, const char *constrType,
--- 15917,15969 ----
  	}
  }
  
+ /*
+  * Split out CREATE STATISTICS arguments.
+  */
+ static void
+ SplitStatsArgList(CreateStatsStmt *stmt, List *arguments)
+ {
+ 	ListCell   *cell;
+ 
+ 	foreach(cell, arguments)
+ 	{
+ 		CreateStatsArgument *n = lfirst_node(CreateStatsArgument, cell);
+ 
+ 		switch (n->subtype)
+ 		{
+ 			case CSA_Relations:
+ 				if (stmt->relation)
+ 					ereport(ERROR,
+ 						(errcode(ERRCODE_DUPLICATE_OBJECT),
+ 						 errmsg("redundant or conflicting FROM clauses")));
+ 				if (list_length(n->elements) > 1)
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 							 errmsg("statistics across multiple relations are not supported yet")));
+ 				stmt->relation = linitial_node(RangeVar, n->elements);
+ 				break;
+ 			case CSA_Expressions:
+ 				if (stmt->keys)
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_DUPLICATE_OBJECT),
+ 							 errmsg("redundant or conflicting ON clauses")));
+ 				stmt->keys = n->elements;
+ 				break;
+ 			default:
+ 				elog(ERROR, "unsupported node type %d", n->subtype);
+ 		}
+ 	}
+ 
+ 	if (!stmt->relation)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ 				 errmsg("missing FROM clause")));
+ 	if (!stmt->keys)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ 				 errmsg("missing ON clause")));
+ }
+ 
  /*----------
   * Recursive view transformation
   *
*** a/src/backend/utils/adt/ruleutils.c
--- b/src/backend/utils/adt/ruleutils.c
***************
*** 1504,1518 **** 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
  	 * 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 (");
  		if (ndistinct_enabled)
  			appendStringInfoString(&buf, "ndistinct");
  		else if (dependencies_enabled)
--- 1504,1518 ----
  	}
  
  	/*
! 	 * If any option is disabled, then we'll need to append the types clause
! 	 * to show which options are enabled.  We omit the WITH 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, " (");
  		if (ndistinct_enabled)
  			appendStringInfoString(&buf, "ndistinct");
  		else if (dependencies_enabled)
*** a/src/bin/pg_dump/t/002_pg_dump.pl
--- b/src/bin/pg_dump/t/002_pg_dump.pl
***************
*** 4958,4967 **** qr/CREATE TRANSFORM FOR integer LANGUAGE sql \(FROM SQL WITH FUNCTION pg_catalog
  		all_runs     => 1,
  		catch_all    => 'CREATE ... commands',
  		create_order => 97,
! 		create_sql   => 'CREATE STATISTICS dump_test.test_ext_stats_using
! 							WITH (ndistinct) ON (col1, col2) FROM dump_test.test_fifth_table',
  		regexp => qr/^
! 			\QCREATE STATISTICS dump_test.test_ext_stats_using WITH (ndistinct) ON (col1, col2) FROM test_fifth_table;\E
  		    /xms,
  		like => {
  			binary_upgrade          => 1,
--- 4958,4967 ----
  		all_runs     => 1,
  		catch_all    => 'CREATE ... commands',
  		create_order => 97,
! 		create_sql   => 'CREATE STATISTICS dump_test.test_ext_stats_opts
! 							(ndistinct) ON (col1, col2) FROM dump_test.test_fifth_table',
  		regexp => qr/^
! 			\QCREATE STATISTICS dump_test.test_ext_stats_opts (ndistinct) ON (col1, col2) FROM test_fifth_table;\E
  		    /xms,
  		like => {
  			binary_upgrade          => 1,
*** a/src/bin/psql/describe.c
--- b/src/bin/psql/describe.c
***************
*** 2385,2391 **** describeOneTableDetails(const char *schemaname,
  					printfPQExpBuffer(&buf, "    ");
  
  					/* statistics name (qualified with namespace) */
! 					appendPQExpBuffer(&buf, "\"%s.%s\" WITH (",
  									  PQgetvalue(result, i, 1),
  									  PQgetvalue(result, i, 2));
  
--- 2385,2391 ----
  					printfPQExpBuffer(&buf, "    ");
  
  					/* statistics name (qualified with namespace) */
! 					appendPQExpBuffer(&buf, "\"%s.%s\" (",
  									  PQgetvalue(result, i, 1),
  									  PQgetvalue(result, i, 2));
  
*** a/src/include/nodes/nodes.h
--- b/src/include/nodes/nodes.h
***************
*** 462,467 **** typedef enum NodeTag
--- 462,468 ----
  	T_InferClause,
  	T_OnConflictClause,
  	T_CommonTableExpr,
+ 	T_CreateStatsArgument,
  	T_RoleSpec,
  	T_TriggerTransition,
  	T_PartitionElem,
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
***************
*** 2689,2700 **** typedef struct CreateStatsStmt
--- 2689,2714 ----
  {
  	NodeTag		type;
  	List	   *defnames;		/* qualified name (list of Value strings) */
+ 	List	   *stat_types;		/* stat types (list of Value strings) */
  	RangeVar   *relation;		/* relation to build statistics on */
  	List	   *keys;			/* String nodes naming referenced columns */
  	List	   *options;		/* list of DefElem */
  	bool		if_not_exists;	/* do nothing if statistics already exists */
  } CreateStatsStmt;
  
+ typedef enum CSA_Type
+ {
+ 	CSA_Relations,
+ 	CSA_Expressions
+ } CSA_Type;
+ 
+ typedef struct CreateStatsArgument
+ {
+ 	NodeTag		type;
+ 	CSA_Type	subtype;
+ 	List	   *elements;			/* elements (list of Node) */
+ } CreateStatsArgument;
+ 
  /* ----------------------
   *		Create Function Statement
   * ----------------------
*** a/src/test/regress/expected/stats_ext.out
--- b/src/test/regress/expected/stats_ext.out
***************
*** 5,10 ****
--- 5,35 ----
  SET max_parallel_workers = 0;
  SET max_parallel_workers_per_gather = 0;
  SET work_mem = '128kB';
+ -- Verify failures
+ CREATE STATISTICS tst;
+ ERROR:  syntax error at or near ";"
+ LINE 1: CREATE STATISTICS tst;
+                              ^
+ CREATE STATISTICS tst ON (a, b);
+ ERROR:  missing FROM clause
+ CREATE STATISTICS tst ON (a + b);
+ ERROR:  syntax error at or near "+"
+ LINE 1: CREATE STATISTICS tst ON (a + b);
+                                     ^
+ CREATE STATISTICS tst FROM sometab;
+ ERROR:  missing ON clause
+ CREATE STATISTICS tst FROM sometab, othertab;
+ ERROR:  statistics across multiple relations are not supported yet
+ CREATE STATISTICS tst WITH (fillfactor = 80);
+ ERROR:  WITH clause is not yet implemented
+ CREATE STATISTICS tst WHERE mars > earth;
+ ERROR:  WHERE clause is not yet implemented
+ CREATE STATISTICS tst ON (a, b) FROM nonexistant;
+ ERROR:  relation "nonexistant" does not exist
+ CREATE STATISTICS tst ON (a, b) FROM pg_class;
+ ERROR:  column "a" referenced in statistics does not exist
+ CREATE STATISTICS tst (unrecognized) ON (relname, relnatts) FROM pg_class;
+ ERROR:  unrecognized statistics type "unrecognized"
  -- Ensure stats are dropped sanely
  CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);
  CREATE STATISTICS ab1_a_b_stats ON (a, b) FROM ab1;
***************
*** 31,37 **** ALTER TABLE ab1 DROP COLUMN a;
   b      | integer |           |          | 
   c      | integer |           |          | 
  Statistics:
!     "public.ab1_b_c_stats" WITH (ndistinct, dependencies) ON (b, c)
  
  DROP TABLE ab1;
  -- Ensure things work sanely with SET STATISTICS 0
--- 56,62 ----
   b      | integer |           |          | 
   c      | integer |           |          | 
  Statistics:
!     "public.ab1_b_c_stats" (ndistinct, dependencies) ON (b, c)
  
  DROP TABLE ab1;
  -- Ensure things work sanely with SET STATISTICS 0
***************
*** 389,395 **** EXPLAIN (COSTS OFF)
  (2 rows)
  
  -- create statistics
! CREATE STATISTICS func_deps_stat WITH (dependencies) ON (a, b, c) FROM functional_dependencies;
  ANALYZE functional_dependencies;
  EXPLAIN (COSTS OFF)
   SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1';
--- 414,420 ----
  (2 rows)
  
  -- create statistics
! CREATE STATISTICS func_deps_stat (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,438 **** EXPLAIN (COSTS OFF)
  (2 rows)
  
  -- create statistics
! CREATE STATISTICS func_deps_stat WITH (dependencies) ON (a, b, c) FROM functional_dependencies;
  ANALYZE functional_dependencies;
  EXPLAIN (COSTS OFF)
   SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1';
--- 457,463 ----
  (2 rows)
  
  -- create statistics
! CREATE STATISTICS func_deps_stat (dependencies) ON (a, b, c) FROM functional_dependencies;
  ANALYZE functional_dependencies;
  EXPLAIN (COSTS OFF)
   SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1';
*** a/src/test/regress/sql/stats_ext.sql
--- b/src/test/regress/sql/stats_ext.sql
***************
*** 7,12 **** SET max_parallel_workers = 0;
--- 7,24 ----
  SET max_parallel_workers_per_gather = 0;
  SET work_mem = '128kB';
  
+ -- Verify failures
+ CREATE STATISTICS tst;
+ CREATE STATISTICS tst ON (a, b);
+ CREATE STATISTICS tst ON (a + b);
+ CREATE STATISTICS tst FROM sometab;
+ CREATE STATISTICS tst FROM sometab, othertab;
+ CREATE STATISTICS tst WITH (fillfactor = 80);
+ CREATE STATISTICS tst WHERE mars > earth;
+ CREATE STATISTICS tst ON (a, b) FROM nonexistant;
+ CREATE STATISTICS tst ON (a, b) FROM pg_class;
+ CREATE STATISTICS tst (unrecognized) ON (relname, relnatts) FROM pg_class;
+ 
  -- Ensure stats are dropped sanely
  CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);
  CREATE STATISTICS ab1_a_b_stats ON (a, b) FROM ab1;
***************
*** 233,239 **** 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;
  
  ANALYZE functional_dependencies;
  
--- 245,251 ----
   SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1;
  
  -- create statistics
! CREATE STATISTICS func_deps_stat (dependencies) ON (a, b, c) FROM functional_dependencies;
  
  ANALYZE functional_dependencies;
  
***************
*** 259,265 **** 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;
  
  ANALYZE functional_dependencies;
  
--- 271,277 ----
   SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1;
  
  -- create statistics
! CREATE STATISTICS func_deps_stat (dependencies) ON (a, b, c) FROM functional_dependencies;
  
  ANALYZE functional_dependencies;
  
