diff options
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r-- | src/backend/optimizer/util/plancat.c | 248 | ||||
-rw-r--r-- | src/backend/optimizer/util/relnode.c | 17 |
2 files changed, 133 insertions, 132 deletions
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 4a9f63312c3..3e0bbe69225 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.76 2003/01/28 22:13:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.77 2003/02/03 15:07:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,6 +23,7 @@ #include "catalog/pg_amop.h" #include "catalog/pg_inherits.h" #include "catalog/pg_index.h" +#include "nodes/makefuncs.h" #include "optimizer/clauses.h" #include "optimizer/plancat.h" #include "parser/parsetree.h" @@ -38,155 +39,160 @@ /* * get_relation_info - * Retrieves catalog information for a given relation. - * Given the Oid of the relation, return the following info: - * whether the relation has secondary indices - * number of pages - * number of tuples - */ -void -get_relation_info(Oid relationObjectId, - bool *hasindex, long *pages, double *tuples) -{ - HeapTuple relationTuple; - Form_pg_class relation; - - relationTuple = SearchSysCache(RELOID, - ObjectIdGetDatum(relationObjectId), - 0, 0, 0); - if (!HeapTupleIsValid(relationTuple)) - elog(ERROR, "get_relation_info: Relation %u not found", - relationObjectId); - relation = (Form_pg_class) GETSTRUCT(relationTuple); - - if (IsIgnoringSystemIndexes() && IsSystemClass(relation)) - *hasindex = false; - else - *hasindex = relation->relhasindex; - - *pages = relation->relpages; - *tuples = relation->reltuples; - - ReleaseSysCache(relationTuple); -} - -/* - * find_secondary_indexes - * Creates a list of IndexOptInfo nodes containing information for each - * secondary index defined on the specified relation. * - * 'relationObjectId' is the OID of the relation for which indices are wanted + * Given the Oid of the relation, return the following info into fields + * of the RelOptInfo struct: * - * Returns a list of new IndexOptInfo nodes. + * varlist list of physical columns (expressed as Vars) + * indexlist list of IndexOptInfos for relation's indexes + * pages number of pages + * tuples number of tuples */ -List * -find_secondary_indexes(Oid relationObjectId) +void +get_relation_info(Oid relationObjectId, RelOptInfo *rel) { - List *indexinfos = NIL; - List *indexoidlist, - *indexoidscan; Relation relation; + Index varno = lfirsti(rel->relids); + bool hasindex; + List *varlist = NIL; + List *indexinfos = NIL; + int attrno, + numattrs; + + relation = heap_open(relationObjectId, AccessShareLock); /* - * We used to scan pg_index directly, but now the relcache offers a - * cached list of OID indexes for each relation. So, get that list - * and then use the syscache to obtain pg_index entries. + * Make list of physical Vars. Note we do NOT ignore dropped columns; + * the intent is to model the physical tuples of the relation. */ - relation = heap_open(relationObjectId, AccessShareLock); - indexoidlist = RelationGetIndexList(relation); + numattrs = RelationGetNumberOfAttributes(relation); - foreach(indexoidscan, indexoidlist) + for (attrno = 1; attrno <= numattrs; attrno++) { - Oid indexoid = lfirsti(indexoidscan); - Relation indexRelation; - Form_pg_index index; - IndexOptInfo *info; - int i; - int16 amorderstrategy; - - /* Extract info from the relation descriptor for the index */ - indexRelation = index_open(indexoid); + Form_pg_attribute att_tup = relation->rd_att->attrs[attrno - 1]; + + varlist = lappend(varlist, + makeVar(varno, + attrno, + att_tup->atttypid, + att_tup->atttypmod, + 0)); + } - info = makeNode(IndexOptInfo); + rel->varlist = varlist; - /* - * Need to make these arrays large enough to be sure there is room - * for a terminating 0 at the end of each one. - */ - info->classlist = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS + 1)); - info->indexkeys = (int *) palloc(sizeof(int) * (INDEX_MAX_KEYS + 1)); - info->ordering = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS + 1)); - - /* Extract info from the pg_index tuple */ - index = indexRelation->rd_index; - info->indexoid = index->indexrelid; - info->indproc = index->indproc; /* functional index ?? */ - if (VARSIZE(&index->indpred) > VARHDRSZ) /* partial index ?? */ - { - char *predString; + /* + * Make list of indexes. Ignore indexes on system catalogs if told to. + */ + if (IsIgnoringSystemIndexes() && IsSystemClass(relation->rd_rel)) + hasindex = false; + else + hasindex = relation->rd_rel->relhasindex; - predString = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(&index->indpred))); - info->indpred = (List *) stringToNode(predString); - pfree(predString); - } - else - info->indpred = NIL; - info->unique = index->indisunique; + if (hasindex) + { + List *indexoidlist, + *indexoidscan; - for (i = 0; i < INDEX_MAX_KEYS; i++) - { - if (index->indclass[i] == (Oid) 0) - break; - info->classlist[i] = index->indclass[i]; - } - info->classlist[i] = (Oid) 0; - info->ncolumns = i; + indexoidlist = RelationGetIndexList(relation); - for (i = 0; i < INDEX_MAX_KEYS; i++) + foreach(indexoidscan, indexoidlist) { - if (index->indkey[i] == 0) - break; - info->indexkeys[i] = index->indkey[i]; - } - info->indexkeys[i] = 0; - info->nkeys = i; + Oid indexoid = lfirsti(indexoidscan); + Relation indexRelation; + Form_pg_index index; + IndexOptInfo *info; + int i; + int16 amorderstrategy; + + /* Extract info from the relation descriptor for the index */ + indexRelation = index_open(indexoid); + + info = makeNode(IndexOptInfo); + + /* + * Need to make these arrays large enough to be sure there is room + * for a terminating 0 at the end of each one. + */ + info->classlist = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS + 1)); + info->indexkeys = (int *) palloc(sizeof(int) * (INDEX_MAX_KEYS + 1)); + info->ordering = (Oid *) palloc(sizeof(Oid) * (INDEX_MAX_KEYS + 1)); + + /* Extract info from the pg_index tuple */ + index = indexRelation->rd_index; + info->indexoid = index->indexrelid; + info->indproc = index->indproc; /* functional index ?? */ + if (VARSIZE(&index->indpred) > VARHDRSZ) /* partial index ?? */ + { + char *predString; - info->relam = indexRelation->rd_rel->relam; - info->pages = indexRelation->rd_rel->relpages; - info->tuples = indexRelation->rd_rel->reltuples; - info->amcostestimate = index_cost_estimator(indexRelation); - amorderstrategy = indexRelation->rd_am->amorderstrategy; + predString = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(&index->indpred))); + info->indpred = (List *) stringToNode(predString); + pfree(predString); + } + else + info->indpred = NIL; + info->unique = index->indisunique; - /* - * Fetch the ordering operators associated with the index, if any. - */ - MemSet(info->ordering, 0, sizeof(Oid) * (INDEX_MAX_KEYS + 1)); - if (amorderstrategy != 0) - { - int oprindex = amorderstrategy - 1; + for (i = 0; i < INDEX_MAX_KEYS; i++) + { + if (index->indclass[i] == (Oid) 0) + break; + info->classlist[i] = index->indclass[i]; + } + info->classlist[i] = (Oid) 0; + info->ncolumns = i; - for (i = 0; i < info->ncolumns; i++) + for (i = 0; i < INDEX_MAX_KEYS; i++) { - info->ordering[i] = indexRelation->rd_operator[oprindex]; - oprindex += indexRelation->rd_am->amstrategies; + if (index->indkey[i] == 0) + break; + info->indexkeys[i] = index->indkey[i]; } - } + info->indexkeys[i] = 0; + info->nkeys = i; + + info->relam = indexRelation->rd_rel->relam; + info->pages = indexRelation->rd_rel->relpages; + info->tuples = indexRelation->rd_rel->reltuples; + info->amcostestimate = index_cost_estimator(indexRelation); + amorderstrategy = indexRelation->rd_am->amorderstrategy; + + /* + * Fetch the ordering operators associated with the index, if any. + */ + MemSet(info->ordering, 0, sizeof(Oid) * (INDEX_MAX_KEYS + 1)); + if (amorderstrategy != 0) + { + int oprindex = amorderstrategy - 1; - /* initialize cached join info to empty */ - info->outer_relids = NIL; - info->inner_paths = NIL; + for (i = 0; i < info->ncolumns; i++) + { + info->ordering[i] = indexRelation->rd_operator[oprindex]; + oprindex += indexRelation->rd_am->amstrategies; + } + } - index_close(indexRelation); + /* initialize cached join info to empty */ + info->outer_relids = NIL; + info->inner_paths = NIL; - indexinfos = lcons(info, indexinfos); + index_close(indexRelation); + + indexinfos = lcons(info, indexinfos); + } + + freeList(indexoidlist); } - freeList(indexoidlist); + rel->indexlist = indexinfos; + + rel->pages = relation->rd_rel->relpages; + rel->tuples = relation->rd_rel->reltuples; /* XXX keep the lock here? */ heap_close(relation, AccessShareLock); - - return indexinfos; } /* diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 06a73bf4e9e..ebfaa4924d4 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.45 2003/01/24 03:58:43 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.46 2003/02/03 15:07:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -143,6 +143,7 @@ make_base_rel(Query *root, int relid) rel->cheapest_unique_path = NULL; rel->pruneable = true; rel->rtekind = rte->rtekind; + rel->varlist = NIL; rel->indexlist = NIL; rel->pages = 0; rel->tuples = 0; @@ -159,16 +160,9 @@ make_base_rel(Query *root, int relid) switch (rte->rtekind) { case RTE_RELATION: - { - /* Table --- retrieve statistics from the system catalogs */ - bool indexed; - - get_relation_info(rte->relid, - &indexed, &rel->pages, &rel->tuples); - if (indexed) - rel->indexlist = find_secondary_indexes(rte->relid); - break; - } + /* Table --- retrieve statistics from the system catalogs */ + get_relation_info(rte->relid, rel); + break; case RTE_SUBQUERY: case RTE_FUNCTION: /* Subquery or function --- nothing to do here */ @@ -304,6 +298,7 @@ build_join_rel(Query *root, joinrel->cheapest_unique_path = NULL; joinrel->pruneable = true; joinrel->rtekind = RTE_JOIN; + joinrel->varlist = NIL; joinrel->indexlist = NIL; joinrel->pages = 0; joinrel->tuples = 0; |