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