PostgreSQL Source Code  git master
indexing.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * indexing.c
4  * This file contains routines to support indexes defined on system
5  * catalogs.
6  *
7  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  * src/backend/catalog/indexing.c
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17 
18 #include "access/htup_details.h"
19 #include "catalog/index.h"
20 #include "catalog/indexing.h"
21 #include "executor/executor.h"
22 #include "utils/rel.h"
23 
24 
25 /*
26  * CatalogOpenIndexes - open the indexes on a system catalog.
27  *
28  * When inserting or updating tuples in a system catalog, call this
29  * to prepare to update the indexes for the catalog.
30  *
31  * In the current implementation, we share code for opening/closing the
32  * indexes with execUtils.c. But we do not use ExecInsertIndexTuples,
33  * because we don't want to create an EState. This implies that we
34  * do not support partial or expressional indexes on system catalogs,
35  * nor can we support generalized exclusion constraints.
36  * This could be fixed with localized changes here if we wanted to pay
37  * the extra overhead of building an EState.
38  */
41 {
42  ResultRelInfo *resultRelInfo;
43 
44  resultRelInfo = makeNode(ResultRelInfo);
45  resultRelInfo->ri_RangeTableIndex = 1; /* dummy */
46  resultRelInfo->ri_RelationDesc = heapRel;
47  resultRelInfo->ri_TrigDesc = NULL; /* we don't fire triggers */
48 
49  ExecOpenIndices(resultRelInfo, false);
50 
51  return resultRelInfo;
52 }
53 
54 /*
55  * CatalogCloseIndexes - clean up resources allocated by CatalogOpenIndexes
56  */
57 void
59 {
60  ExecCloseIndices(indstate);
61  pfree(indstate);
62 }
63 
64 /*
65  * CatalogIndexInsert - insert index entries for one catalog tuple
66  *
67  * This should be called for each inserted or updated catalog tuple.
68  *
69  * This is effectively a cut-down version of ExecInsertIndexTuples.
70  */
71 static void
73 {
74  int i;
75  int numIndexes;
76  RelationPtr relationDescs;
77  Relation heapRelation;
78  TupleTableSlot *slot;
79  IndexInfo **indexInfoArray;
81  bool isnull[INDEX_MAX_KEYS];
82 
83  /* HOT update does not require index inserts */
84  if (HeapTupleIsHeapOnly(heapTuple))
85  return;
86 
87  /*
88  * Get information from the state structure. Fall out if nothing to do.
89  */
90  numIndexes = indstate->ri_NumIndices;
91  if (numIndexes == 0)
92  return;
93  relationDescs = indstate->ri_IndexRelationDescs;
94  indexInfoArray = indstate->ri_IndexRelationInfo;
95  heapRelation = indstate->ri_RelationDesc;
96 
97  /* Need a slot to hold the tuple being examined */
98  slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
99  ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
100 
101  /*
102  * for each index, form and insert the index tuple
103  */
104  for (i = 0; i < numIndexes; i++)
105  {
106  IndexInfo *indexInfo;
107 
108  indexInfo = indexInfoArray[i];
109 
110  /* If the index is marked as read-only, ignore it */
111  if (!indexInfo->ii_ReadyForInserts)
112  continue;
113 
114  /*
115  * Expressional and partial indexes on system catalogs are not
116  * supported, nor exclusion constraints, nor deferred uniqueness
117  */
118  Assert(indexInfo->ii_Expressions == NIL);
119  Assert(indexInfo->ii_Predicate == NIL);
120  Assert(indexInfo->ii_ExclusionOps == NULL);
121  Assert(relationDescs[i]->rd_index->indimmediate);
122  Assert(indexInfo->ii_NumIndexKeyAttrs != 0);
123 
124  /*
125  * FormIndexDatum fills in its values and isnull parameters with the
126  * appropriate values for the column(s) of the index.
127  */
128  FormIndexDatum(indexInfo,
129  slot,
130  NULL, /* no expression eval to do */
131  values,
132  isnull);
133 
134  /*
135  * The index AM does the rest.
136  */
137  index_insert(relationDescs[i], /* index relation */
138  values, /* array of index Datums */
139  isnull, /* is-null flags */
140  &(heapTuple->t_self), /* tid of heap tuple */
141  heapRelation,
142  relationDescs[i]->rd_index->indisunique ?
144  indexInfo);
145  }
146 
148 }
149 
150 /*
151  * CatalogTupleInsert - do heap and indexing work for a new catalog tuple
152  *
153  * Insert the tuple data in "tup" into the specified catalog relation.
154  * The Oid of the inserted tuple is returned.
155  *
156  * This is a convenience routine for the common case of inserting a single
157  * tuple in a system catalog; it inserts a new heap tuple, keeping indexes
158  * current. Avoid using it for multiple tuples, since opening the indexes
159  * and building the index info structures is moderately expensive.
160  * (Use CatalogTupleInsertWithInfo in such cases.)
161  */
162 Oid
164 {
165  CatalogIndexState indstate;
166  Oid oid;
167 
168  indstate = CatalogOpenIndexes(heapRel);
169 
170  oid = simple_heap_insert(heapRel, tup);
171 
172  CatalogIndexInsert(indstate, tup);
173  CatalogCloseIndexes(indstate);
174 
175  return oid;
176 }
177 
178 /*
179  * CatalogTupleInsertWithInfo - as above, but with caller-supplied index info
180  *
181  * This should be used when it's important to amortize CatalogOpenIndexes/
182  * CatalogCloseIndexes work across multiple insertions. At some point we
183  * might cache the CatalogIndexState data somewhere (perhaps in the relcache)
184  * so that callers needn't trouble over this ... but we don't do so today.
185  */
186 Oid
188  CatalogIndexState indstate)
189 {
190  Oid oid;
191 
192  oid = simple_heap_insert(heapRel, tup);
193 
194  CatalogIndexInsert(indstate, tup);
195 
196  return oid;
197 }
198 
199 /*
200  * CatalogTupleUpdate - do heap and indexing work for updating a catalog tuple
201  *
202  * Update the tuple identified by "otid", replacing it with the data in "tup".
203  *
204  * This is a convenience routine for the common case of updating a single
205  * tuple in a system catalog; it updates one heap tuple, keeping indexes
206  * current. Avoid using it for multiple tuples, since opening the indexes
207  * and building the index info structures is moderately expensive.
208  * (Use CatalogTupleUpdateWithInfo in such cases.)
209  */
210 void
212 {
213  CatalogIndexState indstate;
214 
215  indstate = CatalogOpenIndexes(heapRel);
216 
217  simple_heap_update(heapRel, otid, tup);
218 
219  CatalogIndexInsert(indstate, tup);
220  CatalogCloseIndexes(indstate);
221 }
222 
223 /*
224  * CatalogTupleUpdateWithInfo - as above, but with caller-supplied index info
225  *
226  * This should be used when it's important to amortize CatalogOpenIndexes/
227  * CatalogCloseIndexes work across multiple updates. At some point we
228  * might cache the CatalogIndexState data somewhere (perhaps in the relcache)
229  * so that callers needn't trouble over this ... but we don't do so today.
230  */
231 void
233  CatalogIndexState indstate)
234 {
235  simple_heap_update(heapRel, otid, tup);
236 
237  CatalogIndexInsert(indstate, tup);
238 }
239 
240 /*
241  * CatalogTupleDelete - do heap and indexing work for deleting a catalog tuple
242  *
243  * Delete the tuple identified by "tid" in the specified catalog.
244  *
245  * With Postgres heaps, there is no index work to do at deletion time;
246  * cleanup will be done later by VACUUM. However, callers of this function
247  * shouldn't have to know that; we'd like a uniform abstraction for all
248  * catalog tuple changes. Hence, provide this currently-trivial wrapper.
249  *
250  * The abstraction is a bit leaky in that we don't provide an optimized
251  * CatalogTupleDeleteWithInfo version, because there is currently nothing to
252  * optimize. If we ever need that, rather than touching a lot of call sites,
253  * it might be better to do something about caching CatalogIndexState.
254  */
255 void
257 {
258  simple_heap_delete(heapRel, tid);
259 }
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: index.c:2000
int ri_NumIndices
Definition: execnodes.h:400
#define NIL
Definition: pg_list.h:69
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
Definition: execTuples.c:356
Relation ri_RelationDesc
Definition: execnodes.h:397
List * ii_Predicate
Definition: execnodes.h:156
#define RelationGetDescr(relation)
Definition: rel.h:433
#define InvalidBuffer
Definition: buf.h:25
static void CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
Definition: indexing.c:72
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:256
unsigned int Oid
Definition: postgres_ext.h:31
Index ri_RangeTableIndex
Definition: execnodes.h:394
void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
Definition: execIndexing.c:149
Form_pg_index rd_index
Definition: rel.h:131
void pfree(void *pointer)
Definition: mcxt.c:1031
int ii_NumIndexKeyAttrs
Definition: execnodes.h:152
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:163
ItemPointerData t_self
Definition: htup.h:65
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:247
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:232
bool ii_ReadyForInserts
Definition: execnodes.h:165
TriggerDesc * ri_TrigDesc
Definition: execnodes.h:409
void CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:232
uintptr_t Datum
Definition: postgres.h:367
Oid simple_heap_insert(Relation relation, HeapTuple tup)
Definition: heapam.c:2986
#define makeNode(_type_)
Definition: nodes.h:565
List * ii_Expressions
Definition: execnodes.h:154
#define HeapTupleIsHeapOnly(tuple)
Definition: htup_details.h:698
#define Assert(condition)
Definition: c.h:699
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:40
#define INDEX_MAX_KEYS
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:211
void simple_heap_delete(Relation relation, ItemPointer tid)
Definition: heapam.c:3455
void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup)
Definition: heapam.c:4599
static Datum values[MAXATTR]
Definition: bootstrap.c:164
Oid * ii_ExclusionOps
Definition: execnodes.h:158
IndexInfo ** ri_IndexRelationInfo
Definition: execnodes.h:406
int i
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:58
Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:187
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:224
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:403
bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique, IndexInfo *indexInfo)
Definition: indexam.c:194