diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 426c1e6710..0c9591415e 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -420,20 +420,34 @@ do_analyze_rel(Relation onerel, VacuumParams *params, /* * Open all indexes of the relation, and see if there are any analyzable * columns in the indexes. We do not analyze index columns if there was - * an explicit column list in the ANALYZE command, however. If we are - * doing a recursive scan, we don't want to touch the parent's indexes at - * all. + * an explicit column list in the ANALYZE command, however. + * + * If we are doing a recursive scan, we don't want to touch the parent's + * indexes at all. If we're processing a partitioned table, we need to + * know if there are any indexes, but we don't want to process them. */ - if (!inh) + if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + List *idxs = RelationGetIndexList(onerel); + + Irel = NULL; + nindexes = 0; + hasindex = idxs != NIL; + list_free(idxs); + } + else if (!inh) + { vac_open_indexes(onerel, AccessShareLock, &nindexes, &Irel); + hasindex = nindexes > 0; + } else { Irel = NULL; nindexes = 0; + hasindex = false; } - hasindex = (nindexes > 0); indexdata = NULL; - if (hasindex) + if (nindexes > 0) { indexdata = (AnlIndexData *) palloc0(nindexes * sizeof(AnlIndexData)); for (ind = 0; ind < nindexes; ind++) @@ -572,7 +586,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params, MemoryContextResetAndDeleteChildren(col_context); } - if (hasindex) + if (nindexes > 0) compute_index_stats(onerel, totalrows, indexdata, nindexes, rows, numrows, @@ -660,10 +674,10 @@ do_analyze_rel(Relation onerel, VacuumParams *params, /* * Partitioned tables don't have storage, so we don't set any fields * in their pg_class entries except for reltuples, which is necessary - * for auto-analyze to work properly. + * for auto-analyze to work properly, and relhasindex. */ vac_update_relstats(onerel, -1, totalrows, - 0, false, InvalidTransactionId, + 0, hasindex, InvalidTransactionId, InvalidMultiXactId, in_outer_xact); } diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index e5771462d5..3e70e4c788 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -199,6 +199,28 @@ VACUUM ANALYZE vacparted(a,b,a); ERROR: column "a" of relation "vacparted" appears more than once ANALYZE vacparted(a,b,b); ERROR: column "b" of relation "vacparted" appears more than once +-- partitioned table with index +CREATE TABLE vacparted_i (a int primary key, b varchar(100)) + PARTITION BY HASH (a); +CREATE TABLE vacparted_i1 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE vacparted_i2 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO vacparted_i SELECT i, 'test_'|| i from generate_series(1,10) i; +VACUUM (ANALYZE) vacparted_i; +VACUUM (FULL) vacparted_i; +VACUUM (FREEZE) vacparted_i; +SELECT relname, relhasindex FROM pg_class + WHERE relname LIKE 'vacparted_i%' AND relkind IN ('p','r') + ORDER BY relname; + relname | relhasindex +--------------+------------- + vacparted_i | t + vacparted_i1 | t + vacparted_i2 | t +(3 rows) + +DROP TABLE vacparted_i; -- multiple tables specified VACUUM vaccluster, vactst; VACUUM vacparted, does_not_exist; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index f220fc28a7..18cb7fd08a 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -170,6 +170,22 @@ VACUUM (FREEZE) vacparted; VACUUM ANALYZE vacparted(a,b,a); ANALYZE vacparted(a,b,b); +-- partitioned table with index +CREATE TABLE vacparted_i (a int primary key, b varchar(100)) + PARTITION BY HASH (a); +CREATE TABLE vacparted_i1 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE vacparted_i2 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO vacparted_i SELECT i, 'test_'|| i from generate_series(1,10) i; +VACUUM (ANALYZE) vacparted_i; +VACUUM (FULL) vacparted_i; +VACUUM (FREEZE) vacparted_i; +SELECT relname, relhasindex FROM pg_class + WHERE relname LIKE 'vacparted_i%' AND relkind IN ('p','r') + ORDER BY relname; +DROP TABLE vacparted_i; + -- multiple tables specified VACUUM vaccluster, vactst; VACUUM vacparted, does_not_exist;