Commit f0c9397f authored by Tom Lane's avatar Tom Lane

First steps towards statistics on expressional (nee functional) indexes.

This commit teaches ANALYZE to store such stats in pg_statistic, but
nothing is done yet about teaching the planner to use 'em.
Also, repair longstanding oversight in separate ANALYZE command: it
updated the pg_class.relpages and reltuples counts for the table proper,
but not for indexes.
parent 4b8f1259
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
$PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.83 2004/02/12 23:41:00 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.84 2004/02/15 21:01:38 tgl Exp $
--> -->
<chapter id="catalogs"> <chapter id="catalogs">
...@@ -3068,22 +3068,31 @@ ...@@ -3068,22 +3068,31 @@
</indexterm> </indexterm>
<para> <para>
The catalog <structname>pg_statistic</structname> stores statistical data about The catalog <structname>pg_statistic</structname> stores statistical data
the contents of the database. Entries are created by about the contents of the database. Entries are created by
<command>ANALYZE</command> and subsequently used by the query planner. <command>ANALYZE</command> and subsequently used by the query planner.
There is one entry for each table column that has been analyzed. There is one entry for each table column that has been analyzed.
Note that all the statistical data is inherently approximate, Note that all the statistical data is inherently approximate,
even assuming that it is up-to-date. even assuming that it is up-to-date.
</para> </para>
<para>
<structname>pg_statistic</structname> also stores statistical data about
the values of index expressions. These are described as if they were
actual data columns; in particular, <structfield>starelid</structfield>
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.
</para>
<para> <para>
Since different kinds of statistics may be appropriate for different Since different kinds of statistics may be appropriate for different
kinds of data, <structname>pg_statistic</structname> is designed not kinds of data, <structname>pg_statistic</structname> is designed not
to assume very much about what sort of statistics it stores. Only to assume very much about what sort of statistics it stores. Only
extremely general statistics (such as nullness) are given dedicated extremely general statistics (such as nullness) are given dedicated
columns in <structname>pg_statistic</structname>. Everything else columns in <structname>pg_statistic</structname>. Everything else
is stored in <quote>slots</quote>, which are groups of associated columns whose is stored in <quote>slots</quote>, which are groups of associated columns
content is identified by a code number in one of the slot's columns. whose content is identified by a code number in one of the slot's columns.
For more information see For more information see
<filename>src/include/catalog/pg_statistic.h</filename>. <filename>src/include/catalog/pg_statistic.h</filename>.
</para> </para>
...@@ -3117,7 +3126,7 @@ ...@@ -3117,7 +3126,7 @@
<entry><structfield>starelid</structfield></entry> <entry><structfield>starelid</structfield></entry>
<entry><type>oid</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry> <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
<entry>The table that the described column belongs to</entry> <entry>The table or index that the described column belongs to</entry>
</row> </row>
<row> <row>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.259 2004/02/12 23:41:02 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.260 2004/02/15 21:01:39 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -76,7 +76,6 @@ static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin); ...@@ -76,7 +76,6 @@ static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin);
static void StoreRelCheck(Relation rel, char *ccname, char *ccbin); static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
static void StoreConstraints(Relation rel, TupleDesc tupdesc); static void StoreConstraints(Relation rel, TupleDesc tupdesc);
static void SetRelationNumChecks(Relation rel, int numchecks); static void SetRelationNumChecks(Relation rel, int numchecks);
static void RemoveStatistics(Relation rel, AttrNumber attnum);
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
...@@ -1868,7 +1867,7 @@ RemoveRelConstraints(Relation rel, const char *constrName, ...@@ -1868,7 +1867,7 @@ RemoveRelConstraints(Relation rel, const char *constrName,
* 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
* for that column. * for that column.
*/ */
static void void
RemoveStatistics(Relation rel, AttrNumber attnum) RemoveStatistics(Relation rel, AttrNumber attnum)
{ {
Relation pgstatistic; Relation pgstatistic;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.227 2004/02/10 01:55:24 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.228 2004/02/15 21:01:39 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -153,7 +153,7 @@ ConstructTupleDescriptor(Relation heapRelation, ...@@ -153,7 +153,7 @@ ConstructTupleDescriptor(Relation heapRelation,
*/ */
to->attnum = i + 1; to->attnum = i + 1;
to->attstattarget = 0; to->attstattarget = -1;
to->attcacheoff = -1; to->attcacheoff = -1;
to->attnotnull = false; to->attnotnull = false;
to->atthasdef = false; to->atthasdef = false;
...@@ -197,6 +197,7 @@ ConstructTupleDescriptor(Relation heapRelation, ...@@ -197,6 +197,7 @@ ConstructTupleDescriptor(Relation heapRelation,
to->attbyval = typeTup->typbyval; to->attbyval = typeTup->typbyval;
to->attstorage = typeTup->typstorage; to->attstorage = typeTup->typstorage;
to->attalign = typeTup->typalign; to->attalign = typeTup->typalign;
to->attstattarget = -1;
to->attcacheoff = -1; to->attcacheoff = -1;
to->atttypmod = -1; to->atttypmod = -1;
to->attislocal = true; to->attislocal = true;
...@@ -753,6 +754,7 @@ index_drop(Oid indexId) ...@@ -753,6 +754,7 @@ index_drop(Oid indexId)
Relation userIndexRelation; Relation userIndexRelation;
Relation indexRelation; Relation indexRelation;
HeapTuple tuple; HeapTuple tuple;
bool hasexprs;
int i; int i;
Assert(OidIsValid(indexId)); Assert(OidIsValid(indexId));
...@@ -786,7 +788,7 @@ index_drop(Oid indexId) ...@@ -786,7 +788,7 @@ index_drop(Oid indexId)
DeleteAttributeTuples(indexId); DeleteAttributeTuples(indexId);
/* /*
* fix INDEX relation * fix INDEX relation, and check for expressional index
*/ */
indexRelation = heap_openr(IndexRelationName, RowExclusiveLock); indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
...@@ -796,11 +798,20 @@ index_drop(Oid indexId) ...@@ -796,11 +798,20 @@ index_drop(Oid indexId)
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for index %u", indexId); elog(ERROR, "cache lookup failed for index %u", indexId);
hasexprs = !heap_attisnull(tuple, Anum_pg_index_indexprs);
simple_heap_delete(indexRelation, &tuple->t_self); simple_heap_delete(indexRelation, &tuple->t_self);
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
heap_close(indexRelation, RowExclusiveLock); heap_close(indexRelation, RowExclusiveLock);
/*
* if it has any expression columns, we might have stored
* statistics about them.
*/
if (hasexprs)
RemoveStatistics(userIndexRelation, 0);
/* /*
* flush buffer cache and physically remove the file * flush buffer cache and physically remove the file
*/ */
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.98 2004/02/10 01:55:25 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.99 2004/02/15 21:01:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2258,13 +2258,19 @@ AlterTableAlterColumnFlags(Oid myrelid, bool recurse, ...@@ -2258,13 +2258,19 @@ AlterTableAlterColumnFlags(Oid myrelid, bool recurse,
HeapTuple tuple; HeapTuple tuple;
Form_pg_attribute attrtuple; Form_pg_attribute attrtuple;
rel = heap_open(myrelid, AccessExclusiveLock); rel = relation_open(myrelid, AccessExclusiveLock);
/*
* Allow index for statistics case only
*/
if (rel->rd_rel->relkind != RELKIND_RELATION) if (rel->rd_rel->relkind != RELKIND_RELATION)
ereport(ERROR, {
(errcode(ERRCODE_WRONG_OBJECT_TYPE), if (rel->rd_rel->relkind != RELKIND_INDEX || *flagType != 'S')
errmsg("\"%s\" is not a table", ereport(ERROR,
RelationGetRelationName(rel)))); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not a table",
RelationGetRelationName(rel))));
}
/* Permissions checks */ /* Permissions checks */
if (!pg_class_ownercheck(myrelid, GetUserId())) if (!pg_class_ownercheck(myrelid, GetUserId()))
...@@ -2339,7 +2345,7 @@ AlterTableAlterColumnFlags(Oid myrelid, bool recurse, ...@@ -2339,7 +2345,7 @@ AlterTableAlterColumnFlags(Oid myrelid, bool recurse,
/* /*
* Propagate to children if desired * Propagate to children if desired
*/ */
if (recurse) if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
{ {
List *child, List *child,
*children; *children;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.63 2003/11/29 22:40:58 pgsql Exp $ * $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.64 2004/02/15 21:01:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -69,6 +69,7 @@ extern void RemoveAttributeById(Oid relid, AttrNumber attnum); ...@@ -69,6 +69,7 @@ extern void RemoveAttributeById(Oid relid, AttrNumber attnum);
extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, extern void RemoveAttrDefault(Oid relid, AttrNumber attnum,
DropBehavior behavior, bool complain); DropBehavior behavior, bool complain);
extern void RemoveAttrDefaultById(Oid attrdefId); extern void RemoveAttrDefaultById(Oid attrdefId);
extern void RemoveStatistics(Relation rel, AttrNumber attnum);
extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
bool relhasoids); bool relhasoids);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.50 2004/02/13 06:39:49 tgl Exp $ * $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.51 2004/02/15 21:01:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -106,8 +106,11 @@ typedef struct VacAttrStats ...@@ -106,8 +106,11 @@ typedef struct VacAttrStats
* be looked at by type-specific functions. * be looked at by type-specific functions.
*/ */
int tupattnum; /* attribute number within tuples */ int tupattnum; /* attribute number within tuples */
HeapTuple *rows; /* access info for fetch function */ HeapTuple *rows; /* access info for std fetch function */
TupleDesc tupDesc; TupleDesc tupDesc;
Datum *exprvals; /* access info for index fetch function */
bool *exprnulls;
int rowstride;
} VacAttrStats; } VacAttrStats;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment