diff --git a/src/backend/distributed/deparser/deparse_statistics_stmts.c b/src/backend/distributed/deparser/deparse_statistics_stmts.c index 4da69a041..049b0d5a3 100644 --- a/src/backend/distributed/deparser/deparse_statistics_stmts.c +++ b/src/backend/distributed/deparser/deparse_statistics_stmts.c @@ -12,6 +12,8 @@ */ #include "postgres.h" +#include "distributed/pg_version_constants.h" + #include "distributed/citus_ruleutils.h" #include "distributed/deparser.h" #include "distributed/listutils.h" @@ -231,7 +233,25 @@ AppendStatTypes(StringInfo buf, CreateStatsStmt *stmt) appendStringInfoString(buf, ")"); } +#if PG_VERSION_NUM >= PG_VERSION_14 +static void +AppendColumnNames(StringInfo buf, CreateStatsStmt *stmt) +{ + StatsElem *column = NULL; + foreach_ptr(column, stmt->exprs) + { + char *columnName = NameListToQuotedString(list_make1(makeString(column->name))); + + appendStringInfoString(buf, columnName); + + if (column != llast(stmt->exprs)) + { + appendStringInfoString(buf, ", "); + } + } +} +#else static void AppendColumnNames(StringInfo buf, CreateStatsStmt *stmt) { @@ -257,7 +277,7 @@ AppendColumnNames(StringInfo buf, CreateStatsStmt *stmt) } } } - +#endif static void AppendTableName(StringInfo buf, CreateStatsStmt *stmt) diff --git a/src/test/regress/expected/propagate_statistics.out b/src/test/regress/expected/propagate_statistics.out index 1c798c526..e29ca7fce 100644 --- a/src/test/regress/expected/propagate_statistics.out +++ b/src/test/regress/expected/propagate_statistics.out @@ -100,11 +100,12 @@ SELECT create_distributed_table('test','x'); (1 row) CREATE STATISTICS stats_xy ON (x, y) FROM test; -ERROR: only simple column references are allowed in CREATE STATISTICS +ERROR: syntax error at or near "," CREATE STATISTICS stats_xy ON x+y FROM test; -ERROR: only simple column references are allowed in CREATE STATISTICS +ERROR: syntax error at or near "+" CREATE STATISTICS stats_xy ON x,y FROM test; CREATE STATISTICS IF NOT EXISTS stats_xy ON x+y FROM test; +ERROR: syntax error at or near "+" \c - - - :worker_1_port SELECT stxname FROM pg_statistic_ext diff --git a/src/test/regress/expected/propagate_statistics_0.out b/src/test/regress/expected/propagate_statistics_0.out new file mode 100644 index 000000000..1c798c526 --- /dev/null +++ b/src/test/regress/expected/propagate_statistics_0.out @@ -0,0 +1,246 @@ +CREATE SCHEMA "statistics'Test"; +SET search_path TO "statistics'Test"; +SET citus.next_shard_id TO 980000; +SET client_min_messages TO WARNING; +SET citus.shard_count TO 32; +SET citus.shard_replication_factor TO 1; +-- test create statistics propagation +CREATE TABLE test_stats ( + a int, + b int +); +SELECT create_distributed_table('test_stats', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE STATISTICS s1 (dependencies) ON a, b FROM test_stats; +-- test for distributing an already existing statistics +CREATE TABLE "test'stats2" ( + a int, + b int +); +CREATE STATISTICS s2 (dependencies) ON a, b FROM "test'stats2"; +SELECT create_distributed_table('test''stats2', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- test when stats is on a different schema +CREATE SCHEMA sc1; +CREATE TABLE tbl (a int, "B" text); +SELECT create_distributed_table ('tbl', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE STATISTICS sc1.st1 ON a, "B" FROM tbl; +-- test distributing table with already created stats on a new schema +CREATE TABLE test_stats3 ( + a int, + b int +); +CREATE SCHEMA sc2; +CREATE STATISTICS sc2."neW'Stat" ON a,b FROM test_stats3; +SELECT create_distributed_table ('test_stats3','a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- test dropping statistics +CREATE TABLE test_stats4 ( + a int, + b int +); +SELECT create_reference_table ('test_stats4'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +CREATE STATISTICS s3 ON a,b FROM test_stats3; +CREATE STATISTICS sc2.s4 ON a,b FROM test_stats3; +CREATE STATISTICS s5 ON a,b FROM test_stats4; +-- s6 doesn't exist +DROP STATISTICS IF EXISTS s3, sc2.s4, s6; +DROP STATISTICS s5,s6; +ERROR: statistics object "statistics'Test.s6" does not exist +DROP STATISTICS IF EXISTS s5,s5,s6,s6; +-- test renaming statistics +CREATE STATISTICS s6 ON a,b FROM test_stats4; +DROP STATISTICS s7; +ERROR: statistics object "statistics'Test.s7" does not exist +ALTER STATISTICS s6 RENAME TO s7; +ALTER STATISTICS sc1.st1 RENAME TO st1_new; +-- test altering stats schema +CREATE SCHEMA test_alter_schema; +ALTER STATISTICS s7 SET SCHEMA test_alter_schema; +-- test alter owner +ALTER STATISTICS sc2."neW'Stat" OWNER TO pg_monitor; +-- test alter owner before distribution +CREATE TABLE ownertest(a int, b int); +CREATE STATISTICS sc1.s9 ON a,b FROM ownertest; +ALTER STATISTICS sc1.s9 OWNER TO pg_signal_backend; +SELECT create_distributed_table('ownertest','a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- test invalid column expressions +CREATE TABLE test (x int, y int); +SELECT create_distributed_table('test','x'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE STATISTICS stats_xy ON (x, y) FROM test; +ERROR: only simple column references are allowed in CREATE STATISTICS +CREATE STATISTICS stats_xy ON x+y FROM test; +ERROR: only simple column references are allowed in CREATE STATISTICS +CREATE STATISTICS stats_xy ON x,y FROM test; +CREATE STATISTICS IF NOT EXISTS stats_xy ON x+y FROM test; +\c - - - :worker_1_port +SELECT stxname +FROM pg_statistic_ext +WHERE stxnamespace IN ( + SELECT oid + FROM pg_namespace + WHERE nspname IN ('public', 'statistics''Test', 'sc1', 'sc2') +) +ORDER BY stxname ASC; + stxname +--------------------------------------------------------------------- + neW'Stat_980096 + neW'Stat_980098 + neW'Stat_980100 + neW'Stat_980102 + neW'Stat_980104 + neW'Stat_980106 + neW'Stat_980108 + neW'Stat_980110 + neW'Stat_980112 + neW'Stat_980114 + neW'Stat_980116 + neW'Stat_980118 + neW'Stat_980120 + neW'Stat_980122 + neW'Stat_980124 + neW'Stat_980126 + s1_980000 + s1_980002 + s1_980004 + s1_980006 + s1_980008 + s1_980010 + s1_980012 + s1_980014 + s1_980016 + s1_980018 + s1_980020 + s1_980022 + s1_980024 + s1_980026 + s1_980028 + s1_980030 + s2_980032 + s2_980034 + s2_980036 + s2_980038 + s2_980040 + s2_980042 + s2_980044 + s2_980046 + s2_980048 + s2_980050 + s2_980052 + s2_980054 + s2_980056 + s2_980058 + s2_980060 + s2_980062 + s9_980129 + s9_980131 + s9_980133 + s9_980135 + s9_980137 + s9_980139 + s9_980141 + s9_980143 + s9_980145 + s9_980147 + s9_980149 + s9_980151 + s9_980153 + s9_980155 + s9_980157 + s9_980159 + st1_new_980064 + st1_new_980066 + st1_new_980068 + st1_new_980070 + st1_new_980072 + st1_new_980074 + st1_new_980076 + st1_new_980078 + st1_new_980080 + st1_new_980082 + st1_new_980084 + st1_new_980086 + st1_new_980088 + st1_new_980090 + st1_new_980092 + st1_new_980094 + stats_xy_980161 + stats_xy_980163 + stats_xy_980165 + stats_xy_980167 + stats_xy_980169 + stats_xy_980171 + stats_xy_980173 + stats_xy_980175 + stats_xy_980177 + stats_xy_980179 + stats_xy_980181 + stats_xy_980183 + stats_xy_980185 + stats_xy_980187 + stats_xy_980189 + stats_xy_980191 +(96 rows) + +SELECT count(DISTINCT stxnamespace) +FROM pg_statistic_ext +WHERE stxnamespace IN ( + SELECT oid + FROM pg_namespace + WHERE nspname IN ('public', 'statistics''Test', 'sc1', 'sc2') +); + count +--------------------------------------------------------------------- + 3 +(1 row) + +SELECT COUNT(DISTINCT stxowner) +FROM pg_statistic_ext +WHERE stxnamespace IN ( + SELECT oid + FROM pg_namespace + WHERE nspname IN ('public', 'statistics''Test', 'sc1', 'sc2') +); + count +--------------------------------------------------------------------- + 3 +(1 row) + +\c - - - :master_port +SET client_min_messages TO WARNING; +DROP SCHEMA "statistics'Test" CASCADE; +DROP SCHEMA test_alter_schema CASCADE; +DROP SCHEMA sc1 CASCADE; +DROP SCHEMA sc2 CASCADE;