Fix some errors in vacuum
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index cb43657..f2fff2c 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -748,6 +748,35 @@
}
}
+ {
+ List *tableOIDs;
+ /*
+ * Find all members of inheritance set. We only need AccessShareLock on
+ * the children.
+ */
+ tableOIDs =
+ find_all_inheritors(RelationGetRelid(onerel), AccessShareLock, NULL);
+
+ /*
+ * Check that there's at least one descendant, else fail. This could
+ * happen despite analyze_rel's relhassubclass check, if table once had a
+ * child but no longer does. In that case, we can clear the
+ * relhassubclass field so as not to make the same mistake again later.
+ * (This is safe because we hold ShareUpdateExclusiveLock.)
+ * Please refer to https://github.com/greenplum-db/gpdb/issues/14644
+ */
+ if (list_length(tableOIDs) < 2)
+ {
+ /* CCI because we already updated the pg_class row in this command */
+ CommandCounterIncrement();
+ SetRelationHasSubclass(RelationGetRelid(onerel), false);
+ ereport(elevel,
+ (errmsg("skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables",
+ get_namespace_name(RelationGetNamespace(onerel)),
+ RelationGetRelationName(onerel))));
+ }
+ }
+
sample_needed = needs_sample(onerel, vacattrstats, attr_cnt);
if (ctx || sample_needed)
{
@@ -1983,9 +2012,6 @@
*/
if (list_length(tableOIDs) < 2)
{
- /* CCI because we already updated the pg_class row in this command */
- CommandCounterIncrement();
- SetRelationHasSubclass(RelationGetRelid(onerel), false);
*totalrows = 0;
*totaldeadrows = 0;
ereport(elevel,
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 936aa9b..bcb850a 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -445,7 +445,8 @@
VACOPT_VERBOSE |
VACOPT_PROCESS_MAIN |
VACOPT_PROCESS_TOAST |
- VACOPT_ONLY_DATABASE_STATS))
+ VACOPT_ONLY_DATABASE_STATS |
+ VACOPT_UPDATE_DATFROZENXID))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("ONLY_DATABASE_STATS cannot be specified with other VACUUM options")));
@@ -3401,11 +3402,14 @@
options = lappend(options, makeDefElem("skip_locked", (Node *) makeInteger(1), -1));
optmask &= ~VACOPT_SKIP_LOCKED;
}
- if (optmask & VACOPT_PROCESS_MAIN)
+ if (!(optmask & VACOPT_PROCESS_MAIN))
{
- options = lappend(options, makeDefElem("process_main", (Node *) makeInteger(1), -1));
+ options = lappend(options, makeDefElem("process_main", (Node *) makeInteger(0), -1));
optmask &= ~VACOPT_PROCESS_MAIN;
}
+ else
+ optmask &= ~VACOPT_PROCESS_MAIN;
+
if (optmask & VACOPT_PROCESS_TOAST)
{
/* GPDB_14_MERGE_FIXME: skip_toast is replaced by process_toast, need to check */
@@ -3418,6 +3422,18 @@
optmask &= ~VACOPT_DISABLE_PAGE_SKIPPING;
}
+ if ((optmask & VACOPT_SKIP_DATABASE_STATS))
+ {
+ options = lappend(options, makeDefElem("skip_database_stats", (Node *) makeInteger(1), -1));
+ optmask &= ~VACOPT_SKIP_DATABASE_STATS;
+ }
+ if ((optmask & VACOPT_ONLY_DATABASE_STATS))
+ {
+ options = lappend(options, makeDefElem("only_database_stats", (Node *) makeInteger(1), -1));
+ optmask &= ~VACOPT_ONLY_DATABASE_STATS;
+ }
+
+
if (optmask & VACUUM_AO_PHASE_MASK)
{
options = lappend(options, makeDefElem("ao_phase",
diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out
index 7e5efcb..93bb198 100644
--- a/src/test/regress/expected/vacuum.out
+++ b/src/test/regress/expected/vacuum.out
@@ -344,19 +344,17 @@
ORDER BY rel;
VACUUM (PROCESS_TOAST TRUE) vac_option_tab;
SELECT * FROM vac_option_tab_counts;
- rel | vacuum_count
--------+--------------
- main | 1
- toast | 1
-(2 rows)
+ rel | vacuum_count
+------+--------------
+ main | 1
+(1 row)
VACUUM (PROCESS_TOAST FALSE) vac_option_tab;
SELECT * FROM vac_option_tab_counts;
- rel | vacuum_count
--------+--------------
- main | 2
- toast | 1
-(2 rows)
+ rel | vacuum_count
+------+--------------
+ main | 2
+(1 row)
VACUUM (PROCESS_TOAST FALSE, FULL) vac_option_tab; -- error
ERROR: PROCESS_TOAST required with VACUUM FULL
@@ -364,20 +362,18 @@
-- Only the toast table is processed.
VACUUM (PROCESS_MAIN FALSE) vac_option_tab;
SELECT * FROM vac_option_tab_counts;
- rel | vacuum_count
--------+--------------
- main | 2
- toast | 2
-(2 rows)
+ rel | vacuum_count
+------+--------------
+ main | 2
+(1 row)
-- Nothing is processed.
VACUUM (PROCESS_MAIN FALSE, PROCESS_TOAST FALSE) vac_option_tab;
SELECT * FROM vac_option_tab_counts;
- rel | vacuum_count
--------+--------------
- main | 2
- toast | 2
-(2 rows)
+ rel | vacuum_count
+------+--------------
+ main | 2
+(1 row)
-- Check if the filenodes nodes have been updated as wanted after FULL.
SELECT relfilenode AS main_filenode FROM pg_class