diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 82d3658a50b..0acd79361bd 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,4 +1,4 @@
-
+
@@ -4506,19 +4506,32 @@
The catalog pg_statistic stores
statistical data about the contents of the database. Entries are
created by
- and subsequently used by the query planner. There is one entry for
- each table column that has been analyzed. Note that all the
+ and subsequently used by the query planner. Note that all the
statistical data is inherently approximate, even assuming that it
is up-to-date.
+
+ Normally there is one entry, with stainherit> =
+ false>, for each table column that has been analyzed.
+ If the table has inheritance children, a second entry with
+ stainherit> = true> is also created. This row
+ represents the column's statistics over the inheritance tree, i.e.,
+ statistics for the data you'd see with
+ SELECT column> FROM table>*,
+ whereas the stainherit> = false> row represents
+ the results of
+ SELECT column> FROM ONLY table>.
+
+
pg_statistic also stores statistical data about
the values of index expressions. These are described as if they were
actual data columns; in particular, starelid
references the index. No entry is made for an ordinary non-expression
index column, however, since it would be redundant with the entry
- for the underlying table column.
+ for the underlying table column. Currently, entries for index expressions
+ always have stainherit> = false>.
@@ -4572,6 +4585,14 @@
The number of the described column
+
+ stainherit
+ bool
+
+ If true, the stats include inheritance child columns, not just the
+ values in the specified relation
+
+
stanullfrac
float4
@@ -7114,6 +7135,14 @@
Name of the column described by this row
+
+ inherited
+ bool
+
+ If true, this row includes inheritance child columns, not just the
+ values in the specified table
+
+
null_frac
real
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 0f33c525b61..8ef00f9287b 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.362 2009/12/24 22:09:23 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.363 2009/12/29 20:11:43 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -2314,7 +2314,7 @@ cookConstraint(ParseState *pstate,
/*
* RemoveStatistics --- remove entries in pg_statistic for a rel or column
*
- * If attnum is zero, remove all entries for rel; else remove only the one
+ * If attnum is zero, remove all entries for rel; else remove only the one(s)
* for that column.
*/
void
@@ -2344,9 +2344,10 @@ RemoveStatistics(Oid relid, AttrNumber attnum)
nkeys = 2;
}
- scan = systable_beginscan(pgstatistic, StatisticRelidAttnumIndexId, true,
+ scan = systable_beginscan(pgstatistic, StatisticRelidAttnumInhIndexId, true,
SnapshotNow, nkeys, key);
+ /* we must loop even when attnum != 0, in case of inherited stats */
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
simple_heap_delete(pgstatistic, &tuple->t_self);
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 05608bdbee5..cb5ed390e3a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -3,7 +3,7 @@
*
* Copyright (c) 1996-2009, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.63 2009/11/29 18:14:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.64 2009/12/29 20:11:44 tgl Exp $
*/
CREATE VIEW pg_roles AS
@@ -109,6 +109,7 @@ CREATE VIEW pg_stats AS
nspname AS schemaname,
relname AS tablename,
attname AS attname,
+ stainherit AS inherited,
stanullfrac AS null_frac,
stawidth AS avg_width,
stadistinct AS n_distinct,
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 6d13eeb5ec1..0739db99f50 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.143 2009/12/09 21:57:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.144 2009/12/29 20:11:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,11 +18,13 @@
#include "access/heapam.h"
#include "access/transam.h"
+#include "access/tupconvert.h"
#include "access/tuptoaster.h"
#include "access/xact.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
+#include "catalog/pg_inherits_fn.h"
#include "catalog/pg_namespace.h"
#include "commands/dbcommands.h"
#include "commands/vacuum.h"
@@ -55,6 +57,7 @@ typedef struct
BlockNumber t; /* current block number */
int m; /* blocks selected so far */
} BlockSamplerData;
+
typedef BlockSamplerData *BlockSampler;
/* Per-index data for ANALYZE */
@@ -78,6 +81,8 @@ static MemoryContext anl_context = NULL;
static BufferAccessStrategy vac_strategy;
+static void do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
+ bool update_reltuples, bool inh);
static void BlockSampler_Init(BlockSampler bs, BlockNumber nblocks,
int samplesize);
static bool BlockSampler_HasMore(BlockSampler bs);
@@ -93,7 +98,11 @@ static double random_fract(void);
static double init_selection_state(int n);
static double get_next_S(double t, int n, double *stateptr);
static int compare_rows(const void *a, const void *b);
-static void update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats);
+static int acquire_inherited_sample_rows(Relation onerel,
+ HeapTuple *rows, int targrows,
+ double *totalrows, double *totaldeadrows);
+static void update_attstats(Oid relid, bool inh,
+ int natts, VacAttrStats **vacattrstats);
static Datum std_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull);
static Datum ind_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull);
@@ -116,27 +125,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
BufferAccessStrategy bstrategy, bool update_reltuples)
{
Relation onerel;
- int attr_cnt,
- tcnt,
- i,
- ind;
- Relation *Irel;
- int nindexes;
- bool hasindex;
- bool analyzableindex;
- VacAttrStats **vacattrstats;
- AnlIndexData *indexdata;
- int targrows,
- numrows;
- double totalrows,
- totaldeadrows;
- HeapTuple *rows;
- PGRUsage ru0;
- TimestampTz starttime = 0;
- Oid save_userid;
- int save_sec_context;
- int save_nestlevel;
+ /* Set up static variables */
if (vacstmt->options & VACOPT_VERBOSE)
elevel = INFO;
else
@@ -145,15 +135,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
vac_strategy = bstrategy;
/*
- * Use the current context for storing analysis info. vacuum.c ensures
- * that this context will be cleared when I return, thus releasing the
- * memory allocated here.
- */
- anl_context = CurrentMemoryContext;
-
- /*
- * Check for user-requested abort. Note we want this to be inside a
- * transaction, so xact.c doesn't issue useless WARNING.
+ * Check for user-requested abort.
*/
CHECK_FOR_INTERRUPTS();
@@ -230,10 +212,91 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
return;
}
- ereport(elevel,
- (errmsg("analyzing \"%s.%s\"",
- get_namespace_name(RelationGetNamespace(onerel)),
- RelationGetRelationName(onerel))));
+ /*
+ * OK, let's do it. First let other backends know I'm in ANALYZE.
+ */
+ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+ MyProc->vacuumFlags |= PROC_IN_ANALYZE;
+ LWLockRelease(ProcArrayLock);
+
+ /*
+ * Do the normal non-recursive ANALYZE.
+ */
+ do_analyze_rel(onerel, vacstmt, update_reltuples, false);
+
+ /*
+ * If there are child tables, do recursive ANALYZE.
+ */
+ if (onerel->rd_rel->relhassubclass)
+ do_analyze_rel(onerel, vacstmt, false, true);
+
+ /*
+ * Close source relation now, but keep lock so that no one deletes it
+ * before we commit. (If someone did, they'd fail to clean up the entries
+ * we made in pg_statistic. Also, releasing the lock before commit would
+ * expose us to concurrent-update failures in update_attstats.)
+ */
+ relation_close(onerel, NoLock);
+
+ /*
+ * Reset my PGPROC flag. Note: we need this here, and not in vacuum_rel,
+ * because the vacuum flag is cleared by the end-of-xact code.
+ */
+ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+ MyProc->vacuumFlags &= ~PROC_IN_ANALYZE;
+ LWLockRelease(ProcArrayLock);
+}
+
+/*
+ * do_analyze_rel() -- analyze one relation, recursively or not
+ */
+static void
+do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
+ bool update_reltuples, bool inh)
+{
+ int attr_cnt,
+ tcnt,
+ i,
+ ind;
+ Relation *Irel;
+ int nindexes;
+ bool hasindex;
+ bool analyzableindex;
+ VacAttrStats **vacattrstats;
+ AnlIndexData *indexdata;
+ int targrows,
+ numrows;
+ double totalrows,
+ totaldeadrows;
+ HeapTuple *rows;
+ PGRUsage ru0;
+ TimestampTz starttime = 0;
+ MemoryContext caller_context;
+ Oid save_userid;
+ int save_sec_context;
+ int save_nestlevel;
+
+ if (inh)
+ ereport(elevel,
+ (errmsg("analyzing \"%s.%s\" inheritance tree",
+ get_namespace_name(RelationGetNamespace(onerel)),
+ RelationGetRelationName(onerel))));
+ else
+ ereport(elevel,
+ (errmsg("analyzing \"%s.%s\"",
+ get_namespace_name(RelationGetNamespace(onerel)),
+ RelationGetRelationName(onerel))));
+
+ /*
+ * Set up a working context so that we can easily free whatever junk
+ * gets created.
+ */
+ anl_context = AllocSetContextCreate(CurrentMemoryContext,
+ "Analyze",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+ caller_context = MemoryContextSwitchTo(anl_context);
/*
* Switch to the table owner's userid, so that any index functions are run
@@ -245,11 +308,6 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
- /* let others know what I'm doing */
- LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
- MyProc->vacuumFlags |= PROC_IN_ANALYZE;
- LWLockRelease(ProcArrayLock);
-
/* measure elapsed time iff autovacuum logging requires it */
if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0)
{
@@ -304,9 +362,17 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
/*
* 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.
+ * 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.
*/
- vac_open_indexes(onerel, AccessShareLock, &nindexes, &Irel);
+ if (!inh)
+ vac_open_indexes(onerel, AccessShareLock, &nindexes, &Irel);
+ else
+ {
+ Irel = NULL;
+ nindexes = 0;
+ }
hasindex = (nindexes > 0);
indexdata = NULL;
analyzableindex = false;
@@ -399,8 +465,12 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
* Acquire the sample rows
*/
rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple));
- numrows = acquire_sample_rows(onerel, rows, targrows,
- &totalrows, &totaldeadrows);
+ if (inh)
+ numrows = acquire_inherited_sample_rows(onerel, rows, targrows,
+ &totalrows, &totaldeadrows);
+ else
+ numrows = acquire_sample_rows(onerel, rows, targrows,
+ &totalrows, &totaldeadrows);
/*
* Compute the statistics. Temporary results during the calculations for
@@ -452,13 +522,14 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
* previous statistics for the target columns. (If there are stats in
* pg_statistic for columns we didn't process, we leave them alone.)
*/
- update_attstats(relid, attr_cnt, vacattrstats);
+ update_attstats(RelationGetRelid(onerel), inh,
+ attr_cnt, vacattrstats);
for (ind = 0; ind < nindexes; ind++)
{
AnlIndexData *thisdata = &indexdata[ind];
- update_attstats(RelationGetRelid(Irel[ind]),
+ update_attstats(RelationGetRelid(Irel[ind]), false,
thisdata->attr_cnt, thisdata->vacattrstats);
}
}
@@ -537,27 +608,16 @@ cleanup:
pg_rusage_show(&ru0))));
}
- /*
- * Close source relation now, but keep lock so that no one deletes it
- * before we commit. (If someone did, they'd fail to clean up the entries
- * we made in pg_statistic. Also, releasing the lock before commit would
- * expose us to concurrent-update failures in update_attstats.)
- */
- relation_close(onerel, NoLock);
-
- /*
- * Reset my PGPROC flag. Note: we need this here, and not in vacuum_rel,
- * because the vacuum flag is cleared by the end-of-xact code.
- */
- LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
- MyProc->vacuumFlags &= ~PROC_IN_ANALYZE;
- LWLockRelease(ProcArrayLock);
-
/* Roll back any GUC changes executed by index functions */
AtEOXact_GUC(false, save_nestlevel);
/* Restore userid and security context */
SetUserIdAndSecContext(save_userid, save_sec_context);
+
+ /* Restore current context and release memory */
+ MemoryContextSwitchTo(caller_context);
+ MemoryContextDelete(anl_context);
+ anl_context = NULL;
}
/*
@@ -877,6 +937,15 @@ BlockSampler_Next(BlockSampler bs)
/*
* acquire_sample_rows -- acquire a random sample of rows from the table
*
+ * Selected rows are returned in the caller-allocated array rows[], which
+ * must have at least targrows entries.
+ * The actual number of rows selected is returned as the function result.
+ * We also estimate the total numbers of live and dead rows in the table,
+ * and return them into *totalrows and *totaldeadrows, respectively.
+ *
+ * The returned list of tuples is in order by physical position in the table.
+ * (We will rely on this later to derive correlation estimates.)
+ *
* As of May 2004 we use a new two-stage method: Stage one selects up
* to targrows random blocks (or all blocks, if there aren't so many).
* Stage two scans these blocks and uses the Vitter algorithm to create
@@ -892,17 +961,11 @@ BlockSampler_Next(BlockSampler bs)
* the number of different blocks represented by the sample tends to be
* too small. We can live with that for now. Improvements are welcome.
*
- * We also estimate the total numbers of live and dead rows in the table,
- * and return them into *totalrows and *totaldeadrows, respectively.
- *
* An important property of this sampling method is that because we do
* look at a statistically unbiased set of blocks, we should get
* unbiased estimates of the average numbers of live and dead rows per
* block. The previous sampling method put too much credence in the row
* density near the start of the table.
- *
- * The returned list of tuples is in order by physical position in the table.
- * (We will rely on this later to derive correlation estimates.)
*/
static int
acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
@@ -918,7 +981,7 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
BlockSamplerData bs;
double rstate;
- Assert(targrows > 1);
+ Assert(targrows > 0);
totalblocks = RelationGetNumberOfBlocks(onerel);
@@ -1276,6 +1339,155 @@ compare_rows(const void *a, const void *b)
}
+/*
+ * acquire_inherited_sample_rows -- acquire sample rows from inheritance tree
+ *
+ * This has the same API as acquire_sample_rows, except that rows are
+ * collected from all inheritance children as well as the specified table.
+ * We fail and return zero if there are no inheritance children.
+ */
+static int
+acquire_inherited_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
+ double *totalrows, double *totaldeadrows)
+{
+ List *tableOIDs;
+ Relation *rels;
+ double *relblocks;
+ double totalblocks;
+ int numrows,
+ nrels,
+ i;
+ ListCell *lc;
+
+ /*
+ * Find all members of inheritance set. We only need AccessShareLock on
+ * the children.
+ */
+ tableOIDs = find_all_inheritors(RelationGetRelid(onerel), AccessShareLock);
+
+ /*
+ * 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.
+ */
+ 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.
+ */
+ return 0;
+ }
+
+ /*
+ * Count the blocks in all the relations. The result could overflow
+ * BlockNumber, so we use double arithmetic.
+ */
+ rels = (Relation *) palloc(list_length(tableOIDs) * sizeof(Relation));
+ relblocks = (double *) palloc(list_length(tableOIDs) * sizeof(double));
+ totalblocks = 0;
+ nrels = 0;
+ foreach(lc, tableOIDs)
+ {
+ Oid childOID = lfirst_oid(lc);
+ Relation childrel;
+
+ /* We already got the needed lock */
+ childrel = heap_open(childOID, NoLock);
+
+ /* Ignore if temp table of another backend */
+ if (RELATION_IS_OTHER_TEMP(childrel))
+ {
+ /* ... but release the lock on it */
+ Assert(childrel != onerel);
+ heap_close(childrel, AccessShareLock);
+ continue;
+ }
+
+ rels[nrels] = childrel;
+ relblocks[nrels] = (double) RelationGetNumberOfBlocks(childrel);
+ totalblocks += relblocks[nrels];
+ nrels++;
+ }
+
+ /*
+ * Now sample rows from each relation, proportionally to its fraction
+ * of the total block count. (This might be less than desirable if the
+ * child rels have radically different free-space percentages, but it's
+ * not clear that it's worth working harder.)
+ */
+ numrows = 0;
+ *totalrows = 0;
+ *totaldeadrows = 0;
+ for (i = 0; i < nrels; i++)
+ {
+ Relation childrel = rels[i];
+ double childblocks = relblocks[i];
+
+ if (childblocks > 0)
+ {
+ int childtargrows;
+
+ childtargrows = (int) rint(targrows * childblocks / totalblocks);
+ /* Make sure we don't overrun due to roundoff error */
+ childtargrows = Min(childtargrows, targrows - numrows);
+ if (childtargrows > 0)
+ {
+ int childrows;
+ double trows,
+ tdrows;
+
+ /* Fetch a random sample of the child's rows */
+ childrows = acquire_sample_rows(childrel,
+ rows + numrows,
+ childtargrows,
+ &trows,
+ &tdrows);
+
+ /* We may need to convert from child's rowtype to parent's */
+ if (childrows > 0 &&
+ !equalTupleDescs(RelationGetDescr(childrel),
+ RelationGetDescr(onerel)))
+ {
+ TupleConversionMap *map;
+
+ map = convert_tuples_by_name(RelationGetDescr(childrel),
+ RelationGetDescr(onerel),
+ gettext_noop("could not convert row type"));
+ if (map != NULL)
+ {
+ int j;
+
+ for (j = 0; j < childrows; j++)
+ {
+ HeapTuple newtup;
+
+ newtup = do_convert_tuple(rows[numrows + j], map);
+ heap_freetuple(rows[numrows + j]);
+ rows[numrows + j] = newtup;
+ }
+ free_conversion_map(map);
+ }
+ }
+
+ /* And add to counts */
+ numrows += childrows;
+ *totalrows += trows;
+ *totaldeadrows += tdrows;
+ }
+ }
+
+ /*
+ * Note: we cannot release the child-table locks, since we may have
+ * pointers to their TOAST tables in the sampled rows.
+ */
+ heap_close(childrel, NoLock);
+ }
+
+ return numrows;
+}
+
+
/*
* update_attstats() -- update attribute statistics for one relation
*
@@ -1299,7 +1511,7 @@ compare_rows(const void *a, const void *b)
* by taking a self-exclusive lock on the relation in analyze_rel().
*/
static void
-update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
+update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
{
Relation sd;
int attno;
@@ -1337,6 +1549,7 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
i = 0;
values[i++] = ObjectIdGetDatum(relid); /* starelid */
values[i++] = Int16GetDatum(stats->attr->attnum); /* staattnum */
+ values[i++] = BoolGetDatum(inh); /* stainherit */
values[i++] = Float4GetDatum(stats->stanullfrac); /* stanullfrac */
values[i++] = Int32GetDatum(stats->stawidth); /* stawidth */
values[i++] = Float4GetDatum(stats->stadistinct); /* stadistinct */
@@ -1393,10 +1606,11 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
}
/* Is there already a pg_statistic tuple for this attribute? */
- oldtup = SearchSysCache(STATRELATT,
+ oldtup = SearchSysCache(STATRELATTINH,
ObjectIdGetDatum(relid),
Int16GetDatum(stats->attr->attnum),
- 0, 0);
+ BoolGetDatum(inh),
+ 0);
if (HeapTupleIsValid(oldtup))
{
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index b9d1fac0882..0049b7c9731 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.399 2009/12/19 01:32:34 sriggs Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.400 2009/12/29 20:11:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -292,7 +292,6 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
{
const char *stmttype;
- volatile MemoryContext anl_context = NULL;
volatile bool all_rels,
in_outer_xact,
use_own_xacts;
@@ -403,17 +402,6 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
use_own_xacts = false;
}
- /*
- * If we are running ANALYZE without per-table transactions, we'll need a
- * memory context with table lifetime.
- */
- if (!use_own_xacts)
- anl_context = AllocSetContextCreate(PortalContext,
- "Analyze",
- ALLOCSET_DEFAULT_MINSIZE,
- ALLOCSET_DEFAULT_INITSIZE,
- ALLOCSET_DEFAULT_MAXSIZE);
-
/*
* vacuum_rel expects to be entered with no transaction active; it will
* start and commit its own transaction. But we are called by an SQL
@@ -454,14 +442,9 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
if (vacstmt->options & VACOPT_ANALYZE)
{
- MemoryContext old_context = NULL;
-
/*
* If using separate xacts, start one for analyze. Otherwise,
- * we can use the outer transaction, but we still need to call
- * analyze_rel in a memory context that will be cleaned up on
- * return (else we leak memory while processing multiple
- * tables).
+ * we can use the outer transaction.
*/
if (use_own_xacts)
{
@@ -469,8 +452,6 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
/* functions in indexes may want a snapshot set */
PushActiveSnapshot(GetTransactionSnapshot());
}
- else
- old_context = MemoryContextSwitchTo(anl_context);
analyze_rel(relid, vacstmt, vac_strategy, !scanned_all);
@@ -479,11 +460,6 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
PopActiveSnapshot();
CommitTransactionCommand();
}
- else
- {
- MemoryContextSwitchTo(old_context);
- MemoryContextResetAndDeleteChildren(anl_context);
- }
}
}
}
@@ -528,9 +504,6 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
*/
MemoryContextDelete(vac_context);
vac_context = NULL;
-
- if (anl_context)
- MemoryContextDelete(anl_context);
}
/*
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 16b84d0f5ad..a58e9170272 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.123 2009/10/30 20:58:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.124 2009/12/29 20:11:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -996,10 +996,11 @@ ExecHashBuildSkewHash(HashJoinTable hashtable, Hash *node, int mcvsToUse)
/*
* Try to find the MCV statistics for the outer relation's join key.
*/
- statsTuple = SearchSysCache(STATRELATT,
+ statsTuple = SearchSysCache(STATRELATTINH,
ObjectIdGetDatum(node->skewTable),
Int16GetDatum(node->skewColumn),
- 0, 0);
+ BoolGetDatum(node->skewInherit),
+ 0);
if (!HeapTupleIsValid(statsTuple))
return;
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 2722a93e074..afbc3edaf62 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.455 2009/12/23 02:35:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.456 2009/12/29 20:11:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -763,6 +763,7 @@ _copyHash(Hash *from)
*/
COPY_SCALAR_FIELD(skewTable);
COPY_SCALAR_FIELD(skewColumn);
+ COPY_SCALAR_FIELD(skewInherit);
COPY_SCALAR_FIELD(skewColType);
COPY_SCALAR_FIELD(skewColTypmod);
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 419c005b508..b35b0beaf19 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.376 2009/12/23 02:35:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.377 2009/12/29 20:11:45 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
@@ -693,6 +693,7 @@ _outHash(StringInfo str, Hash *node)
WRITE_OID_FIELD(skewTable);
WRITE_INT_FIELD(skewColumn);
+ WRITE_BOOL_FIELD(skewInherit);
WRITE_OID_FIELD(skewColType);
WRITE_INT_FIELD(skewColTypmod);
}
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 41238b7c0e6..43b0c123ca2 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.267 2009/11/15 02:45:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.268 2009/12/29 20:11:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -115,6 +115,7 @@ static HashJoin *make_hashjoin(List *tlist,
static Hash *make_hash(Plan *lefttree,
Oid skewTable,
AttrNumber skewColumn,
+ bool skewInherit,
Oid skewColType,
int32 skewColTypmod);
static MergeJoin *make_mergejoin(List *tlist,
@@ -1898,6 +1899,7 @@ create_hashjoin_plan(PlannerInfo *root,
List *hashclauses;
Oid skewTable = InvalidOid;
AttrNumber skewColumn = InvalidAttrNumber;
+ bool skewInherit = false;
Oid skewColType = InvalidOid;
int32 skewColTypmod = -1;
HashJoin *join_plan;
@@ -1969,6 +1971,7 @@ create_hashjoin_plan(PlannerInfo *root,
{
skewTable = rte->relid;
skewColumn = var->varattno;
+ skewInherit = rte->inh;
skewColType = var->vartype;
skewColTypmod = var->vartypmod;
}
@@ -1981,6 +1984,7 @@ create_hashjoin_plan(PlannerInfo *root,
hash_plan = make_hash(inner_plan,
skewTable,
skewColumn,
+ skewInherit,
skewColType,
skewColTypmod);
join_plan = make_hashjoin(tlist,
@@ -2794,6 +2798,7 @@ static Hash *
make_hash(Plan *lefttree,
Oid skewTable,
AttrNumber skewColumn,
+ bool skewInherit,
Oid skewColType,
int32 skewColTypmod)
{
@@ -2814,6 +2819,7 @@ make_hash(Plan *lefttree,
node->skewTable = skewTable;
node->skewColumn = skewColumn;
+ node->skewInherit = skewInherit;
node->skewColType = skewColType;
node->skewColTypmod = skewColTypmod;
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 20d4180e9b9..8bc26cb6e97 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.263 2009/10/21 20:38:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.264 2009/12/29 20:11:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -4046,20 +4046,13 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
!vardata->freefunc)
elog(ERROR, "no function provided to release variable stats with");
}
- else if (rte->inh)
- {
- /*
- * XXX This means the Var represents a column of an append
- * relation. Later add code to look at the member relations and
- * try to derive some kind of combined statistics?
- */
- }
else if (rte->rtekind == RTE_RELATION)
{
- vardata->statsTuple = SearchSysCache(STATRELATT,
+ vardata->statsTuple = SearchSysCache(STATRELATTINH,
ObjectIdGetDatum(rte->relid),
Int16GetDatum(var->varattno),
- 0, 0);
+ BoolGetDatum(rte->inh),
+ 0);
vardata->freefunc = ReleaseSysCache;
}
else
@@ -4196,10 +4189,11 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
else if (index->indpred == NIL)
{
vardata->statsTuple =
- SearchSysCache(STATRELATT,
+ SearchSysCache(STATRELATTINH,
ObjectIdGetDatum(index->indexoid),
Int16GetDatum(pos + 1),
- 0, 0);
+ BoolGetDatum(false),
+ 0);
vardata->freefunc = ReleaseSysCache;
}
if (vardata->statsTuple)
@@ -5830,10 +5824,11 @@ btcostestimate(PG_FUNCTION_ARGS)
}
else
{
- vardata.statsTuple = SearchSysCache(STATRELATT,
+ vardata.statsTuple = SearchSysCache(STATRELATTINH,
ObjectIdGetDatum(relid),
Int16GetDatum(colnum),
- 0, 0);
+ BoolGetDatum(rte->inh),
+ 0);
vardata.freefunc = ReleaseSysCache;
}
}
@@ -5856,10 +5851,11 @@ btcostestimate(PG_FUNCTION_ARGS)
}
else
{
- vardata.statsTuple = SearchSysCache(STATRELATT,
+ vardata.statsTuple = SearchSysCache(STATRELATTINH,
ObjectIdGetDatum(relid),
Int16GetDatum(colnum),
- 0, 0);
+ BoolGetDatum(false),
+ 0);
vardata.freefunc = ReleaseSysCache;
}
}
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 0b50309bf36..fc1c21bc4a9 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.163 2009/08/10 05:46:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.164 2009/12/29 20:11:45 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
@@ -2524,6 +2524,9 @@ get_typmodout(Oid typid)
* Given the table and attribute number of a column, get the average
* width of entries in the column. Return zero if no data available.
*
+ * Currently this is only consulted for individual tables, not for inheritance
+ * trees, so we don't need an "inh" parameter.
+ *
* Calling a hook at this point looks somewhat strange, but is required
* because the optimizer calls this function without any other way for
* plug-ins to control the result.
@@ -2540,10 +2543,11 @@ get_attavgwidth(Oid relid, AttrNumber attnum)
if (stawidth > 0)
return stawidth;
}
- tp = SearchSysCache(STATRELATT,
+ tp = SearchSysCache(STATRELATTINH,
ObjectIdGetDatum(relid),
Int16GetDatum(attnum),
- 0, 0);
+ BoolGetDatum(false),
+ 0);
if (HeapTupleIsValid(tp))
{
stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;
@@ -2609,7 +2613,7 @@ get_attstatsslot(HeapTuple statstuple,
if (values)
{
- val = SysCacheGetAttr(STATRELATT, statstuple,
+ val = SysCacheGetAttr(STATRELATTINH, statstuple,
Anum_pg_statistic_stavalues1 + i,
&isnull);
if (isnull)
@@ -2658,7 +2662,7 @@ get_attstatsslot(HeapTuple statstuple,
if (numbers)
{
- val = SysCacheGetAttr(STATRELATT, statstuple,
+ val = SysCacheGetAttr(STATRELATTINH, statstuple,
Anum_pg_statistic_stanumbers1 + i,
&isnull);
if (isnull)
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index efed498f120..59e9ee60269 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.121 2009/10/05 19:24:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.122 2009/12/29 20:11:45 tgl Exp $
*
* NOTES
* These routines allow the parser/planner/executor to perform
@@ -597,14 +597,14 @@ static const struct cachedesc cacheinfo[] = {
},
1024
},
- {StatisticRelationId, /* STATRELATT */
- StatisticRelidAttnumIndexId,
+ {StatisticRelationId, /* STATRELATTINH */
+ StatisticRelidAttnumInhIndexId,
Anum_pg_statistic_starelid,
- 2,
+ 3,
{
Anum_pg_statistic_starelid,
Anum_pg_statistic_staattnum,
- 0,
+ Anum_pg_statistic_stainherit,
0
},
1024
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 6ac2c6713d8..0c4ce005295 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.561 2009/12/27 14:50:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.562 2009/12/29 20:11:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200912271
+#define CATALOG_VERSION_NO 200912281
#endif
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index 3bf606c0985..a5d93ed4455 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.111 2009/12/11 03:34:56 itagaki Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.112 2009/12/29 20:11:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -208,8 +208,8 @@ DECLARE_INDEX(pg_shdepend_depender_index, 1232, on pg_shdepend using btree(dbid
DECLARE_INDEX(pg_shdepend_reference_index, 1233, on pg_shdepend using btree(refclassid oid_ops, refobjid oid_ops));
#define SharedDependReferenceIndexId 1233
-DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index, 2696, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops));
-#define StatisticRelidAttnumIndexId 2696
+DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_inh_index, 2696, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops, stainherit bool_ops));
+#define StatisticRelidAttnumInhIndexId 2696
DECLARE_UNIQUE_INDEX(pg_tablespace_oid_index, 2697, on pg_tablespace using btree(oid oid_ops));
#define TablespaceOidIndexId 2697
diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h
index 0e831ef2982..8063f74190d 100644
--- a/src/include/catalog/pg_statistic.h
+++ b/src/include/catalog/pg_statistic.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_statistic.h,v 1.39 2009/06/11 14:49:10 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_statistic.h,v 1.40 2009/12/29 20:11:45 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -43,6 +43,7 @@ CATALOG(pg_statistic,2619) BKI_WITHOUT_OIDS
/* These fields form the unique key for the entry: */
Oid starelid; /* relation containing attribute */
int2 staattnum; /* attribute (column) stats are for */
+ bool stainherit; /* true if inheritance children are included */
/* the fraction of the column's entries that are NULL: */
float4 stanullfrac;
@@ -142,28 +143,29 @@ typedef FormData_pg_statistic *Form_pg_statistic;
* compiler constants for pg_statistic
* ----------------
*/
-#define Natts_pg_statistic 21
+#define Natts_pg_statistic 22
#define Anum_pg_statistic_starelid 1
#define Anum_pg_statistic_staattnum 2
-#define Anum_pg_statistic_stanullfrac 3
-#define Anum_pg_statistic_stawidth 4
-#define Anum_pg_statistic_stadistinct 5
-#define Anum_pg_statistic_stakind1 6
-#define Anum_pg_statistic_stakind2 7
-#define Anum_pg_statistic_stakind3 8
-#define Anum_pg_statistic_stakind4 9
-#define Anum_pg_statistic_staop1 10
-#define Anum_pg_statistic_staop2 11
-#define Anum_pg_statistic_staop3 12
-#define Anum_pg_statistic_staop4 13
-#define Anum_pg_statistic_stanumbers1 14
-#define Anum_pg_statistic_stanumbers2 15
-#define Anum_pg_statistic_stanumbers3 16
-#define Anum_pg_statistic_stanumbers4 17
-#define Anum_pg_statistic_stavalues1 18
-#define Anum_pg_statistic_stavalues2 19
-#define Anum_pg_statistic_stavalues3 20
-#define Anum_pg_statistic_stavalues4 21
+#define Anum_pg_statistic_stainherit 3
+#define Anum_pg_statistic_stanullfrac 4
+#define Anum_pg_statistic_stawidth 5
+#define Anum_pg_statistic_stadistinct 6
+#define Anum_pg_statistic_stakind1 7
+#define Anum_pg_statistic_stakind2 8
+#define Anum_pg_statistic_stakind3 9
+#define Anum_pg_statistic_stakind4 10
+#define Anum_pg_statistic_staop1 11
+#define Anum_pg_statistic_staop2 12
+#define Anum_pg_statistic_staop3 13
+#define Anum_pg_statistic_staop4 14
+#define Anum_pg_statistic_stanumbers1 15
+#define Anum_pg_statistic_stanumbers2 16
+#define Anum_pg_statistic_stanumbers3 17
+#define Anum_pg_statistic_stanumbers4 18
+#define Anum_pg_statistic_stavalues1 19
+#define Anum_pg_statistic_stavalues2 20
+#define Anum_pg_statistic_stavalues3 21
+#define Anum_pg_statistic_stavalues4 22
/*
* Currently, three statistical slot "kinds" are defined: most common values,
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index e9c994e4f27..68c95d5cf8a 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.113 2009/10/26 02:26:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.114 2009/12/29 20:11:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -570,9 +570,9 @@ typedef struct Unique
* hash build node
*
* If the executor is supposed to try to apply skew join optimization, then
- * skewTable/skewColumn identify the outer relation's join key column, from
- * which the relevant MCV statistics can be fetched. Also, its type
- * information is provided to save a lookup.
+ * skewTable/skewColumn/skewInherit identify the outer relation's join key
+ * column, from which the relevant MCV statistics can be fetched. Also, its
+ * type information is provided to save a lookup.
* ----------------
*/
typedef struct Hash
@@ -580,6 +580,7 @@ typedef struct Hash
Plan plan;
Oid skewTable; /* outer join key's table OID, or InvalidOid */
AttrNumber skewColumn; /* outer join key's column #, or zero */
+ bool skewInherit; /* is outer join rel an inheritance tree? */
Oid skewColType; /* datatype of the outer key column */
int32 skewColTypmod; /* typmod of the outer key column */
/* all other info is in the parent HashJoin node */
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index f0647e34194..d2d02236c78 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.75 2009/10/05 19:24:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.76 2009/12/29 20:11:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -70,7 +70,7 @@ enum SysCacheIdentifier
RELNAMENSP,
RELOID,
RULERELNAME,
- STATRELATT,
+ STATRELATTINH,
TSCONFIGMAP,
TSCONFIGNAMENSP,
TSCONFIGOID,
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 9420e568acd..87f87e9afcf 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1276,8 +1276,8 @@ drop table cchild;
-- Check that ruleutils are working
--
SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schema' ORDER BY viewname;
- viewname | definition
---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ viewname | definition
+--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
pg_cursors | SELECT c.name, c.statement, c.is_holdable, c.is_binary, c.is_scrollable, c.creation_time FROM pg_cursor() c(name, statement, is_holdable, is_binary, is_scrollable, creation_time);
pg_group | SELECT pg_authid.rolname AS groname, pg_authid.oid AS grosysid, ARRAY(SELECT pg_auth_members.member FROM pg_auth_members WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist FROM pg_authid WHERE (NOT pg_authid.rolcanlogin);
@@ -1308,7 +1308,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
pg_statio_user_indexes | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE ((pg_statio_all_indexes.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_indexes.schemaname !~ '^pg_toast'::text));
pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE ((pg_statio_all_sequences.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_sequences.schemaname !~ '^pg_toast'::text));
pg_statio_user_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE ((pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (pg_statio_all_tables.schemaname !~ '^pg_toast'::text));
- pg_stats | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stavalues1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stavalues2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stavalues3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stavalues4 ELSE NULL::anyarray END AS most_common_vals, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stanumbers1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stanumbers2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stanumbers3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE WHEN (s.stakind1 = 2) THEN s.stavalues1 WHEN (s.stakind2 = 2) THEN s.stavalues2 WHEN (s.stakind3 = 2) THEN s.stavalues3 WHEN (s.stakind4 = 2) THEN s.stavalues4 ELSE NULL::anyarray END AS histogram_bounds, CASE WHEN (s.stakind1 = 3) THEN s.stanumbers1[1] WHEN (s.stakind2 = 3) THEN s.stanumbers2[1] WHEN (s.stakind3 = 3) THEN s.stanumbers3[1] WHEN (s.stakind4 = 3) THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text));
+ pg_stats | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stainherit AS inherited, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stavalues1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stavalues2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stavalues3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stavalues4 ELSE NULL::anyarray END AS most_common_vals, CASE WHEN (s.stakind1 = ANY (ARRAY[1, 4])) THEN s.stanumbers1 WHEN (s.stakind2 = ANY (ARRAY[1, 4])) THEN s.stanumbers2 WHEN (s.stakind3 = ANY (ARRAY[1, 4])) THEN s.stanumbers3 WHEN (s.stakind4 = ANY (ARRAY[1, 4])) THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE WHEN (s.stakind1 = 2) THEN s.stavalues1 WHEN (s.stakind2 = 2) THEN s.stavalues2 WHEN (s.stakind3 = 2) THEN s.stavalues3 WHEN (s.stakind4 = 2) THEN s.stavalues4 ELSE NULL::anyarray END AS histogram_bounds, CASE WHEN (s.stakind1 = 3) THEN s.stanumbers1[1] WHEN (s.stakind2 = 3) THEN s.stanumbers2[1] WHEN (s.stakind3 = 3) THEN s.stanumbers3[1] WHEN (s.stakind4 = 3) THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text));
pg_tables | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS tablespace, c.relhasindex AS hasindexes, c.relhasrules AS hasrules, c.relhastriggers AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char");
pg_timezone_abbrevs | SELECT pg_timezone_abbrevs.abbrev, pg_timezone_abbrevs.utc_offset, pg_timezone_abbrevs.is_dst FROM pg_timezone_abbrevs() pg_timezone_abbrevs(abbrev, utc_offset, is_dst);
pg_timezone_names | SELECT pg_timezone_names.name, pg_timezone_names.abbrev, pg_timezone_names.utc_offset, pg_timezone_names.is_dst FROM pg_timezone_names() pg_timezone_names(name, abbrev, utc_offset, is_dst);