summaryrefslogtreecommitdiff
path: root/src/backend/commands/analyze.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-09-02 14:29:31 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-09-02 14:29:31 -0400
commit5b562644fec696977df4a82790064e8287927891 (patch)
tree3f8132a4e7e9fb9591c3e7f069035388918ae020 /src/backend/commands/analyze.c
parent2f72d5df6a876406cf5f2f8d7800d591dff3e2e3 (diff)
Teach ANALYZE to clear pg_class.relhassubclass when appropriate.
In the past, relhassubclass always remained true if a relation had ever had child relations, even if the last subclass was long gone. While this had only marginal performance implications in most cases, it was annoying, and I'm now considering some planner changes that would raise the cost of a false positive. It was previously impractical to fix this because of race condition concerns. However, given the recent change that made tablecmds.c take ShareExclusiveLock on relations that are gaining a child (commit fbcf4b92aa64d4577bcf25925b055316b978744a), we can now allow ANALYZE to clear the flag when it's no longer relevant. There is no additional locking cost to do so, since ANALYZE takes ShareExclusiveLock anyway.
Diffstat (limited to 'src/backend/commands/analyze.c')
-rw-r--r--src/backend/commands/analyze.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 1d6301bac16..a9ddb2c2807 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -26,6 +26,7 @@
#include "catalog/pg_inherits_fn.h"
#include "catalog/pg_namespace.h"
#include "commands/dbcommands.h"
+#include "commands/tablecmds.h"
#include "commands/vacuum.h"
#include "executor/executor.h"
#include "miscadmin.h"
@@ -1408,14 +1409,15 @@ acquire_inherited_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
/*
* 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.
+ * 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.)
*/
if (list_length(tableOIDs) < 2)
{
- /*
- * XXX It would be desirable to clear relhassubclass here, but we
- * don't have adequate lock to do that safely.
- */
+ /* CCI because we already updated the pg_class row in this command */
+ CommandCounterIncrement();
+ SetRelationHasSubclass(RelationGetRelid(onerel), false);
return 0;
}