| /*------------------------------------------------------------------------- |
| * |
| * indexing.c |
| * This file contains routines to support indexes defined on system |
| * catalogs. |
| * |
| * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group |
| * Portions Copyright (c) 1994, Regents of the University of California |
| * |
| * |
| * IDENTIFICATION |
| * $PostgreSQL: pgsql/src/backend/catalog/indexing.c,v 1.113 2006/07/03 22:45:38 tgl Exp $ |
| * |
| *------------------------------------------------------------------------- |
| */ |
| #include "postgres.h" |
| |
| #include "access/genam.h" |
| #include "catalog/index.h" |
| #include "catalog/indexing.h" |
| #include "executor/executor.h" |
| |
| |
| /* |
| * CatalogOpenIndexes - open the indexes on a system catalog. |
| * |
| * When inserting or updating tuples in a system catalog, call this |
| * to prepare to update the indexes for the catalog. |
| * |
| * In the current implementation, we share code for opening/closing the |
| * indexes with execUtils.c. But we do not use ExecInsertIndexTuples, |
| * because we don't want to create an EState. This implies that we |
| * do not support partial or expressional indexes on system catalogs. |
| * This could be fixed with localized changes here if we wanted to pay |
| * the extra overhead of building an EState. |
| */ |
| CatalogIndexState |
| CatalogOpenIndexes(Relation heapRel) |
| { |
| ResultRelInfo *resultRelInfo; |
| |
| resultRelInfo = makeNode(ResultRelInfo); |
| resultRelInfo->ri_RangeTableIndex = 1; /* dummy */ |
| resultRelInfo->ri_RelationDesc = heapRel; |
| resultRelInfo->ri_TrigDesc = NULL; /* we don't fire triggers */ |
| |
| ExecOpenIndices(resultRelInfo); |
| |
| return resultRelInfo; |
| } |
| |
| /* |
| * CatalogCloseIndexes - clean up resources allocated by CatalogOpenIndexes |
| */ |
| void |
| CatalogCloseIndexes(CatalogIndexState indstate) |
| { |
| ExecCloseIndices(indstate); |
| pfree(indstate); |
| } |
| |
| /* |
| * CatalogIndexInsert - insert index entries for one catalog tuple |
| * |
| * This should be called for each inserted or updated catalog tuple. |
| * |
| * This is effectively a cut-down version of ExecInsertIndexTuples. |
| */ |
| void |
| CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple) |
| { |
| int i; |
| int numIndexes; |
| RelationPtr relationDescs; |
| Relation heapRelation; |
| TupleTableSlot *slot; |
| IndexInfo **indexInfoArray; |
| Datum values[INDEX_MAX_KEYS]; |
| bool isnull[INDEX_MAX_KEYS]; |
| |
| /* |
| * Get information from the state structure. Fall out if nothing to do. |
| */ |
| numIndexes = indstate->ri_NumIndices; |
| if (numIndexes == 0) |
| return; |
| relationDescs = indstate->ri_IndexRelationDescs; |
| indexInfoArray = indstate->ri_IndexRelationInfo; |
| heapRelation = indstate->ri_RelationDesc; |
| |
| /* Need a slot to hold the tuple being examined */ |
| slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation)); |
| ExecStoreGenericTuple(heapTuple, slot, false); |
| |
| /* |
| * for each index, form and insert the index tuple |
| */ |
| for (i = 0; i < numIndexes; i++) |
| { |
| IndexInfo *indexInfo; |
| |
| indexInfo = indexInfoArray[i]; |
| |
| /* |
| * Expressional and partial indexes on system catalogs are not |
| * supported |
| */ |
| Assert(indexInfo->ii_Expressions == NIL); |
| Assert(indexInfo->ii_Predicate == NIL); |
| |
| /* |
| * FormIndexDatum fills in its values and isnull parameters with the |
| * appropriate values for the column(s) of the index. |
| */ |
| FormIndexDatum(indexInfo, |
| slot, |
| NULL, /* no expression eval to do */ |
| values, |
| isnull); |
| |
| /* |
| * The index AM does the rest. |
| */ |
| index_insert(relationDescs[i], /* index relation */ |
| values, /* array of index Datums */ |
| isnull, /* is-null flags */ |
| &(heapTuple->t_self), /* tid of heap tuple */ |
| heapRelation, |
| relationDescs[i]->rd_index->indisunique); |
| } |
| |
| ExecDropSingleTupleTableSlot(slot); |
| } |
| |
| /* |
| * CatalogUpdateIndexes - do all the indexing work for a new catalog tuple |
| * |
| * This is a convenience routine for the common case where we only need |
| * to insert or update a single tuple in a system catalog. Avoid using it for |
| * multiple tuples, since opening the indexes and building the index info |
| * structures is moderately expensive. |
| */ |
| void |
| CatalogUpdateIndexes(Relation heapRel, HeapTuple heapTuple) |
| { |
| CatalogIndexState indstate; |
| |
| indstate = CatalogOpenIndexes(heapRel); |
| CatalogIndexInsert(indstate, heapTuple); |
| CatalogCloseIndexes(indstate); |
| } |