/*
* 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++)
MemoryContextResetAndDeleteChildren(col_context);
}
- if (hasindex)
+ if (nindexes > 0)
compute_index_stats(onerel, totalrows,
indexdata, nindexes,
rows, numrows,
/*
* 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);
}
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;
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;