PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2017, 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 
123  /*
124  * FormIndexDatum fills in its values and isnull parameters with the
125  * appropriate values for the column(s) of the index.
126  */
127  FormIndexDatum(indexInfo,
128  slot,
129  NULL, /* no expression eval to do */
130  values,
131  isnull);
132 
133  /*
134  * The index AM does the rest.
135  */
136  index_insert(relationDescs[i], /* index relation */
137  values, /* array of index Datums */
138  isnull, /* is-null flags */
139  &(heapTuple->t_self), /* tid of heap tuple */
140  heapRelation,
141  relationDescs[i]->rd_index->indisunique ?
143  indexInfo);
144  }
145 
147 }
148 
149 /*
150  * CatalogTupleInsert - do heap and indexing work for a new catalog tuple
151  *
152  * Insert the tuple data in "tup" into the specified catalog relation.
153  * The Oid of the inserted tuple is returned.
154  *
155  * This is a convenience routine for the common case of inserting a single
156  * tuple in a system catalog; it inserts a new heap tuple, keeping indexes
157  * current. Avoid using it for multiple tuples, since opening the indexes
158  * and building the index info structures is moderately expensive.
159  * (Use CatalogTupleInsertWithInfo in such cases.)
160  */
161 Oid
163 {
164  CatalogIndexState indstate;
165  Oid oid;
166 
167  indstate = CatalogOpenIndexes(heapRel);
168 
169  oid = simple_heap_insert(heapRel, tup);
170 
171  CatalogIndexInsert(indstate, tup);
172  CatalogCloseIndexes(indstate);
173 
174  return oid;
175 }
176 
177 /*
178  * CatalogTupleInsertWithInfo - as above, but with caller-supplied index info
179  *
180  * This should be used when it's important to amortize CatalogOpenIndexes/
181  * CatalogCloseIndexes work across multiple insertions. At some point we
182  * might cache the CatalogIndexState data somewhere (perhaps in the relcache)
183  * so that callers needn't trouble over this ... but we don't do so today.
184  */
185 Oid
187  CatalogIndexState indstate)
188 {
189  Oid oid;
190 
191  oid = simple_heap_insert(heapRel, tup);
192 
193  CatalogIndexInsert(indstate, tup);
194 
195  return oid;
196 }
197 
198 /*
199  * CatalogTupleUpdate - do heap and indexing work for updating a catalog tuple
200  *
201  * Update the tuple identified by "otid", replacing it with the data in "tup".
202  *
203  * This is a convenience routine for the common case of updating a single
204  * tuple in a system catalog; it updates one heap tuple, keeping indexes
205  * current. Avoid using it for multiple tuples, since opening the indexes
206  * and building the index info structures is moderately expensive.
207  * (Use CatalogTupleUpdateWithInfo in such cases.)
208  */
209 void
211 {
212  CatalogIndexState indstate;
213 
214  indstate = CatalogOpenIndexes(heapRel);
215 
216  simple_heap_update(heapRel, otid, tup);
217 
218  CatalogIndexInsert(indstate, tup);
219  CatalogCloseIndexes(indstate);
220 }
221 
222 /*
223  * CatalogTupleUpdateWithInfo - as above, but with caller-supplied index info
224  *
225  * This should be used when it's important to amortize CatalogOpenIndexes/
226  * CatalogCloseIndexes work across multiple updates. At some point we
227  * might cache the CatalogIndexState data somewhere (perhaps in the relcache)
228  * so that callers needn't trouble over this ... but we don't do so today.
229  */
230 void
232  CatalogIndexState indstate)
233 {
234  simple_heap_update(heapRel, otid, tup);
235 
236  CatalogIndexInsert(indstate, tup);
237 }
238 
239 /*
240  * CatalogTupleDelete - do heap and indexing work for deleting a catalog tuple
241  *
242  * Delete the tuple identified by "tid" in the specified catalog.
243  *
244  * With Postgres heaps, there is no index work to do at deletion time;
245  * cleanup will be done later by VACUUM. However, callers of this function
246  * shouldn't have to know that; we'd like a uniform abstraction for all
247  * catalog tuple changes. Hence, provide this currently-trivial wrapper.
248  *
249  * The abstraction is a bit leaky in that we don't provide an optimized
250  * CatalogTupleDeleteWithInfo version, because there is currently nothing to
251  * optimize. If we ever need that, rather than touching a lot of call sites,
252  * it might be better to do something about caching CatalogIndexState.
253  */
254 void
256 {
257  simple_heap_delete(heapRel, tid);
258 }
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: index.c:1765
int ri_NumIndices
Definition: execnodes.h:357
#define NIL
Definition: pg_list.h:69
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
Definition: execTuples.c:320
Relation ri_RelationDesc
Definition: execnodes.h:354
List * ii_Predicate
Definition: execnodes.h:138
#define RelationGetDescr(relation)
Definition: rel.h:428
#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:255
unsigned int Oid
Definition: postgres_ext.h:31
Index ri_RangeTableIndex
Definition: execnodes.h:351
void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
Definition: execIndexing.c:149
Form_pg_index rd_index
Definition: rel.h:159
void pfree(void *pointer)
Definition: mcxt.c:950
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
ItemPointerData t_self
Definition: htup.h:65
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:216
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:199
bool ii_ReadyForInserts
Definition: execnodes.h:147
TriggerDesc * ri_TrigDesc
Definition: execnodes.h:366
void CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:231
uintptr_t Datum
Definition: postgres.h:372
Oid simple_heap_insert(Relation relation, HeapTuple tup)
Definition: heapam.c:2939
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
List * ii_Expressions
Definition: execnodes.h:136
#define HeapTupleIsHeapOnly(tuple)
Definition: htup_details.h:686
#define Assert(condition)
Definition: c.h:675
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:40
#define INDEX_MAX_KEYS
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
void simple_heap_delete(Relation relation, ItemPointer tid)
Definition: heapam.c:3398
void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup)
Definition: heapam.c:4451
static Datum values[MAXATTR]
Definition: bootstrap.c:163
Oid * ii_ExclusionOps
Definition: execnodes.h:140
IndexInfo ** ri_IndexRelationInfo
Definition: execnodes.h:363
int i
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:58
Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:186
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:224
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:360
bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique, IndexInfo *indexInfo)
Definition: indexam.c:194