PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
index.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * index.c
4  * code to create and destroy POSTGRES index relations
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/catalog/index.c
12  *
13  *
14  * INTERFACE ROUTINES
15  * index_create() - Create a cataloged index relation
16  * index_drop() - Removes index relation from catalogs
17  * BuildIndexInfo() - Prepare to insert index tuples
18  * FormIndexDatum() - Construct datum vector for one index tuple
19  *
20  *-------------------------------------------------------------------------
21  */
22 #include "postgres.h"
23 
24 #include <unistd.h>
25 
26 #include "access/amapi.h"
27 #include "access/multixact.h"
28 #include "access/relscan.h"
29 #include "access/sysattr.h"
30 #include "access/transam.h"
31 #include "access/visibilitymap.h"
32 #include "access/xact.h"
33 #include "bootstrap/bootstrap.h"
34 #include "catalog/binary_upgrade.h"
35 #include "catalog/catalog.h"
36 #include "catalog/dependency.h"
37 #include "catalog/heap.h"
38 #include "catalog/index.h"
39 #include "catalog/objectaccess.h"
40 #include "catalog/pg_am.h"
41 #include "catalog/pg_collation.h"
42 #include "catalog/pg_constraint.h"
44 #include "catalog/pg_operator.h"
45 #include "catalog/pg_opclass.h"
46 #include "catalog/pg_tablespace.h"
47 #include "catalog/pg_trigger.h"
48 #include "catalog/pg_type.h"
49 #include "catalog/storage.h"
50 #include "commands/tablecmds.h"
51 #include "commands/trigger.h"
52 #include "executor/executor.h"
53 #include "miscadmin.h"
54 #include "nodes/makefuncs.h"
55 #include "nodes/nodeFuncs.h"
56 #include "optimizer/clauses.h"
57 #include "parser/parser.h"
58 #include "storage/bufmgr.h"
59 #include "storage/lmgr.h"
60 #include "storage/predicate.h"
61 #include "storage/procarray.h"
62 #include "storage/smgr.h"
63 #include "utils/builtins.h"
64 #include "utils/fmgroids.h"
65 #include "utils/guc.h"
66 #include "utils/inval.h"
67 #include "utils/lsyscache.h"
68 #include "utils/memutils.h"
69 #include "utils/pg_rusage.h"
70 #include "utils/syscache.h"
71 #include "utils/tuplesort.h"
72 #include "utils/snapmgr.h"
73 #include "utils/tqual.h"
74 
75 
76 /* Potentially set by pg_upgrade_support functions */
78 
79 /* state info for validate_index bulkdelete callback */
80 typedef struct
81 {
82  Tuplesortstate *tuplesort; /* for sorting the index TIDs */
83  /* statistics (for debug purposes only): */
84  double htups,
85  itups,
87 } v_i_state;
88 
89 /* non-export function prototypes */
90 static bool relationHasPrimaryKey(Relation rel);
91 static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
92  IndexInfo *indexInfo,
93  List *indexColNames,
94  Oid accessMethodObjectId,
95  Oid *collationObjectId,
96  Oid *classObjectId);
97 static void InitializeAttributeOids(Relation indexRelation,
98  int numatts, Oid indexoid);
99 static void AppendAttributeTuples(Relation indexRelation, int numatts);
100 static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
101  IndexInfo *indexInfo,
102  Oid *collationOids,
103  Oid *classOids,
104  int16 *coloptions,
105  bool primary,
106  bool isexclusion,
107  bool immediate,
108  bool isvalid);
109 static void index_update_stats(Relation rel,
110  bool hasindex, bool isprimary,
111  double reltuples);
112 static void IndexCheckExclusion(Relation heapRelation,
113  Relation indexRelation,
114  IndexInfo *indexInfo);
115 static inline int64 itemptr_encode(ItemPointer itemptr);
116 static inline void itemptr_decode(ItemPointer itemptr, int64 encoded);
117 static bool validate_index_callback(ItemPointer itemptr, void *opaque);
118 static void validate_index_heapscan(Relation heapRelation,
119  Relation indexRelation,
120  IndexInfo *indexInfo,
121  Snapshot snapshot,
122  v_i_state *state);
123 static bool ReindexIsCurrentlyProcessingIndex(Oid indexOid);
124 static void SetReindexProcessing(Oid heapOid, Oid indexOid);
125 static void ResetReindexProcessing(void);
126 static void SetReindexPending(List *indexes);
127 static void RemoveReindexPending(Oid indexOid);
128 static void ResetReindexPending(void);
129 
130 
131 /*
132  * relationHasPrimaryKey
133  * See whether an existing relation has a primary key.
134  *
135  * Caller must have suitable lock on the relation.
136  *
137  * Note: we intentionally do not check IndexIsValid here; that's because this
138  * is used to enforce the rule that there can be only one indisprimary index,
139  * and we want that to be true even if said index is invalid.
140  */
141 static bool
143 {
144  bool result = false;
145  List *indexoidlist;
146  ListCell *indexoidscan;
147 
148  /*
149  * Get the list of index OIDs for the table from the relcache, and look up
150  * each one in the pg_index syscache until we find one marked primary key
151  * (hopefully there isn't more than one such).
152  */
153  indexoidlist = RelationGetIndexList(rel);
154 
155  foreach(indexoidscan, indexoidlist)
156  {
157  Oid indexoid = lfirst_oid(indexoidscan);
158  HeapTuple indexTuple;
159 
160  indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
161  if (!HeapTupleIsValid(indexTuple)) /* should not happen */
162  elog(ERROR, "cache lookup failed for index %u", indexoid);
163  result = ((Form_pg_index) GETSTRUCT(indexTuple))->indisprimary;
164  ReleaseSysCache(indexTuple);
165  if (result)
166  break;
167  }
168 
169  list_free(indexoidlist);
170 
171  return result;
172 }
173 
174 /*
175  * index_check_primary_key
176  * Apply special checks needed before creating a PRIMARY KEY index
177  *
178  * This processing used to be in DefineIndex(), but has been split out
179  * so that it can be applied during ALTER TABLE ADD PRIMARY KEY USING INDEX.
180  *
181  * We check for a pre-existing primary key, and that all columns of the index
182  * are simple column references (not expressions), and that all those
183  * columns are marked NOT NULL. If they aren't (which can only happen during
184  * ALTER TABLE ADD CONSTRAINT, since the parser forces such columns to be
185  * created NOT NULL during CREATE TABLE), do an ALTER SET NOT NULL to mark
186  * them so --- or fail if they are not in fact nonnull.
187  *
188  * Caller had better have at least ShareLock on the table, else the not-null
189  * checking isn't trustworthy.
190  */
191 void
193  IndexInfo *indexInfo,
194  bool is_alter_table)
195 {
196  List *cmds;
197  int i;
198 
199  /*
200  * If ALTER TABLE, check that there isn't already a PRIMARY KEY. In CREATE
201  * TABLE, we have faith that the parser rejected multiple pkey clauses;
202  * and CREATE INDEX doesn't have a way to say PRIMARY KEY, so it's no
203  * problem either.
204  */
205  if (is_alter_table &&
206  relationHasPrimaryKey(heapRel))
207  {
208  ereport(ERROR,
209  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
210  errmsg("multiple primary keys for table \"%s\" are not allowed",
211  RelationGetRelationName(heapRel))));
212  }
213 
214  /*
215  * Check that all of the attributes in a primary key are marked as not
216  * null, otherwise attempt to ALTER TABLE .. SET NOT NULL
217  */
218  cmds = NIL;
219  for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
220  {
221  AttrNumber attnum = indexInfo->ii_KeyAttrNumbers[i];
222  HeapTuple atttuple;
223  Form_pg_attribute attform;
224 
225  if (attnum == 0)
226  ereport(ERROR,
227  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
228  errmsg("primary keys cannot be expressions")));
229 
230  /* System attributes are never null, so no need to check */
231  if (attnum < 0)
232  continue;
233 
234  atttuple = SearchSysCache2(ATTNUM,
236  Int16GetDatum(attnum));
237  if (!HeapTupleIsValid(atttuple))
238  elog(ERROR, "cache lookup failed for attribute %d of relation %u",
239  attnum, RelationGetRelid(heapRel));
240  attform = (Form_pg_attribute) GETSTRUCT(atttuple);
241 
242  if (!attform->attnotnull)
243  {
244  /* Add a subcommand to make this one NOT NULL */
246 
247  cmd->subtype = AT_SetNotNull;
248  cmd->name = pstrdup(NameStr(attform->attname));
249  cmds = lappend(cmds, cmd);
250  }
251 
252  ReleaseSysCache(atttuple);
253  }
254 
255  /*
256  * XXX: Shouldn't the ALTER TABLE .. SET NOT NULL cascade to child tables?
257  * Currently, since the PRIMARY KEY itself doesn't cascade, we don't
258  * cascade the notnull constraint(s) either; but this is pretty debatable.
259  *
260  * XXX: possible future improvement: when being called from ALTER TABLE,
261  * it would be more efficient to merge this with the outer ALTER TABLE, so
262  * as to avoid two scans. But that seems to complicate DefineIndex's API
263  * unduly.
264  */
265  if (cmds)
266  AlterTableInternal(RelationGetRelid(heapRel), cmds, false);
267 }
268 
269 /*
270  * ConstructTupleDescriptor
271  *
272  * Build an index tuple descriptor for a new index
273  */
274 static TupleDesc
276  IndexInfo *indexInfo,
277  List *indexColNames,
278  Oid accessMethodObjectId,
279  Oid *collationObjectId,
280  Oid *classObjectId)
281 {
282  int numatts = indexInfo->ii_NumIndexAttrs;
283  ListCell *colnames_item = list_head(indexColNames);
284  ListCell *indexpr_item = list_head(indexInfo->ii_Expressions);
285  IndexAmRoutine *amroutine;
286  TupleDesc heapTupDesc;
287  TupleDesc indexTupDesc;
288  int natts; /* #atts in heap rel --- for error checks */
289  int i;
290 
291  /* We need access to the index AM's API struct */
292  amroutine = GetIndexAmRoutineByAmId(accessMethodObjectId, false);
293 
294  /* ... and to the table's tuple descriptor */
295  heapTupDesc = RelationGetDescr(heapRelation);
296  natts = RelationGetForm(heapRelation)->relnatts;
297 
298  /*
299  * allocate the new tuple descriptor
300  */
301  indexTupDesc = CreateTemplateTupleDesc(numatts, false);
302 
303  /*
304  * For simple index columns, we copy the pg_attribute row from the parent
305  * relation and modify it as necessary. For expressions we have to cons
306  * up a pg_attribute row the hard way.
307  */
308  for (i = 0; i < numatts; i++)
309  {
310  AttrNumber atnum = indexInfo->ii_KeyAttrNumbers[i];
311  Form_pg_attribute to = indexTupDesc->attrs[i];
312  HeapTuple tuple;
313  Form_pg_type typeTup;
314  Form_pg_opclass opclassTup;
315  Oid keyType;
316 
317  if (atnum != 0)
318  {
319  /* Simple index column */
320  Form_pg_attribute from;
321 
322  if (atnum < 0)
323  {
324  /*
325  * here we are indexing on a system attribute (-1...-n)
326  */
327  from = SystemAttributeDefinition(atnum,
328  heapRelation->rd_rel->relhasoids);
329  }
330  else
331  {
332  /*
333  * here we are indexing on a normal attribute (1...n)
334  */
335  if (atnum > natts) /* safety check */
336  elog(ERROR, "invalid column number %d", atnum);
337  from = heapTupDesc->attrs[AttrNumberGetAttrOffset(atnum)];
338  }
339 
340  /*
341  * now that we've determined the "from", let's copy the tuple desc
342  * data...
343  */
344  memcpy(to, from, ATTRIBUTE_FIXED_PART_SIZE);
345 
346  /*
347  * Fix the stuff that should not be the same as the underlying
348  * attr
349  */
350  to->attnum = i + 1;
351 
352  to->attstattarget = -1;
353  to->attcacheoff = -1;
354  to->attnotnull = false;
355  to->atthasdef = false;
356  to->attislocal = true;
357  to->attinhcount = 0;
358  to->attcollation = collationObjectId[i];
359  }
360  else
361  {
362  /* Expressional index */
363  Node *indexkey;
364 
366 
367  if (indexpr_item == NULL) /* shouldn't happen */
368  elog(ERROR, "too few entries in indexprs list");
369  indexkey = (Node *) lfirst(indexpr_item);
370  indexpr_item = lnext(indexpr_item);
371 
372  /*
373  * Lookup the expression type in pg_type for the type length etc.
374  */
375  keyType = exprType(indexkey);
376  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(keyType));
377  if (!HeapTupleIsValid(tuple))
378  elog(ERROR, "cache lookup failed for type %u", keyType);
379  typeTup = (Form_pg_type) GETSTRUCT(tuple);
380 
381  /*
382  * Assign some of the attributes values. Leave the rest as 0.
383  */
384  to->attnum = i + 1;
385  to->atttypid = keyType;
386  to->attlen = typeTup->typlen;
387  to->attbyval = typeTup->typbyval;
388  to->attstorage = typeTup->typstorage;
389  to->attalign = typeTup->typalign;
390  to->attstattarget = -1;
391  to->attcacheoff = -1;
392  to->atttypmod = exprTypmod(indexkey);
393  to->attislocal = true;
394  to->attcollation = collationObjectId[i];
395 
396  ReleaseSysCache(tuple);
397 
398  /*
399  * Make sure the expression yields a type that's safe to store in
400  * an index. We need this defense because we have index opclasses
401  * for pseudo-types such as "record", and the actually stored type
402  * had better be safe; eg, a named composite type is okay, an
403  * anonymous record type is not. The test is the same as for
404  * whether a table column is of a safe type (which is why we
405  * needn't check for the non-expression case).
406  */
407  CheckAttributeType(NameStr(to->attname),
408  to->atttypid, to->attcollation,
409  NIL, false);
410  }
411 
412  /*
413  * We do not yet have the correct relation OID for the index, so just
414  * set it invalid for now. InitializeAttributeOids() will fix it
415  * later.
416  */
417  to->attrelid = InvalidOid;
418 
419  /*
420  * Set the attribute name as specified by caller.
421  */
422  if (colnames_item == NULL) /* shouldn't happen */
423  elog(ERROR, "too few entries in colnames list");
424  namestrcpy(&to->attname, (const char *) lfirst(colnames_item));
425  colnames_item = lnext(colnames_item);
426 
427  /*
428  * Check the opclass and index AM to see if either provides a keytype
429  * (overriding the attribute type). Opclass takes precedence.
430  */
431  tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(classObjectId[i]));
432  if (!HeapTupleIsValid(tuple))
433  elog(ERROR, "cache lookup failed for opclass %u",
434  classObjectId[i]);
435  opclassTup = (Form_pg_opclass) GETSTRUCT(tuple);
436  if (OidIsValid(opclassTup->opckeytype))
437  keyType = opclassTup->opckeytype;
438  else
439  keyType = amroutine->amkeytype;
440 
441  /*
442  * If keytype is specified as ANYELEMENT, and opcintype is ANYARRAY,
443  * then the attribute type must be an array (else it'd not have
444  * matched this opclass); use its element type.
445  */
446  if (keyType == ANYELEMENTOID && opclassTup->opcintype == ANYARRAYOID)
447  {
448  keyType = get_base_element_type(to->atttypid);
449  if (!OidIsValid(keyType))
450  elog(ERROR, "could not get element type of array type %u",
451  to->atttypid);
452  }
453 
454  ReleaseSysCache(tuple);
455 
456  /*
457  * If a key type different from the heap value is specified, update
458  * the type-related fields in the index tupdesc.
459  */
460  if (OidIsValid(keyType) && keyType != to->atttypid)
461  {
462  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(keyType));
463  if (!HeapTupleIsValid(tuple))
464  elog(ERROR, "cache lookup failed for type %u", keyType);
465  typeTup = (Form_pg_type) GETSTRUCT(tuple);
466 
467  to->atttypid = keyType;
468  to->atttypmod = -1;
469  to->attlen = typeTup->typlen;
470  to->attbyval = typeTup->typbyval;
471  to->attalign = typeTup->typalign;
472  to->attstorage = typeTup->typstorage;
473 
474  ReleaseSysCache(tuple);
475  }
476  }
477 
478  pfree(amroutine);
479 
480  return indexTupDesc;
481 }
482 
483 /* ----------------------------------------------------------------
484  * InitializeAttributeOids
485  * ----------------------------------------------------------------
486  */
487 static void
489  int numatts,
490  Oid indexoid)
491 {
492  TupleDesc tupleDescriptor;
493  int i;
494 
495  tupleDescriptor = RelationGetDescr(indexRelation);
496 
497  for (i = 0; i < numatts; i += 1)
498  tupleDescriptor->attrs[i]->attrelid = indexoid;
499 }
500 
501 /* ----------------------------------------------------------------
502  * AppendAttributeTuples
503  * ----------------------------------------------------------------
504  */
505 static void
506 AppendAttributeTuples(Relation indexRelation, int numatts)
507 {
508  Relation pg_attribute;
509  CatalogIndexState indstate;
510  TupleDesc indexTupDesc;
511  int i;
512 
513  /*
514  * open the attribute relation and its indexes
515  */
517 
518  indstate = CatalogOpenIndexes(pg_attribute);
519 
520  /*
521  * insert data from new index's tupdesc into pg_attribute
522  */
523  indexTupDesc = RelationGetDescr(indexRelation);
524 
525  for (i = 0; i < numatts; i++)
526  {
527  /*
528  * There used to be very grotty code here to set these fields, but I
529  * think it's unnecessary. They should be set already.
530  */
531  Assert(indexTupDesc->attrs[i]->attnum == i + 1);
532  Assert(indexTupDesc->attrs[i]->attcacheoff == -1);
533 
534  InsertPgAttributeTuple(pg_attribute, indexTupDesc->attrs[i], indstate);
535  }
536 
537  CatalogCloseIndexes(indstate);
538 
539  heap_close(pg_attribute, RowExclusiveLock);
540 }
541 
542 /* ----------------------------------------------------------------
543  * UpdateIndexRelation
544  *
545  * Construct and insert a new entry in the pg_index catalog
546  * ----------------------------------------------------------------
547  */
548 static void
550  Oid heapoid,
551  IndexInfo *indexInfo,
552  Oid *collationOids,
553  Oid *classOids,
554  int16 *coloptions,
555  bool primary,
556  bool isexclusion,
557  bool immediate,
558  bool isvalid)
559 {
560  int2vector *indkey;
561  oidvector *indcollation;
562  oidvector *indclass;
563  int2vector *indoption;
564  Datum exprsDatum;
565  Datum predDatum;
567  bool nulls[Natts_pg_index];
568  Relation pg_index;
569  HeapTuple tuple;
570  int i;
571 
572  /*
573  * Copy the index key, opclass, and indoption info into arrays (should we
574  * make the caller pass them like this to start with?)
575  */
576  indkey = buildint2vector(NULL, indexInfo->ii_NumIndexAttrs);
577  for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
578  indkey->values[i] = indexInfo->ii_KeyAttrNumbers[i];
579  indcollation = buildoidvector(collationOids, indexInfo->ii_NumIndexAttrs);
580  indclass = buildoidvector(classOids, indexInfo->ii_NumIndexAttrs);
581  indoption = buildint2vector(coloptions, indexInfo->ii_NumIndexAttrs);
582 
583  /*
584  * Convert the index expressions (if any) to a text datum
585  */
586  if (indexInfo->ii_Expressions != NIL)
587  {
588  char *exprsString;
589 
590  exprsString = nodeToString(indexInfo->ii_Expressions);
591  exprsDatum = CStringGetTextDatum(exprsString);
592  pfree(exprsString);
593  }
594  else
595  exprsDatum = (Datum) 0;
596 
597  /*
598  * Convert the index predicate (if any) to a text datum. Note we convert
599  * implicit-AND format to normal explicit-AND for storage.
600  */
601  if (indexInfo->ii_Predicate != NIL)
602  {
603  char *predString;
604 
605  predString = nodeToString(make_ands_explicit(indexInfo->ii_Predicate));
606  predDatum = CStringGetTextDatum(predString);
607  pfree(predString);
608  }
609  else
610  predDatum = (Datum) 0;
611 
612  /*
613  * open the system catalog index relation
614  */
616 
617  /*
618  * Build a pg_index tuple
619  */
620  MemSet(nulls, false, sizeof(nulls));
621 
622  values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
623  values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
624  values[Anum_pg_index_indnatts - 1] = Int16GetDatum(indexInfo->ii_NumIndexAttrs);
625  values[Anum_pg_index_indisunique - 1] = BoolGetDatum(indexInfo->ii_Unique);
626  values[Anum_pg_index_indisprimary - 1] = BoolGetDatum(primary);
627  values[Anum_pg_index_indisexclusion - 1] = BoolGetDatum(isexclusion);
628  values[Anum_pg_index_indimmediate - 1] = BoolGetDatum(immediate);
629  values[Anum_pg_index_indisclustered - 1] = BoolGetDatum(false);
630  values[Anum_pg_index_indisvalid - 1] = BoolGetDatum(isvalid);
631  values[Anum_pg_index_indcheckxmin - 1] = BoolGetDatum(false);
632  /* we set isvalid and isready the same way */
633  values[Anum_pg_index_indisready - 1] = BoolGetDatum(isvalid);
634  values[Anum_pg_index_indislive - 1] = BoolGetDatum(true);
635  values[Anum_pg_index_indisreplident - 1] = BoolGetDatum(false);
636  values[Anum_pg_index_indkey - 1] = PointerGetDatum(indkey);
637  values[Anum_pg_index_indcollation - 1] = PointerGetDatum(indcollation);
638  values[Anum_pg_index_indclass - 1] = PointerGetDatum(indclass);
639  values[Anum_pg_index_indoption - 1] = PointerGetDatum(indoption);
640  values[Anum_pg_index_indexprs - 1] = exprsDatum;
641  if (exprsDatum == (Datum) 0)
642  nulls[Anum_pg_index_indexprs - 1] = true;
643  values[Anum_pg_index_indpred - 1] = predDatum;
644  if (predDatum == (Datum) 0)
645  nulls[Anum_pg_index_indpred - 1] = true;
646 
647  tuple = heap_form_tuple(RelationGetDescr(pg_index), values, nulls);
648 
649  /*
650  * insert the tuple into the pg_index catalog
651  */
652  CatalogTupleInsert(pg_index, tuple);
653 
654  /*
655  * close the relation and free the tuple
656  */
657  heap_close(pg_index, RowExclusiveLock);
658  heap_freetuple(tuple);
659 }
660 
661 
662 /*
663  * index_create
664  *
665  * heapRelation: table to build index on (suitably locked by caller)
666  * indexRelationName: what it say
667  * indexRelationId: normally, pass InvalidOid to let this routine
668  * generate an OID for the index. During bootstrap this may be
669  * nonzero to specify a preselected OID.
670  * relFileNode: normally, pass InvalidOid to get new storage. May be
671  * nonzero to attach an existing valid build.
672  * indexInfo: same info executor uses to insert into the index
673  * indexColNames: column names to use for index (List of char *)
674  * accessMethodObjectId: OID of index AM to use
675  * tableSpaceId: OID of tablespace to use
676  * collationObjectId: array of collation OIDs, one per index column
677  * classObjectId: array of index opclass OIDs, one per index column
678  * coloptions: array of per-index-column indoption settings
679  * reloptions: AM-specific options
680  * isprimary: index is a PRIMARY KEY
681  * isconstraint: index is owned by PRIMARY KEY, UNIQUE, or EXCLUSION constraint
682  * deferrable: constraint is DEFERRABLE
683  * initdeferred: constraint is INITIALLY DEFERRED
684  * allow_system_table_mods: allow table to be a system catalog
685  * skip_build: true to skip the index_build() step for the moment; caller
686  * must do it later (typically via reindex_index())
687  * concurrent: if true, do not lock the table against writers. The index
688  * will be marked "invalid" and the caller must take additional steps
689  * to fix it up.
690  * is_internal: if true, post creation hook for new index
691  * if_not_exists: if true, do not throw an error if a relation with
692  * the same name already exists.
693  *
694  * Returns the OID of the created index.
695  */
696 Oid
697 index_create(Relation heapRelation,
698  const char *indexRelationName,
699  Oid indexRelationId,
700  Oid relFileNode,
701  IndexInfo *indexInfo,
702  List *indexColNames,
703  Oid accessMethodObjectId,
704  Oid tableSpaceId,
705  Oid *collationObjectId,
706  Oid *classObjectId,
707  int16 *coloptions,
708  Datum reloptions,
709  bool isprimary,
710  bool isconstraint,
711  bool deferrable,
712  bool initdeferred,
713  bool allow_system_table_mods,
714  bool skip_build,
715  bool concurrent,
716  bool is_internal,
717  bool if_not_exists)
718 {
719  Oid heapRelationId = RelationGetRelid(heapRelation);
720  Relation pg_class;
721  Relation indexRelation;
722  TupleDesc indexTupDesc;
723  bool shared_relation;
724  bool mapped_relation;
725  bool is_exclusion;
726  Oid namespaceId;
727  int i;
728  char relpersistence;
729 
730  is_exclusion = (indexInfo->ii_ExclusionOps != NULL);
731 
733 
734  /*
735  * The index will be in the same namespace as its parent table, and is
736  * shared across databases if and only if the parent is. Likewise, it
737  * will use the relfilenode map if and only if the parent does; and it
738  * inherits the parent's relpersistence.
739  */
740  namespaceId = RelationGetNamespace(heapRelation);
741  shared_relation = heapRelation->rd_rel->relisshared;
742  mapped_relation = RelationIsMapped(heapRelation);
743  relpersistence = heapRelation->rd_rel->relpersistence;
744 
745  /*
746  * check parameters
747  */
748  if (indexInfo->ii_NumIndexAttrs < 1)
749  elog(ERROR, "must index at least one column");
750 
751  if (!allow_system_table_mods &&
752  IsSystemRelation(heapRelation) &&
754  ereport(ERROR,
755  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
756  errmsg("user-defined indexes on system catalog tables are not supported")));
757 
758  /*
759  * concurrent index build on a system catalog is unsafe because we tend to
760  * release locks before committing in catalogs
761  */
762  if (concurrent &&
763  IsSystemRelation(heapRelation))
764  ereport(ERROR,
765  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
766  errmsg("concurrent index creation on system catalog tables is not supported")));
767 
768  /*
769  * This case is currently not supported, but there's no way to ask for it
770  * in the grammar anyway, so it can't happen.
771  */
772  if (concurrent && is_exclusion)
773  ereport(ERROR,
774  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
775  errmsg_internal("concurrent index creation for exclusion constraints is not supported")));
776 
777  /*
778  * We cannot allow indexing a shared relation after initdb (because
779  * there's no way to make the entry in other databases' pg_class).
780  */
781  if (shared_relation && !IsBootstrapProcessingMode())
782  ereport(ERROR,
783  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
784  errmsg("shared indexes cannot be created after initdb")));
785 
786  /*
787  * Shared relations must be in pg_global, too (last-ditch check)
788  */
789  if (shared_relation && tableSpaceId != GLOBALTABLESPACE_OID)
790  elog(ERROR, "shared relations must be placed in pg_global tablespace");
791 
792  if (get_relname_relid(indexRelationName, namespaceId))
793  {
794  if (if_not_exists)
795  {
796  ereport(NOTICE,
797  (errcode(ERRCODE_DUPLICATE_TABLE),
798  errmsg("relation \"%s\" already exists, skipping",
799  indexRelationName)));
800  heap_close(pg_class, RowExclusiveLock);
801  return InvalidOid;
802  }
803 
804  ereport(ERROR,
805  (errcode(ERRCODE_DUPLICATE_TABLE),
806  errmsg("relation \"%s\" already exists",
807  indexRelationName)));
808  }
809 
810  /*
811  * construct tuple descriptor for index tuples
812  */
813  indexTupDesc = ConstructTupleDescriptor(heapRelation,
814  indexInfo,
815  indexColNames,
816  accessMethodObjectId,
817  collationObjectId,
818  classObjectId);
819 
820  /*
821  * Allocate an OID for the index, unless we were told what to use.
822  *
823  * The OID will be the relfilenode as well, so make sure it doesn't
824  * collide with either pg_class OIDs or existing physical files.
825  */
826  if (!OidIsValid(indexRelationId))
827  {
828  /* Use binary-upgrade override for pg_class.oid/relfilenode? */
829  if (IsBinaryUpgrade)
830  {
832  ereport(ERROR,
833  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
834  errmsg("pg_class index OID value not set when in binary upgrade mode")));
835 
836  indexRelationId = binary_upgrade_next_index_pg_class_oid;
838  }
839  else
840  {
841  indexRelationId =
842  GetNewRelFileNode(tableSpaceId, pg_class, relpersistence);
843  }
844  }
845 
846  /*
847  * create the index relation's relcache entry and physical disk file. (If
848  * we fail further down, it's the smgr's responsibility to remove the disk
849  * file again.)
850  */
851  indexRelation = heap_create(indexRelationName,
852  namespaceId,
853  tableSpaceId,
854  indexRelationId,
855  relFileNode,
856  indexTupDesc,
858  relpersistence,
859  shared_relation,
860  mapped_relation,
861  allow_system_table_mods);
862 
863  Assert(indexRelationId == RelationGetRelid(indexRelation));
864 
865  /*
866  * Obtain exclusive lock on it. Although no other backends can see it
867  * until we commit, this prevents deadlock-risk complaints from lock
868  * manager in cases such as CLUSTER.
869  */
870  LockRelation(indexRelation, AccessExclusiveLock);
871 
872  /*
873  * Fill in fields of the index's pg_class entry that are not set correctly
874  * by heap_create.
875  *
876  * XXX should have a cleaner way to create cataloged indexes
877  */
878  indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
879  indexRelation->rd_rel->relam = accessMethodObjectId;
880  indexRelation->rd_rel->relhasoids = false;
881 
882  /*
883  * store index's pg_class entry
884  */
885  InsertPgClassTuple(pg_class, indexRelation,
886  RelationGetRelid(indexRelation),
887  (Datum) 0,
888  reloptions);
889 
890  /* done with pg_class */
891  heap_close(pg_class, RowExclusiveLock);
892 
893  /*
894  * now update the object id's of all the attribute tuple forms in the
895  * index relation's tuple descriptor
896  */
897  InitializeAttributeOids(indexRelation,
898  indexInfo->ii_NumIndexAttrs,
899  indexRelationId);
900 
901  /*
902  * append ATTRIBUTE tuples for the index
903  */
904  AppendAttributeTuples(indexRelation, indexInfo->ii_NumIndexAttrs);
905 
906  /* ----------------
907  * update pg_index
908  * (append INDEX tuple)
909  *
910  * Note that this stows away a representation of "predicate".
911  * (Or, could define a rule to maintain the predicate) --Nels, Feb '92
912  * ----------------
913  */
914  UpdateIndexRelation(indexRelationId, heapRelationId, indexInfo,
915  collationObjectId, classObjectId, coloptions,
916  isprimary, is_exclusion,
917  !deferrable,
918  !concurrent);
919 
920  /*
921  * Register constraint and dependencies for the index.
922  *
923  * If the index is from a CONSTRAINT clause, construct a pg_constraint
924  * entry. The index will be linked to the constraint, which in turn is
925  * linked to the table. If it's not a CONSTRAINT, we need to make a
926  * dependency directly on the table.
927  *
928  * We don't need a dependency on the namespace, because there'll be an
929  * indirect dependency via our parent table.
930  *
931  * During bootstrap we can't register any dependencies, and we don't try
932  * to make a constraint either.
933  */
935  {
936  ObjectAddress myself,
937  referenced;
938 
939  myself.classId = RelationRelationId;
940  myself.objectId = indexRelationId;
941  myself.objectSubId = 0;
942 
943  if (isconstraint)
944  {
945  char constraintType;
946 
947  if (isprimary)
948  constraintType = CONSTRAINT_PRIMARY;
949  else if (indexInfo->ii_Unique)
950  constraintType = CONSTRAINT_UNIQUE;
951  else if (is_exclusion)
952  constraintType = CONSTRAINT_EXCLUSION;
953  else
954  {
955  elog(ERROR, "constraint must be PRIMARY, UNIQUE or EXCLUDE");
956  constraintType = 0; /* keep compiler quiet */
957  }
958 
959  index_constraint_create(heapRelation,
960  indexRelationId,
961  indexInfo,
962  indexRelationName,
963  constraintType,
964  deferrable,
965  initdeferred,
966  false, /* already marked primary */
967  false, /* pg_index entry is OK */
968  false, /* no old dependencies */
969  allow_system_table_mods,
970  is_internal);
971  }
972  else
973  {
974  bool have_simple_col = false;
975 
976  /* Create auto dependencies on simply-referenced columns */
977  for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
978  {
979  if (indexInfo->ii_KeyAttrNumbers[i] != 0)
980  {
981  referenced.classId = RelationRelationId;
982  referenced.objectId = heapRelationId;
983  referenced.objectSubId = indexInfo->ii_KeyAttrNumbers[i];
984 
985  recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
986 
987  have_simple_col = true;
988  }
989  }
990 
991  /*
992  * If there are no simply-referenced columns, give the index an
993  * auto dependency on the whole table. In most cases, this will
994  * be redundant, but it might not be if the index expressions and
995  * predicate contain no Vars or only whole-row Vars.
996  */
997  if (!have_simple_col)
998  {
999  referenced.classId = RelationRelationId;
1000  referenced.objectId = heapRelationId;
1001  referenced.objectSubId = 0;
1002 
1003  recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
1004  }
1005 
1006  /* Non-constraint indexes can't be deferrable */
1007  Assert(!deferrable);
1008  Assert(!initdeferred);
1009  }
1010 
1011  /* Store dependency on collations */
1012  /* The default collation is pinned, so don't bother recording it */
1013  for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
1014  {
1015  if (OidIsValid(collationObjectId[i]) &&
1016  collationObjectId[i] != DEFAULT_COLLATION_OID)
1017  {
1018  referenced.classId = CollationRelationId;
1019  referenced.objectId = collationObjectId[i];
1020  referenced.objectSubId = 0;
1021 
1022  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1023  }
1024  }
1025 
1026  /* Store dependency on operator classes */
1027  for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
1028  {
1029  referenced.classId = OperatorClassRelationId;
1030  referenced.objectId = classObjectId[i];
1031  referenced.objectSubId = 0;
1032 
1033  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1034  }
1035 
1036  /* Store dependencies on anything mentioned in index expressions */
1037  if (indexInfo->ii_Expressions)
1038  {
1040  (Node *) indexInfo->ii_Expressions,
1041  heapRelationId,
1043  DEPENDENCY_AUTO, false);
1044  }
1045 
1046  /* Store dependencies on anything mentioned in predicate */
1047  if (indexInfo->ii_Predicate)
1048  {
1050  (Node *) indexInfo->ii_Predicate,
1051  heapRelationId,
1053  DEPENDENCY_AUTO, false);
1054  }
1055  }
1056  else
1057  {
1058  /* Bootstrap mode - assert we weren't asked for constraint support */
1059  Assert(!isconstraint);
1060  Assert(!deferrable);
1061  Assert(!initdeferred);
1062  }
1063 
1064  /* Post creation hook for new index */
1066  indexRelationId, 0, is_internal);
1067 
1068  /*
1069  * Advance the command counter so that we can see the newly-entered
1070  * catalog tuples for the index.
1071  */
1073 
1074  /*
1075  * In bootstrap mode, we have to fill in the index strategy structure with
1076  * information from the catalogs. If we aren't bootstrapping, then the
1077  * relcache entry has already been rebuilt thanks to sinval update during
1078  * CommandCounterIncrement.
1079  */
1081  RelationInitIndexAccessInfo(indexRelation);
1082  else
1083  Assert(indexRelation->rd_indexcxt != NULL);
1084 
1085  /*
1086  * If this is bootstrap (initdb) time, then we don't actually fill in the
1087  * index yet. We'll be creating more indexes and classes later, so we
1088  * delay filling them in until just before we're done with bootstrapping.
1089  * Similarly, if the caller specified skip_build then filling the index is
1090  * delayed till later (ALTER TABLE can save work in some cases with this).
1091  * Otherwise, we call the AM routine that constructs the index.
1092  */
1094  {
1095  index_register(heapRelationId, indexRelationId, indexInfo);
1096  }
1097  else if (skip_build)
1098  {
1099  /*
1100  * Caller is responsible for filling the index later on. However,
1101  * we'd better make sure that the heap relation is correctly marked as
1102  * having an index.
1103  */
1104  index_update_stats(heapRelation,
1105  true,
1106  isprimary,
1107  -1.0);
1108  /* Make the above update visible */
1110  }
1111  else
1112  {
1113  index_build(heapRelation, indexRelation, indexInfo, isprimary, false);
1114  }
1115 
1116  /*
1117  * Close the index; but we keep the lock that we acquired above until end
1118  * of transaction. Closing the heap is caller's responsibility.
1119  */
1120  index_close(indexRelation, NoLock);
1121 
1122  return indexRelationId;
1123 }
1124 
1125 /*
1126  * index_constraint_create
1127  *
1128  * Set up a constraint associated with an index. Return the new constraint's
1129  * address.
1130  *
1131  * heapRelation: table owning the index (must be suitably locked by caller)
1132  * indexRelationId: OID of the index
1133  * indexInfo: same info executor uses to insert into the index
1134  * constraintName: what it say (generally, should match name of index)
1135  * constraintType: one of CONSTRAINT_PRIMARY, CONSTRAINT_UNIQUE, or
1136  * CONSTRAINT_EXCLUSION
1137  * deferrable: constraint is DEFERRABLE
1138  * initdeferred: constraint is INITIALLY DEFERRED
1139  * mark_as_primary: if true, set flags to mark index as primary key
1140  * update_pgindex: if true, update pg_index row (else caller's done that)
1141  * remove_old_dependencies: if true, remove existing dependencies of index
1142  * on table's columns
1143  * allow_system_table_mods: allow table to be a system catalog
1144  * is_internal: index is constructed due to internal process
1145  */
1148  Oid indexRelationId,
1149  IndexInfo *indexInfo,
1150  const char *constraintName,
1151  char constraintType,
1152  bool deferrable,
1153  bool initdeferred,
1154  bool mark_as_primary,
1155  bool update_pgindex,
1156  bool remove_old_dependencies,
1157  bool allow_system_table_mods,
1158  bool is_internal)
1159 {
1160  Oid namespaceId = RelationGetNamespace(heapRelation);
1161  ObjectAddress myself,
1162  referenced;
1163  Oid conOid;
1164 
1165  /* constraint creation support doesn't work while bootstrapping */
1167 
1168  /* enforce system-table restriction */
1169  if (!allow_system_table_mods &&
1170  IsSystemRelation(heapRelation) &&
1172  ereport(ERROR,
1173  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1174  errmsg("user-defined indexes on system catalog tables are not supported")));
1175 
1176  /* primary/unique constraints shouldn't have any expressions */
1177  if (indexInfo->ii_Expressions &&
1178  constraintType != CONSTRAINT_EXCLUSION)
1179  elog(ERROR, "constraints cannot have index expressions");
1180 
1181  /*
1182  * If we're manufacturing a constraint for a pre-existing index, we need
1183  * to get rid of the existing auto dependencies for the index (the ones
1184  * that index_create() would have made instead of calling this function).
1185  *
1186  * Note: this code would not necessarily do the right thing if the index
1187  * has any expressions or predicate, but we'd never be turning such an
1188  * index into a UNIQUE or PRIMARY KEY constraint.
1189  */
1190  if (remove_old_dependencies)
1193 
1194  /*
1195  * Construct a pg_constraint entry.
1196  */
1197  conOid = CreateConstraintEntry(constraintName,
1198  namespaceId,
1199  constraintType,
1200  deferrable,
1201  initdeferred,
1202  true,
1203  RelationGetRelid(heapRelation),
1204  indexInfo->ii_KeyAttrNumbers,
1205  indexInfo->ii_NumIndexAttrs,
1206  InvalidOid, /* no domain */
1207  indexRelationId, /* index OID */
1208  InvalidOid, /* no foreign key */
1209  NULL,
1210  NULL,
1211  NULL,
1212  NULL,
1213  0,
1214  ' ',
1215  ' ',
1216  ' ',
1217  indexInfo->ii_ExclusionOps,
1218  NULL, /* no check constraint */
1219  NULL,
1220  NULL,
1221  true, /* islocal */
1222  0, /* inhcount */
1223  true, /* noinherit */
1224  is_internal);
1225 
1226  /*
1227  * Register the index as internally dependent on the constraint.
1228  *
1229  * Note that the constraint has a dependency on the table, so we don't
1230  * need (or want) any direct dependency from the index to the table.
1231  */
1232  myself.classId = RelationRelationId;
1233  myself.objectId = indexRelationId;
1234  myself.objectSubId = 0;
1235 
1236  referenced.classId = ConstraintRelationId;
1237  referenced.objectId = conOid;
1238  referenced.objectSubId = 0;
1239 
1240  recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
1241 
1242  /*
1243  * If the constraint is deferrable, create the deferred uniqueness
1244  * checking trigger. (The trigger will be given an internal dependency on
1245  * the constraint by CreateTrigger.)
1246  */
1247  if (deferrable)
1248  {
1249  CreateTrigStmt *trigger;
1250 
1251  trigger = makeNode(CreateTrigStmt);
1252  trigger->trigname = (constraintType == CONSTRAINT_PRIMARY) ?
1253  "PK_ConstraintTrigger" :
1254  "Unique_ConstraintTrigger";
1255  trigger->relation = NULL;
1256  trigger->funcname = SystemFuncName("unique_key_recheck");
1257  trigger->args = NIL;
1258  trigger->row = true;
1259  trigger->timing = TRIGGER_TYPE_AFTER;
1261  trigger->columns = NIL;
1262  trigger->whenClause = NULL;
1263  trigger->isconstraint = true;
1264  trigger->deferrable = true;
1265  trigger->initdeferred = initdeferred;
1266  trigger->constrrel = NULL;
1267 
1268  (void) CreateTrigger(trigger, NULL, RelationGetRelid(heapRelation),
1269  InvalidOid, conOid, indexRelationId, true);
1270  }
1271 
1272  /*
1273  * If needed, mark the table as having a primary key. We assume it can't
1274  * have been so marked already, so no need to clear the flag in the other
1275  * case.
1276  *
1277  * Note: this might better be done by callers. We do it here to avoid
1278  * exposing index_update_stats() globally, but that wouldn't be necessary
1279  * if relhaspkey went away.
1280  */
1281  if (mark_as_primary)
1282  index_update_stats(heapRelation,
1283  true,
1284  true,
1285  -1.0);
1286 
1287  /*
1288  * If needed, mark the index as primary and/or deferred in pg_index.
1289  *
1290  * Note: When making an existing index into a constraint, caller must have
1291  * a table lock that prevents concurrent table updates; otherwise, there
1292  * is a risk that concurrent readers of the table will miss seeing this
1293  * index at all.
1294  */
1295  if (update_pgindex && (mark_as_primary || deferrable))
1296  {
1297  Relation pg_index;
1298  HeapTuple indexTuple;
1299  Form_pg_index indexForm;
1300  bool dirty = false;
1301 
1303 
1304  indexTuple = SearchSysCacheCopy1(INDEXRELID,
1305  ObjectIdGetDatum(indexRelationId));
1306  if (!HeapTupleIsValid(indexTuple))
1307  elog(ERROR, "cache lookup failed for index %u", indexRelationId);
1308  indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
1309 
1310  if (mark_as_primary && !indexForm->indisprimary)
1311  {
1312  indexForm->indisprimary = true;
1313  dirty = true;
1314  }
1315 
1316  if (deferrable && indexForm->indimmediate)
1317  {
1318  indexForm->indimmediate = false;
1319  dirty = true;
1320  }
1321 
1322  if (dirty)
1323  {
1324  CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple);
1325 
1326  InvokeObjectPostAlterHookArg(IndexRelationId, indexRelationId, 0,
1327  InvalidOid, is_internal);
1328  }
1329 
1330  heap_freetuple(indexTuple);
1331  heap_close(pg_index, RowExclusiveLock);
1332  }
1333 
1334  return referenced;
1335 }
1336 
1337 /*
1338  * index_drop
1339  *
1340  * NOTE: this routine should now only be called through performDeletion(),
1341  * else associated dependencies won't be cleaned up.
1342  */
1343 void
1344 index_drop(Oid indexId, bool concurrent)
1345 {
1346  Oid heapId;
1347  Relation userHeapRelation;
1348  Relation userIndexRelation;
1349  Relation indexRelation;
1350  HeapTuple tuple;
1351  bool hasexprs;
1352  LockRelId heaprelid,
1353  indexrelid;
1354  LOCKTAG heaplocktag;
1355  LOCKMODE lockmode;
1356 
1357  /*
1358  * To drop an index safely, we must grab exclusive lock on its parent
1359  * table. Exclusive lock on the index alone is insufficient because
1360  * another backend might be about to execute a query on the parent table.
1361  * If it relies on a previously cached list of index OIDs, then it could
1362  * attempt to access the just-dropped index. We must therefore take a
1363  * table lock strong enough to prevent all queries on the table from
1364  * proceeding until we commit and send out a shared-cache-inval notice
1365  * that will make them update their index lists.
1366  *
1367  * In the concurrent case we avoid this requirement by disabling index use
1368  * in multiple steps and waiting out any transactions that might be using
1369  * the index, so we don't need exclusive lock on the parent table. Instead
1370  * we take ShareUpdateExclusiveLock, to ensure that two sessions aren't
1371  * doing CREATE/DROP INDEX CONCURRENTLY on the same index. (We will get
1372  * AccessExclusiveLock on the index below, once we're sure nobody else is
1373  * using it.)
1374  */
1375  heapId = IndexGetRelation(indexId, false);
1376  lockmode = concurrent ? ShareUpdateExclusiveLock : AccessExclusiveLock;
1377  userHeapRelation = heap_open(heapId, lockmode);
1378  userIndexRelation = index_open(indexId, lockmode);
1379 
1380  /*
1381  * We might still have open queries using it in our own session, which the
1382  * above locking won't prevent, so test explicitly.
1383  */
1384  CheckTableNotInUse(userIndexRelation, "DROP INDEX");
1385 
1386  /*
1387  * Drop Index Concurrently is more or less the reverse process of Create
1388  * Index Concurrently.
1389  *
1390  * First we unset indisvalid so queries starting afterwards don't use the
1391  * index to answer queries anymore. We have to keep indisready = true so
1392  * transactions that are still scanning the index can continue to see
1393  * valid index contents. For instance, if they are using READ COMMITTED
1394  * mode, and another transaction makes changes and commits, they need to
1395  * see those new tuples in the index.
1396  *
1397  * After all transactions that could possibly have used the index for
1398  * queries end, we can unset indisready and indislive, then wait till
1399  * nobody could be touching it anymore. (Note: we need indislive because
1400  * this state must be distinct from the initial state during CREATE INDEX
1401  * CONCURRENTLY, which has indislive true while indisready and indisvalid
1402  * are false. That's because in that state, transactions must examine the
1403  * index for HOT-safety decisions, while in this state we don't want them
1404  * to open it at all.)
1405  *
1406  * Since all predicate locks on the index are about to be made invalid, we
1407  * must promote them to predicate locks on the heap. In the
1408  * non-concurrent case we can just do that now. In the concurrent case
1409  * it's a bit trickier. The predicate locks must be moved when there are
1410  * no index scans in progress on the index and no more can subsequently
1411  * start, so that no new predicate locks can be made on the index. Also,
1412  * they must be moved before heap inserts stop maintaining the index, else
1413  * the conflict with the predicate lock on the index gap could be missed
1414  * before the lock on the heap relation is in place to detect a conflict
1415  * based on the heap tuple insert.
1416  */
1417  if (concurrent)
1418  {
1419  /*
1420  * We must commit our transaction in order to make the first pg_index
1421  * state update visible to other sessions. If the DROP machinery has
1422  * already performed any other actions (removal of other objects,
1423  * pg_depend entries, etc), the commit would make those actions
1424  * permanent, which would leave us with inconsistent catalog state if
1425  * we fail partway through the following sequence. Since DROP INDEX
1426  * CONCURRENTLY is restricted to dropping just one index that has no
1427  * dependencies, we should get here before anything's been done ---
1428  * but let's check that to be sure. We can verify that the current
1429  * transaction has not executed any transactional updates by checking
1430  * that no XID has been assigned.
1431  */
1433  ereport(ERROR,
1434  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1435  errmsg("DROP INDEX CONCURRENTLY must be first action in transaction")));
1436 
1437  /*
1438  * Mark index invalid by updating its pg_index entry
1439  */
1441 
1442  /*
1443  * Invalidate the relcache for the table, so that after this commit
1444  * all sessions will refresh any cached plans that might reference the
1445  * index.
1446  */
1447  CacheInvalidateRelcache(userHeapRelation);
1448 
1449  /* save lockrelid and locktag for below, then close but keep locks */
1450  heaprelid = userHeapRelation->rd_lockInfo.lockRelId;
1451  SET_LOCKTAG_RELATION(heaplocktag, heaprelid.dbId, heaprelid.relId);
1452  indexrelid = userIndexRelation->rd_lockInfo.lockRelId;
1453 
1454  heap_close(userHeapRelation, NoLock);
1455  index_close(userIndexRelation, NoLock);
1456 
1457  /*
1458  * We must commit our current transaction so that the indisvalid
1459  * update becomes visible to other transactions; then start another.
1460  * Note that any previously-built data structures are lost in the
1461  * commit. The only data we keep past here are the relation IDs.
1462  *
1463  * Before committing, get a session-level lock on the table, to ensure
1464  * that neither it nor the index can be dropped before we finish. This
1465  * cannot block, even if someone else is waiting for access, because
1466  * we already have the same lock within our transaction.
1467  */
1470 
1474 
1475  /*
1476  * Now we must wait until no running transaction could be using the
1477  * index for a query. Use AccessExclusiveLock here to check for
1478  * running transactions that hold locks of any kind on the table. Note
1479  * we do not need to worry about xacts that open the table for reading
1480  * after this point; they will see the index as invalid when they open
1481  * the relation.
1482  *
1483  * Note: the reason we use actual lock acquisition here, rather than
1484  * just checking the ProcArray and sleeping, is that deadlock is
1485  * possible if one of the transactions in question is blocked trying
1486  * to acquire an exclusive lock on our table. The lock code will
1487  * detect deadlock and error out properly.
1488  */
1489  WaitForLockers(heaplocktag, AccessExclusiveLock);
1490 
1491  /*
1492  * No more predicate locks will be acquired on this index, and we're
1493  * about to stop doing inserts into the index which could show
1494  * conflicts with existing predicate locks, so now is the time to move
1495  * them to the heap relation.
1496  */
1497  userHeapRelation = heap_open(heapId, ShareUpdateExclusiveLock);
1498  userIndexRelation = index_open(indexId, ShareUpdateExclusiveLock);
1499  TransferPredicateLocksToHeapRelation(userIndexRelation);
1500 
1501  /*
1502  * Now we are sure that nobody uses the index for queries; they just
1503  * might have it open for updating it. So now we can unset indisready
1504  * and indislive, then wait till nobody could be using it at all
1505  * anymore.
1506  */
1508 
1509  /*
1510  * Invalidate the relcache for the table, so that after this commit
1511  * all sessions will refresh the table's index list. Forgetting just
1512  * the index's relcache entry is not enough.
1513  */
1514  CacheInvalidateRelcache(userHeapRelation);
1515 
1516  /*
1517  * Close the relations again, though still holding session lock.
1518  */
1519  heap_close(userHeapRelation, NoLock);
1520  index_close(userIndexRelation, NoLock);
1521 
1522  /*
1523  * Again, commit the transaction to make the pg_index update visible
1524  * to other sessions.
1525  */
1528 
1529  /*
1530  * Wait till every transaction that saw the old index state has
1531  * finished.
1532  */
1533  WaitForLockers(heaplocktag, AccessExclusiveLock);
1534 
1535  /*
1536  * Re-open relations to allow us to complete our actions.
1537  *
1538  * At this point, nothing should be accessing the index, but lets
1539  * leave nothing to chance and grab AccessExclusiveLock on the index
1540  * before the physical deletion.
1541  */
1542  userHeapRelation = heap_open(heapId, ShareUpdateExclusiveLock);
1543  userIndexRelation = index_open(indexId, AccessExclusiveLock);
1544  }
1545  else
1546  {
1547  /* Not concurrent, so just transfer predicate locks and we're good */
1548  TransferPredicateLocksToHeapRelation(userIndexRelation);
1549  }
1550 
1551  /*
1552  * Schedule physical removal of the files
1553  */
1554  RelationDropStorage(userIndexRelation);
1555 
1556  /*
1557  * Close and flush the index's relcache entry, to ensure relcache doesn't
1558  * try to rebuild it while we're deleting catalog entries. We keep the
1559  * lock though.
1560  */
1561  index_close(userIndexRelation, NoLock);
1562 
1563  RelationForgetRelation(indexId);
1564 
1565  /*
1566  * fix INDEX relation, and check for expressional index
1567  */
1568  indexRelation = heap_open(IndexRelationId, RowExclusiveLock);
1569 
1570  tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexId));
1571  if (!HeapTupleIsValid(tuple))
1572  elog(ERROR, "cache lookup failed for index %u", indexId);
1573 
1574  hasexprs = !heap_attisnull(tuple, Anum_pg_index_indexprs);
1575 
1576  CatalogTupleDelete(indexRelation, &tuple->t_self);
1577 
1578  ReleaseSysCache(tuple);
1579  heap_close(indexRelation, RowExclusiveLock);
1580 
1581  /*
1582  * if it has any expression columns, we might have stored statistics about
1583  * them.
1584  */
1585  if (hasexprs)
1586  RemoveStatistics(indexId, 0);
1587 
1588  /*
1589  * fix ATTRIBUTE relation
1590  */
1591  DeleteAttributeTuples(indexId);
1592 
1593  /*
1594  * fix RELATION relation
1595  */
1596  DeleteRelationTuple(indexId);
1597 
1598  /*
1599  * We are presently too lazy to attempt to compute the new correct value
1600  * of relhasindex (the next VACUUM will fix it if necessary). So there is
1601  * no need to update the pg_class tuple for the owning relation. But we
1602  * must send out a shared-cache-inval notice on the owning relation to
1603  * ensure other backends update their relcache lists of indexes. (In the
1604  * concurrent case, this is redundant but harmless.)
1605  */
1606  CacheInvalidateRelcache(userHeapRelation);
1607 
1608  /*
1609  * Close owning rel, but keep lock
1610  */
1611  heap_close(userHeapRelation, NoLock);
1612 
1613  /*
1614  * Release the session locks before we go.
1615  */
1616  if (concurrent)
1617  {
1620  }
1621 }
1622 
1623 /* ----------------------------------------------------------------
1624  * index_build support
1625  * ----------------------------------------------------------------
1626  */
1627 
1628 /* ----------------
1629  * BuildIndexInfo
1630  * Construct an IndexInfo record for an open index
1631  *
1632  * IndexInfo stores the information about the index that's needed by
1633  * FormIndexDatum, which is used for both index_build() and later insertion
1634  * of individual index tuples. Normally we build an IndexInfo for an index
1635  * just once per command, and then use it for (potentially) many tuples.
1636  * ----------------
1637  */
1638 IndexInfo *
1640 {
1641  IndexInfo *ii = makeNode(IndexInfo);
1642  Form_pg_index indexStruct = index->rd_index;
1643  int i;
1644  int numKeys;
1645 
1646  /* check the number of keys, and copy attr numbers into the IndexInfo */
1647  numKeys = indexStruct->indnatts;
1648  if (numKeys < 1 || numKeys > INDEX_MAX_KEYS)
1649  elog(ERROR, "invalid indnatts %d for index %u",
1650  numKeys, RelationGetRelid(index));
1651  ii->ii_NumIndexAttrs = numKeys;
1652  for (i = 0; i < numKeys; i++)
1653  ii->ii_KeyAttrNumbers[i] = indexStruct->indkey.values[i];
1654 
1655  /* fetch any expressions needed for expressional indexes */
1657  ii->ii_ExpressionsState = NIL;
1658 
1659  /* fetch index predicate if any */
1661  ii->ii_PredicateState = NIL;
1662 
1663  /* fetch exclusion constraint info if any */
1664  if (indexStruct->indisexclusion)
1665  {
1667  &ii->ii_ExclusionOps,
1668  &ii->ii_ExclusionProcs,
1669  &ii->ii_ExclusionStrats);
1670  }
1671  else
1672  {
1673  ii->ii_ExclusionOps = NULL;
1674  ii->ii_ExclusionProcs = NULL;
1675  ii->ii_ExclusionStrats = NULL;
1676  }
1677 
1678  /* other info */
1679  ii->ii_Unique = indexStruct->indisunique;
1680  ii->ii_ReadyForInserts = IndexIsReady(indexStruct);
1681  /* assume not doing speculative insertion for now */
1682  ii->ii_UniqueOps = NULL;
1683  ii->ii_UniqueProcs = NULL;
1684  ii->ii_UniqueStrats = NULL;
1685 
1686  /* initialize index-build state to default */
1687  ii->ii_Concurrent = false;
1688  ii->ii_BrokenHotChain = false;
1689 
1690  /* set up for possible use by index AM */
1691  ii->ii_AmCache = NULL;
1693 
1694  return ii;
1695 }
1696 
1697 /* ----------------
1698  * BuildSpeculativeIndexInfo
1699  * Add extra state to IndexInfo record
1700  *
1701  * For unique indexes, we usually don't want to add info to the IndexInfo for
1702  * checking uniqueness, since the B-Tree AM handles that directly. However,
1703  * in the case of speculative insertion, additional support is required.
1704  *
1705  * Do this processing here rather than in BuildIndexInfo() to not incur the
1706  * overhead in the common non-speculative cases.
1707  * ----------------
1708  */
1709 void
1711 {
1712  int ncols = index->rd_rel->relnatts;
1713  int i;
1714 
1715  /*
1716  * fetch info for checking unique indexes
1717  */
1718  Assert(ii->ii_Unique);
1719 
1720  if (index->rd_rel->relam != BTREE_AM_OID)
1721  elog(ERROR, "unexpected non-btree speculative unique index");
1722 
1723  ii->ii_UniqueOps = (Oid *) palloc(sizeof(Oid) * ncols);
1724  ii->ii_UniqueProcs = (Oid *) palloc(sizeof(Oid) * ncols);
1725  ii->ii_UniqueStrats = (uint16 *) palloc(sizeof(uint16) * ncols);
1726 
1727  /*
1728  * We have to look up the operator's strategy number. This provides a
1729  * cross-check that the operator does match the index.
1730  */
1731  /* We need the func OIDs and strategy numbers too */
1732  for (i = 0; i < ncols; i++)
1733  {
1735  ii->ii_UniqueOps[i] =
1736  get_opfamily_member(index->rd_opfamily[i],
1737  index->rd_opcintype[i],
1738  index->rd_opcintype[i],
1739  ii->ii_UniqueStrats[i]);
1740  ii->ii_UniqueProcs[i] = get_opcode(ii->ii_UniqueOps[i]);
1741  }
1742 }
1743 
1744 /* ----------------
1745  * FormIndexDatum
1746  * Construct values[] and isnull[] arrays for a new index tuple.
1747  *
1748  * indexInfo Info about the index
1749  * slot Heap tuple for which we must prepare an index entry
1750  * estate executor state for evaluating any index expressions
1751  * values Array of index Datums (output area)
1752  * isnull Array of is-null indicators (output area)
1753  *
1754  * When there are no index expressions, estate may be NULL. Otherwise it
1755  * must be supplied, *and* the ecxt_scantuple slot of its per-tuple expr
1756  * context must point to the heap tuple passed in.
1757  *
1758  * Notice we don't actually call index_form_tuple() here; we just prepare
1759  * its input arrays values[] and isnull[]. This is because the index AM
1760  * may wish to alter the data before storage.
1761  * ----------------
1762  */
1763 void
1765  TupleTableSlot *slot,
1766  EState *estate,
1767  Datum *values,
1768  bool *isnull)
1769 {
1770  ListCell *indexpr_item;
1771  int i;
1772 
1773  if (indexInfo->ii_Expressions != NIL &&
1774  indexInfo->ii_ExpressionsState == NIL)
1775  {
1776  /* First time through, set up expression evaluation state */
1777  indexInfo->ii_ExpressionsState = (List *)
1778  ExecPrepareExpr((Expr *) indexInfo->ii_Expressions,
1779  estate);
1780  /* Check caller has set up context correctly */
1781  Assert(GetPerTupleExprContext(estate)->ecxt_scantuple == slot);
1782  }
1783  indexpr_item = list_head(indexInfo->ii_ExpressionsState);
1784 
1785  for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
1786  {
1787  int keycol = indexInfo->ii_KeyAttrNumbers[i];
1788  Datum iDatum;
1789  bool isNull;
1790 
1791  if (keycol != 0)
1792  {
1793  /*
1794  * Plain index column; get the value we need directly from the
1795  * heap tuple.
1796  */
1797  iDatum = slot_getattr(slot, keycol, &isNull);
1798  }
1799  else
1800  {
1801  /*
1802  * Index expression --- need to evaluate it.
1803  */
1804  if (indexpr_item == NULL)
1805  elog(ERROR, "wrong number of index expressions");
1806  iDatum = ExecEvalExprSwitchContext((ExprState *) lfirst(indexpr_item),
1807  GetPerTupleExprContext(estate),
1808  &isNull);
1809  indexpr_item = lnext(indexpr_item);
1810  }
1811  values[i] = iDatum;
1812  isnull[i] = isNull;
1813  }
1814 
1815  if (indexpr_item != NULL)
1816  elog(ERROR, "wrong number of index expressions");
1817 }
1818 
1819 
1820 /*
1821  * index_update_stats --- update pg_class entry after CREATE INDEX or REINDEX
1822  *
1823  * This routine updates the pg_class row of either an index or its parent
1824  * relation after CREATE INDEX or REINDEX. Its rather bizarre API is designed
1825  * to ensure we can do all the necessary work in just one update.
1826  *
1827  * hasindex: set relhasindex to this value
1828  * isprimary: if true, set relhaspkey true; else no change
1829  * reltuples: if >= 0, set reltuples to this value; else no change
1830  *
1831  * If reltuples >= 0, relpages and relallvisible are also updated (using
1832  * RelationGetNumberOfBlocks() and visibilitymap_count()).
1833  *
1834  * NOTE: an important side-effect of this operation is that an SI invalidation
1835  * message is sent out to all backends --- including me --- causing relcache
1836  * entries to be flushed or updated with the new data. This must happen even
1837  * if we find that no change is needed in the pg_class row. When updating
1838  * a heap entry, this ensures that other backends find out about the new
1839  * index. When updating an index, it's important because some index AMs
1840  * expect a relcache flush to occur after REINDEX.
1841  */
1842 static void
1844  bool hasindex,
1845  bool isprimary,
1846  double reltuples)
1847 {
1848  Oid relid = RelationGetRelid(rel);
1849  Relation pg_class;
1850  HeapTuple tuple;
1851  Form_pg_class rd_rel;
1852  bool dirty;
1853 
1854  /*
1855  * We always update the pg_class row using a non-transactional,
1856  * overwrite-in-place update. There are several reasons for this:
1857  *
1858  * 1. In bootstrap mode, we have no choice --- UPDATE wouldn't work.
1859  *
1860  * 2. We could be reindexing pg_class itself, in which case we can't move
1861  * its pg_class row because CatalogUpdateIndexes might not know about all
1862  * the indexes yet (see reindex_relation).
1863  *
1864  * 3. Because we execute CREATE INDEX with just share lock on the parent
1865  * rel (to allow concurrent index creations), an ordinary update could
1866  * suffer a tuple-concurrently-updated failure against another CREATE
1867  * INDEX committing at about the same time. We can avoid that by having
1868  * them both do nontransactional updates (we assume they will both be
1869  * trying to change the pg_class row to the same thing, so it doesn't
1870  * matter which goes first).
1871  *
1872  * It is safe to use a non-transactional update even though our
1873  * transaction could still fail before committing. Setting relhasindex
1874  * true is safe even if there are no indexes (VACUUM will eventually fix
1875  * it), likewise for relhaspkey. And of course the new relpages and
1876  * reltuples counts are correct regardless. However, we don't want to
1877  * change relpages (or relallvisible) if the caller isn't providing an
1878  * updated reltuples count, because that would bollix the
1879  * reltuples/relpages ratio which is what's really important.
1880  */
1881 
1883 
1884  /*
1885  * Make a copy of the tuple to update. Normally we use the syscache, but
1886  * we can't rely on that during bootstrap or while reindexing pg_class
1887  * itself.
1888  */
1889  if (IsBootstrapProcessingMode() ||
1891  {
1892  /* don't assume syscache will work */
1893  HeapScanDesc pg_class_scan;
1894  ScanKeyData key[1];
1895 
1896  ScanKeyInit(&key[0],
1898  BTEqualStrategyNumber, F_OIDEQ,
1899  ObjectIdGetDatum(relid));
1900 
1901  pg_class_scan = heap_beginscan_catalog(pg_class, 1, key);
1902  tuple = heap_getnext(pg_class_scan, ForwardScanDirection);
1903  tuple = heap_copytuple(tuple);
1904  heap_endscan(pg_class_scan);
1905  }
1906  else
1907  {
1908  /* normal case, use syscache */
1909  tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
1910  }
1911 
1912  if (!HeapTupleIsValid(tuple))
1913  elog(ERROR, "could not find tuple for relation %u", relid);
1914  rd_rel = (Form_pg_class) GETSTRUCT(tuple);
1915 
1916  /* Apply required updates, if any, to copied tuple */
1917 
1918  dirty = false;
1919  if (rd_rel->relhasindex != hasindex)
1920  {
1921  rd_rel->relhasindex = hasindex;
1922  dirty = true;
1923  }
1924  if (isprimary)
1925  {
1926  if (!rd_rel->relhaspkey)
1927  {
1928  rd_rel->relhaspkey = true;
1929  dirty = true;
1930  }
1931  }
1932 
1933  if (reltuples >= 0)
1934  {
1935  BlockNumber relpages = RelationGetNumberOfBlocks(rel);
1936  BlockNumber relallvisible;
1937 
1938  if (rd_rel->relkind != RELKIND_INDEX)
1939  visibilitymap_count(rel, &relallvisible, NULL);
1940  else /* don't bother for indexes */
1941  relallvisible = 0;
1942 
1943  if (rd_rel->relpages != (int32) relpages)
1944  {
1945  rd_rel->relpages = (int32) relpages;
1946  dirty = true;
1947  }
1948  if (rd_rel->reltuples != (float4) reltuples)
1949  {
1950  rd_rel->reltuples = (float4) reltuples;
1951  dirty = true;
1952  }
1953  if (rd_rel->relallvisible != (int32) relallvisible)
1954  {
1955  rd_rel->relallvisible = (int32) relallvisible;
1956  dirty = true;
1957  }
1958  }
1959 
1960  /*
1961  * If anything changed, write out the tuple
1962  */
1963  if (dirty)
1964  {
1965  heap_inplace_update(pg_class, tuple);
1966  /* the above sends a cache inval message */
1967  }
1968  else
1969  {
1970  /* no need to change tuple, but force relcache inval anyway */
1972  }
1973 
1974  heap_freetuple(tuple);
1975 
1976  heap_close(pg_class, RowExclusiveLock);
1977 }
1978 
1979 
1980 /*
1981  * index_build - invoke access-method-specific index build procedure
1982  *
1983  * On entry, the index's catalog entries are valid, and its physical disk
1984  * file has been created but is empty. We call the AM-specific build
1985  * procedure to fill in the index contents. We then update the pg_class
1986  * entries of the index and heap relation as needed, using statistics
1987  * returned by ambuild as well as data passed by the caller.
1988  *
1989  * isprimary tells whether to mark the index as a primary-key index.
1990  * isreindex indicates we are recreating a previously-existing index.
1991  *
1992  * Note: when reindexing an existing index, isprimary can be false even if
1993  * the index is a PK; it's already properly marked and need not be re-marked.
1994  *
1995  * Note: before Postgres 8.2, the passed-in heap and index Relations
1996  * were automatically closed by this routine. This is no longer the case.
1997  * The caller opened 'em, and the caller should close 'em.
1998  */
1999 void
2000 index_build(Relation heapRelation,
2001  Relation indexRelation,
2002  IndexInfo *indexInfo,
2003  bool isprimary,
2004  bool isreindex)
2005 {
2006  IndexBuildResult *stats;
2007  Oid save_userid;
2008  int save_sec_context;
2009  int save_nestlevel;
2010 
2011  /*
2012  * sanity checks
2013  */
2014  Assert(RelationIsValid(indexRelation));
2015  Assert(PointerIsValid(indexRelation->rd_amroutine));
2016  Assert(PointerIsValid(indexRelation->rd_amroutine->ambuild));
2017  Assert(PointerIsValid(indexRelation->rd_amroutine->ambuildempty));
2018 
2019  ereport(DEBUG1,
2020  (errmsg("building index \"%s\" on table \"%s\"",
2021  RelationGetRelationName(indexRelation),
2022  RelationGetRelationName(heapRelation))));
2023 
2024  /*
2025  * Switch to the table owner's userid, so that any index functions are run
2026  * as that user. Also lock down security-restricted operations and
2027  * arrange to make GUC variable changes local to this command.
2028  */
2029  GetUserIdAndSecContext(&save_userid, &save_sec_context);
2030  SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
2031  save_sec_context | SECURITY_RESTRICTED_OPERATION);
2032  save_nestlevel = NewGUCNestLevel();
2033 
2034  /*
2035  * Call the access method's build procedure
2036  */
2037  stats = indexRelation->rd_amroutine->ambuild(heapRelation, indexRelation,
2038  indexInfo);
2039  Assert(PointerIsValid(stats));
2040 
2041  /*
2042  * If this is an unlogged index, we may need to write out an init fork for
2043  * it -- but we must first check whether one already exists. If, for
2044  * example, an unlogged relation is truncated in the transaction that
2045  * created it, or truncated twice in a subsequent transaction, the
2046  * relfilenode won't change, and nothing needs to be done here.
2047  */
2048  if (indexRelation->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED &&
2049  !smgrexists(indexRelation->rd_smgr, INIT_FORKNUM))
2050  {
2051  RelationOpenSmgr(indexRelation);
2052  smgrcreate(indexRelation->rd_smgr, INIT_FORKNUM, false);
2053  indexRelation->rd_amroutine->ambuildempty(indexRelation);
2054  }
2055 
2056  /*
2057  * If we found any potentially broken HOT chains, mark the index as not
2058  * being usable until the current transaction is below the event horizon.
2059  * See src/backend/access/heap/README.HOT for discussion. Also set this
2060  * if early pruning/vacuuming is enabled for the heap relation. While it
2061  * might become safe to use the index earlier based on actual cleanup
2062  * activity and other active transactions, the test for that would be much
2063  * more complex and would require some form of blocking, so keep it simple
2064  * and fast by just using the current transaction.
2065  *
2066  * However, when reindexing an existing index, we should do nothing here.
2067  * Any HOT chains that are broken with respect to the index must predate
2068  * the index's original creation, so there is no need to change the
2069  * index's usability horizon. Moreover, we *must not* try to change the
2070  * index's pg_index entry while reindexing pg_index itself, and this
2071  * optimization nicely prevents that. The more complex rules needed for a
2072  * reindex are handled separately after this function returns.
2073  *
2074  * We also need not set indcheckxmin during a concurrent index build,
2075  * because we won't set indisvalid true until all transactions that care
2076  * about the broken HOT chains or early pruning/vacuuming are gone.
2077  *
2078  * Therefore, this code path can only be taken during non-concurrent
2079  * CREATE INDEX. Thus the fact that heap_update will set the pg_index
2080  * tuple's xmin doesn't matter, because that tuple was created in the
2081  * current transaction anyway. That also means we don't need to worry
2082  * about any concurrent readers of the tuple; no other transaction can see
2083  * it yet.
2084  */
2085  if ((indexInfo->ii_BrokenHotChain || EarlyPruningEnabled(heapRelation)) &&
2086  !isreindex &&
2087  !indexInfo->ii_Concurrent)
2088  {
2089  Oid indexId = RelationGetRelid(indexRelation);
2090  Relation pg_index;
2091  HeapTuple indexTuple;
2092  Form_pg_index indexForm;
2093 
2095 
2096  indexTuple = SearchSysCacheCopy1(INDEXRELID,
2097  ObjectIdGetDatum(indexId));
2098  if (!HeapTupleIsValid(indexTuple))
2099  elog(ERROR, "cache lookup failed for index %u", indexId);
2100  indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
2101 
2102  /* If it's a new index, indcheckxmin shouldn't be set ... */
2103  Assert(!indexForm->indcheckxmin);
2104 
2105  indexForm->indcheckxmin = true;
2106  CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple);
2107 
2108  heap_freetuple(indexTuple);
2109  heap_close(pg_index, RowExclusiveLock);
2110  }
2111 
2112  /*
2113  * Update heap and index pg_class rows
2114  */
2115  index_update_stats(heapRelation,
2116  true,
2117  isprimary,
2118  stats->heap_tuples);
2119 
2120  index_update_stats(indexRelation,
2121  false,
2122  false,
2123  stats->index_tuples);
2124 
2125  /* Make the updated catalog row versions visible */
2127 
2128  /*
2129  * If it's for an exclusion constraint, make a second pass over the heap
2130  * to verify that the constraint is satisfied. We must not do this until
2131  * the index is fully valid. (Broken HOT chains shouldn't matter, though;
2132  * see comments for IndexCheckExclusion.)
2133  */
2134  if (indexInfo->ii_ExclusionOps != NULL)
2135  IndexCheckExclusion(heapRelation, indexRelation, indexInfo);
2136 
2137  /* Roll back any GUC changes executed by index functions */
2138  AtEOXact_GUC(false, save_nestlevel);
2139 
2140  /* Restore userid and security context */
2141  SetUserIdAndSecContext(save_userid, save_sec_context);
2142 }
2143 
2144 
2145 /*
2146  * IndexBuildHeapScan - scan the heap relation to find tuples to be indexed
2147  *
2148  * This is called back from an access-method-specific index build procedure
2149  * after the AM has done whatever setup it needs. The parent heap relation
2150  * is scanned to find tuples that should be entered into the index. Each
2151  * such tuple is passed to the AM's callback routine, which does the right
2152  * things to add it to the new index. After we return, the AM's index
2153  * build procedure does whatever cleanup it needs.
2154  *
2155  * The total count of heap tuples is returned. This is for updating pg_class
2156  * statistics. (It's annoying not to be able to do that here, but we want
2157  * to merge that update with others; see index_update_stats.) Note that the
2158  * index AM itself must keep track of the number of index tuples; we don't do
2159  * so here because the AM might reject some of the tuples for its own reasons,
2160  * such as being unable to store NULLs.
2161  *
2162  * A side effect is to set indexInfo->ii_BrokenHotChain to true if we detect
2163  * any potentially broken HOT chains. Currently, we set this if there are
2164  * any RECENTLY_DEAD or DELETE_IN_PROGRESS entries in a HOT chain, without
2165  * trying very hard to detect whether they're really incompatible with the
2166  * chain tip.
2167  */
2168 double
2170  Relation indexRelation,
2171  IndexInfo *indexInfo,
2172  bool allow_sync,
2174  void *callback_state)
2175 {
2176  return IndexBuildHeapRangeScan(heapRelation, indexRelation,
2177  indexInfo, allow_sync,
2178  false,
2179  0, InvalidBlockNumber,
2180  callback, callback_state);
2181 }
2182 
2183 /*
2184  * As above, except that instead of scanning the complete heap, only the given
2185  * number of blocks are scanned. Scan to end-of-rel can be signalled by
2186  * passing InvalidBlockNumber as numblocks. Note that restricting the range
2187  * to scan cannot be done when requesting syncscan.
2188  *
2189  * When "anyvisible" mode is requested, all tuples visible to any transaction
2190  * are considered, including those inserted or deleted by transactions that are
2191  * still in progress.
2192  */
2193 double
2195  Relation indexRelation,
2196  IndexInfo *indexInfo,
2197  bool allow_sync,
2198  bool anyvisible,
2199  BlockNumber start_blockno,
2200  BlockNumber numblocks,
2202  void *callback_state)
2203 {
2204  bool is_system_catalog;
2205  bool checking_uniqueness;
2206  HeapScanDesc scan;
2207  HeapTuple heapTuple;
2209  bool isnull[INDEX_MAX_KEYS];
2210  double reltuples;
2211  List *predicate;
2212  TupleTableSlot *slot;
2213  EState *estate;
2214  ExprContext *econtext;
2215  Snapshot snapshot;
2217  BlockNumber root_blkno = InvalidBlockNumber;
2218  OffsetNumber root_offsets[MaxHeapTuplesPerPage];
2219 
2220  /*
2221  * sanity checks
2222  */
2223  Assert(OidIsValid(indexRelation->rd_rel->relam));
2224 
2225  /* Remember if it's a system catalog */
2226  is_system_catalog = IsSystemRelation(heapRelation);
2227 
2228  /* See whether we're verifying uniqueness/exclusion properties */
2229  checking_uniqueness = (indexInfo->ii_Unique ||
2230  indexInfo->ii_ExclusionOps != NULL);
2231 
2232  /*
2233  * "Any visible" mode is not compatible with uniqueness checks; make sure
2234  * only one of those is requested.
2235  */
2236  Assert(!(anyvisible && checking_uniqueness));
2237 
2238  /*
2239  * Need an EState for evaluation of index expressions and partial-index
2240  * predicates. Also a slot to hold the current tuple.
2241  */
2242  estate = CreateExecutorState();
2243  econtext = GetPerTupleExprContext(estate);
2244  slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
2245 
2246  /* Arrange for econtext's scan tuple to be the tuple under test */
2247  econtext->ecxt_scantuple = slot;
2248 
2249  /* Set up execution state for predicate, if any. */
2250  predicate = (List *)
2251  ExecPrepareExpr((Expr *) indexInfo->ii_Predicate,
2252  estate);
2253 
2254  /*
2255  * Prepare for scan of the base relation. In a normal index build, we use
2256  * SnapshotAny because we must retrieve all tuples and do our own time
2257  * qual checks (because we have to index RECENTLY_DEAD tuples). In a
2258  * concurrent build, or during bootstrap, we take a regular MVCC snapshot
2259  * and index whatever's live according to that.
2260  */
2261  if (IsBootstrapProcessingMode() || indexInfo->ii_Concurrent)
2262  {
2264  OldestXmin = InvalidTransactionId; /* not used */
2265 
2266  /* "any visible" mode is not compatible with this */
2267  Assert(!anyvisible);
2268  }
2269  else
2270  {
2271  snapshot = SnapshotAny;
2272  /* okay to ignore lazy VACUUMs here */
2273  OldestXmin = GetOldestXmin(heapRelation, true);
2274  }
2275 
2276  scan = heap_beginscan_strat(heapRelation, /* relation */
2277  snapshot, /* snapshot */
2278  0, /* number of keys */
2279  NULL, /* scan key */
2280  true, /* buffer access strategy OK */
2281  allow_sync); /* syncscan OK? */
2282 
2283  /* set our scan endpoints */
2284  if (!allow_sync)
2285  heap_setscanlimits(scan, start_blockno, numblocks);
2286  else
2287  {
2288  /* syncscan can only be requested on whole relation */
2289  Assert(start_blockno == 0);
2290  Assert(numblocks == InvalidBlockNumber);
2291  }
2292 
2293  reltuples = 0;
2294 
2295  /*
2296  * Scan all tuples in the base relation.
2297  */
2298  while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
2299  {
2300  bool tupleIsAlive;
2301 
2303 
2304  /*
2305  * When dealing with a HOT-chain of updated tuples, we want to index
2306  * the values of the live tuple (if any), but index it under the TID
2307  * of the chain's root tuple. This approach is necessary to preserve
2308  * the HOT-chain structure in the heap. So we need to be able to find
2309  * the root item offset for every tuple that's in a HOT-chain. When
2310  * first reaching a new page of the relation, call
2311  * heap_get_root_tuples() to build a map of root item offsets on the
2312  * page.
2313  *
2314  * It might look unsafe to use this information across buffer
2315  * lock/unlock. However, we hold ShareLock on the table so no
2316  * ordinary insert/update/delete should occur; and we hold pin on the
2317  * buffer continuously while visiting the page, so no pruning
2318  * operation can occur either.
2319  *
2320  * Also, although our opinions about tuple liveness could change while
2321  * we scan the page (due to concurrent transaction commits/aborts),
2322  * the chain root locations won't, so this info doesn't need to be
2323  * rebuilt after waiting for another transaction.
2324  *
2325  * Note the implied assumption that there is no more than one live
2326  * tuple per HOT-chain --- else we could create more than one index
2327  * entry pointing to the same root tuple.
2328  */
2329  if (scan->rs_cblock != root_blkno)
2330  {
2331  Page page = BufferGetPage(scan->rs_cbuf);
2332 
2334  heap_get_root_tuples(page, root_offsets);
2336 
2337  root_blkno = scan->rs_cblock;
2338  }
2339 
2340  if (snapshot == SnapshotAny)
2341  {
2342  /* do our own time qual check */
2343  bool indexIt;
2344  TransactionId xwait;
2345 
2346  recheck:
2347 
2348  /*
2349  * We could possibly get away with not locking the buffer here,
2350  * since caller should hold ShareLock on the relation, but let's
2351  * be conservative about it. (This remark is still correct even
2352  * with HOT-pruning: our pin on the buffer prevents pruning.)
2353  */
2355 
2356  switch (HeapTupleSatisfiesVacuum(heapTuple, OldestXmin,
2357  scan->rs_cbuf))
2358  {
2359  case HEAPTUPLE_DEAD:
2360  /* Definitely dead, we can ignore it */
2361  indexIt = false;
2362  tupleIsAlive = false;
2363  break;
2364  case HEAPTUPLE_LIVE:
2365  /* Normal case, index and unique-check it */
2366  indexIt = true;
2367  tupleIsAlive = true;
2368  break;
2370 
2371  /*
2372  * If tuple is recently deleted then we must index it
2373  * anyway to preserve MVCC semantics. (Pre-existing
2374  * transactions could try to use the index after we finish
2375  * building it, and may need to see such tuples.)
2376  *
2377  * However, if it was HOT-updated then we must only index
2378  * the live tuple at the end of the HOT-chain. Since this
2379  * breaks semantics for pre-existing snapshots, mark the
2380  * index as unusable for them.
2381  */
2382  if (HeapTupleIsHotUpdated(heapTuple))
2383  {
2384  indexIt = false;
2385  /* mark the index as unsafe for old snapshots */
2386  indexInfo->ii_BrokenHotChain = true;
2387  }
2388  else
2389  indexIt = true;
2390  /* In any case, exclude the tuple from unique-checking */
2391  tupleIsAlive = false;
2392  break;
2394 
2395  /*
2396  * In "anyvisible" mode, this tuple is visible and we
2397  * don't need any further checks.
2398  */
2399  if (anyvisible)
2400  {
2401  indexIt = true;
2402  tupleIsAlive = true;
2403  break;
2404  }
2405 
2406  /*
2407  * Since caller should hold ShareLock or better, normally
2408  * the only way to see this is if it was inserted earlier
2409  * in our own transaction. However, it can happen in
2410  * system catalogs, since we tend to release write lock
2411  * before commit there. Give a warning if neither case
2412  * applies.
2413  */
2414  xwait = HeapTupleHeaderGetXmin(heapTuple->t_data);
2416  {
2417  if (!is_system_catalog)
2418  elog(WARNING, "concurrent insert in progress within table \"%s\"",
2419  RelationGetRelationName(heapRelation));
2420 
2421  /*
2422  * If we are performing uniqueness checks, indexing
2423  * such a tuple could lead to a bogus uniqueness
2424  * failure. In that case we wait for the inserting
2425  * transaction to finish and check again.
2426  */
2427  if (checking_uniqueness)
2428  {
2429  /*
2430  * Must drop the lock on the buffer before we wait
2431  */
2433  XactLockTableWait(xwait, heapRelation,
2434  &heapTuple->t_self,
2437  goto recheck;
2438  }
2439  }
2440 
2441  /*
2442  * We must index such tuples, since if the index build
2443  * commits then they're good.
2444  */
2445  indexIt = true;
2446  tupleIsAlive = true;
2447  break;
2449 
2450  /*
2451  * As with INSERT_IN_PROGRESS case, this is unexpected
2452  * unless it's our own deletion or a system catalog; but
2453  * in anyvisible mode, this tuple is visible.
2454  */
2455  if (anyvisible)
2456  {
2457  indexIt = true;
2458  tupleIsAlive = false;
2459  break;
2460  }
2461 
2462  xwait = HeapTupleHeaderGetUpdateXid(heapTuple->t_data);
2464  {
2465  if (!is_system_catalog)
2466  elog(WARNING, "concurrent delete in progress within table \"%s\"",
2467  RelationGetRelationName(heapRelation));
2468 
2469  /*
2470  * If we are performing uniqueness checks, assuming
2471  * the tuple is dead could lead to missing a
2472  * uniqueness violation. In that case we wait for the
2473  * deleting transaction to finish and check again.
2474  *
2475  * Also, if it's a HOT-updated tuple, we should not
2476  * index it but rather the live tuple at the end of
2477  * the HOT-chain. However, the deleting transaction
2478  * could abort, possibly leaving this tuple as live
2479  * after all, in which case it has to be indexed. The
2480  * only way to know what to do is to wait for the
2481  * deleting transaction to finish and check again.
2482  */
2483  if (checking_uniqueness ||
2484  HeapTupleIsHotUpdated(heapTuple))
2485  {
2486  /*
2487  * Must drop the lock on the buffer before we wait
2488  */
2490  XactLockTableWait(xwait, heapRelation,
2491  &heapTuple->t_self,
2494  goto recheck;
2495  }
2496 
2497  /*
2498  * Otherwise index it but don't check for uniqueness,
2499  * the same as a RECENTLY_DEAD tuple.
2500  */
2501  indexIt = true;
2502  }
2503  else if (HeapTupleIsHotUpdated(heapTuple))
2504  {
2505  /*
2506  * It's a HOT-updated tuple deleted by our own xact.
2507  * We can assume the deletion will commit (else the
2508  * index contents don't matter), so treat the same as
2509  * RECENTLY_DEAD HOT-updated tuples.
2510  */
2511  indexIt = false;
2512  /* mark the index as unsafe for old snapshots */
2513  indexInfo->ii_BrokenHotChain = true;
2514  }
2515  else
2516  {
2517  /*
2518  * It's a regular tuple deleted by our own xact. Index
2519  * it but don't check for uniqueness, the same as a
2520  * RECENTLY_DEAD tuple.
2521  */
2522  indexIt = true;
2523  }
2524  /* In any case, exclude the tuple from unique-checking */
2525  tupleIsAlive = false;
2526  break;
2527  default:
2528  elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result");
2529  indexIt = tupleIsAlive = false; /* keep compiler quiet */
2530  break;
2531  }
2532 
2534 
2535  if (!indexIt)
2536  continue;
2537  }
2538  else
2539  {
2540  /* heap_getnext did the time qual check */
2541  tupleIsAlive = true;
2542  }
2543 
2544  reltuples += 1;
2545 
2547 
2548  /* Set up for predicate or expression evaluation */
2549  ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
2550 
2551  /*
2552  * In a partial index, discard tuples that don't satisfy the
2553  * predicate.
2554  */
2555  if (predicate != NIL)
2556  {
2557  if (!ExecQual(predicate, econtext, false))
2558  continue;
2559  }
2560 
2561  /*
2562  * For the current heap tuple, extract all the attributes we use in
2563  * this index, and note which are null. This also performs evaluation
2564  * of any expressions needed.
2565  */
2566  FormIndexDatum(indexInfo,
2567  slot,
2568  estate,
2569  values,
2570  isnull);
2571 
2572  /*
2573  * You'd think we should go ahead and build the index tuple here, but
2574  * some index AMs want to do further processing on the data first. So
2575  * pass the values[] and isnull[] arrays, instead.
2576  */
2577 
2578  if (HeapTupleIsHeapOnly(heapTuple))
2579  {
2580  /*
2581  * For a heap-only tuple, pretend its TID is that of the root. See
2582  * src/backend/access/heap/README.HOT for discussion.
2583  */
2584  HeapTupleData rootTuple;
2585  OffsetNumber offnum;
2586 
2587  rootTuple = *heapTuple;
2588  offnum = ItemPointerGetOffsetNumber(&heapTuple->t_self);
2589 
2590  if (!OffsetNumberIsValid(root_offsets[offnum - 1]))
2591  elog(ERROR, "failed to find parent tuple for heap-only tuple at (%u,%u) in table \"%s\"",
2592  ItemPointerGetBlockNumber(&heapTuple->t_self),
2593  offnum, RelationGetRelationName(heapRelation));
2594 
2596  root_offsets[offnum - 1]);
2597 
2598  /* Call the AM's callback routine to process the tuple */
2599  callback(indexRelation, &rootTuple, values, isnull, tupleIsAlive,
2600  callback_state);
2601  }
2602  else
2603  {
2604  /* Call the AM's callback routine to process the tuple */
2605  callback(indexRelation, heapTuple, values, isnull, tupleIsAlive,
2606  callback_state);
2607  }
2608  }
2609 
2610  heap_endscan(scan);
2611 
2612  /* we can now forget our snapshot, if set */
2613  if (IsBootstrapProcessingMode() || indexInfo->ii_Concurrent)
2614  UnregisterSnapshot(snapshot);
2615 
2617 
2618  FreeExecutorState(estate);
2619 
2620  /* These may have been pointing to the now-gone estate */
2621  indexInfo->ii_ExpressionsState = NIL;
2622  indexInfo->ii_PredicateState = NIL;
2623 
2624  return reltuples;
2625 }
2626 
2627 
2628 /*
2629  * IndexCheckExclusion - verify that a new exclusion constraint is satisfied
2630  *
2631  * When creating an exclusion constraint, we first build the index normally
2632  * and then rescan the heap to check for conflicts. We assume that we only
2633  * need to validate tuples that are live according to an up-to-date snapshot,
2634  * and that these were correctly indexed even in the presence of broken HOT
2635  * chains. This should be OK since we are holding at least ShareLock on the
2636  * table, meaning there can be no uncommitted updates from other transactions.
2637  * (Note: that wouldn't necessarily work for system catalogs, since many
2638  * operations release write lock early on the system catalogs.)
2639  */
2640 static void
2642  Relation indexRelation,
2643  IndexInfo *indexInfo)
2644 {
2645  HeapScanDesc scan;
2646  HeapTuple heapTuple;
2648  bool isnull[INDEX_MAX_KEYS];
2649  List *predicate;
2650  TupleTableSlot *slot;
2651  EState *estate;
2652  ExprContext *econtext;
2653  Snapshot snapshot;
2654 
2655  /*
2656  * If we are reindexing the target index, mark it as no longer being
2657  * reindexed, to forestall an Assert in index_beginscan when we try to use
2658  * the index for probes. This is OK because the index is now fully valid.
2659  */
2662 
2663  /*
2664  * Need an EState for evaluation of index expressions and partial-index
2665  * predicates. Also a slot to hold the current tuple.
2666  */
2667  estate = CreateExecutorState();
2668  econtext = GetPerTupleExprContext(estate);
2669  slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
2670 
2671  /* Arrange for econtext's scan tuple to be the tuple under test */
2672  econtext->ecxt_scantuple = slot;
2673 
2674  /* Set up execution state for predicate, if any. */
2675  predicate = (List *)
2676  ExecPrepareExpr((Expr *) indexInfo->ii_Predicate,
2677  estate);
2678 
2679  /*
2680  * Scan all live tuples in the base relation.
2681  */
2682  snapshot = RegisterSnapshot(GetLatestSnapshot());
2683  scan = heap_beginscan_strat(heapRelation, /* relation */
2684  snapshot, /* snapshot */
2685  0, /* number of keys */
2686  NULL, /* scan key */
2687  true, /* buffer access strategy OK */
2688  true); /* syncscan OK */
2689 
2690  while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
2691  {
2693 
2695 
2696  /* Set up for predicate or expression evaluation */
2697  ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
2698 
2699  /*
2700  * In a partial index, ignore tuples that don't satisfy the predicate.
2701  */
2702  if (predicate != NIL)
2703  {
2704  if (!ExecQual(predicate, econtext, false))
2705  continue;
2706  }
2707 
2708  /*
2709  * Extract index column values, including computing expressions.
2710  */
2711  FormIndexDatum(indexInfo,
2712  slot,
2713  estate,
2714  values,
2715  isnull);
2716 
2717  /*
2718  * Check that this tuple has no conflicts.
2719  */
2720  check_exclusion_constraint(heapRelation,
2721  indexRelation, indexInfo,
2722  &(heapTuple->t_self), values, isnull,
2723  estate, true);
2724  }
2725 
2726  heap_endscan(scan);
2727  UnregisterSnapshot(snapshot);
2728 
2730 
2731  FreeExecutorState(estate);
2732 
2733  /* These may have been pointing to the now-gone estate */
2734  indexInfo->ii_ExpressionsState = NIL;
2735  indexInfo->ii_PredicateState = NIL;
2736 }
2737 
2738 
2739 /*
2740  * validate_index - support code for concurrent index builds
2741  *
2742  * We do a concurrent index build by first inserting the catalog entry for the
2743  * index via index_create(), marking it not indisready and not indisvalid.
2744  * Then we commit our transaction and start a new one, then we wait for all
2745  * transactions that could have been modifying the table to terminate. Now
2746  * we know that any subsequently-started transactions will see the index and
2747  * honor its constraints on HOT updates; so while existing HOT-chains might
2748  * be broken with respect to the index, no currently live tuple will have an
2749  * incompatible HOT update done to it. We now build the index normally via
2750  * index_build(), while holding a weak lock that allows concurrent
2751  * insert/update/delete. Also, we index only tuples that are valid
2752  * as of the start of the scan (see IndexBuildHeapScan), whereas a normal
2753  * build takes care to include recently-dead tuples. This is OK because
2754  * we won't mark the index valid until all transactions that might be able
2755  * to see those tuples are gone. The reason for doing that is to avoid
2756  * bogus unique-index failures due to concurrent UPDATEs (we might see
2757  * different versions of the same row as being valid when we pass over them,
2758  * if we used HeapTupleSatisfiesVacuum). This leaves us with an index that
2759  * does not contain any tuples added to the table while we built the index.
2760  *
2761  * Next, we mark the index "indisready" (but still not "indisvalid") and
2762  * commit the second transaction and start a third. Again we wait for all
2763  * transactions that could have been modifying the table to terminate. Now
2764  * we know that any subsequently-started transactions will see the index and
2765  * insert their new tuples into it. We then take a new reference snapshot
2766  * which is passed to validate_index(). Any tuples that are valid according
2767  * to this snap, but are not in the index, must be added to the index.
2768  * (Any tuples committed live after the snap will be inserted into the
2769  * index by their originating transaction. Any tuples committed dead before
2770  * the snap need not be indexed, because we will wait out all transactions
2771  * that might care about them before we mark the index valid.)
2772  *
2773  * validate_index() works by first gathering all the TIDs currently in the
2774  * index, using a bulkdelete callback that just stores the TIDs and doesn't
2775  * ever say "delete it". (This should be faster than a plain indexscan;
2776  * also, not all index AMs support full-index indexscan.) Then we sort the
2777  * TIDs, and finally scan the table doing a "merge join" against the TID list
2778  * to see which tuples are missing from the index. Thus we will ensure that
2779  * all tuples valid according to the reference snapshot are in the index.
2780  *
2781  * Building a unique index this way is tricky: we might try to insert a
2782  * tuple that is already dead or is in process of being deleted, and we
2783  * mustn't have a uniqueness failure against an updated version of the same
2784  * row. We could try to check the tuple to see if it's already dead and tell
2785  * index_insert() not to do the uniqueness check, but that still leaves us
2786  * with a race condition against an in-progress update. To handle that,
2787  * we expect the index AM to recheck liveness of the to-be-inserted tuple
2788  * before it declares a uniqueness error.
2789  *
2790  * After completing validate_index(), we wait until all transactions that
2791  * were alive at the time of the reference snapshot are gone; this is
2792  * necessary to be sure there are none left with a transaction snapshot
2793  * older than the reference (and hence possibly able to see tuples we did
2794  * not index). Then we mark the index "indisvalid" and commit. Subsequent
2795  * transactions will be able to use it for queries.
2796  *
2797  * Doing two full table scans is a brute-force strategy. We could try to be
2798  * cleverer, eg storing new tuples in a special area of the table (perhaps
2799  * making the table append-only by setting use_fsm). However that would
2800  * add yet more locking issues.
2801  */
2802 void
2803 validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
2804 {
2805  Relation heapRelation,
2806  indexRelation;
2807  IndexInfo *indexInfo;
2808  IndexVacuumInfo ivinfo;
2809  v_i_state state;
2810  Oid save_userid;
2811  int save_sec_context;
2812  int save_nestlevel;
2813 
2814  /* Open and lock the parent heap relation */
2815  heapRelation = heap_open(heapId, ShareUpdateExclusiveLock);
2816  /* And the target index relation */
2817  indexRelation = index_open(indexId, RowExclusiveLock);
2818 
2819  /*
2820  * Fetch info needed for index_insert. (You might think this should be
2821  * passed in from DefineIndex, but its copy is long gone due to having
2822  * been built in a previous transaction.)
2823  */
2824  indexInfo = BuildIndexInfo(indexRelation);
2825 
2826  /* mark build is concurrent just for consistency */
2827  indexInfo->ii_Concurrent = true;
2828 
2829  /*
2830  * Switch to the table owner's userid, so that any index functions are run
2831  * as that user. Also lock down security-restricted operations and
2832  * arrange to make GUC variable changes local to this command.
2833  */
2834  GetUserIdAndSecContext(&save_userid, &save_sec_context);
2835  SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
2836  save_sec_context | SECURITY_RESTRICTED_OPERATION);
2837  save_nestlevel = NewGUCNestLevel();
2838 
2839  /*
2840  * Scan the index and gather up all the TIDs into a tuplesort object.
2841  */
2842  ivinfo.index = indexRelation;
2843  ivinfo.analyze_only = false;
2844  ivinfo.estimated_count = true;
2845  ivinfo.message_level = DEBUG2;
2846  ivinfo.num_heap_tuples = heapRelation->rd_rel->reltuples;
2847  ivinfo.strategy = NULL;
2848 
2849  /*
2850  * Encode TIDs as int8 values for the sort, rather than directly sorting
2851  * item pointers. This can be significantly faster, primarily because TID
2852  * is a pass-by-reference type on all platforms, whereas int8 is
2853  * pass-by-value on most platforms.
2854  */
2856  InvalidOid, false,
2858  false);
2859  state.htups = state.itups = state.tups_inserted = 0;
2860 
2861  (void) index_bulk_delete(&ivinfo, NULL,
2862  validate_index_callback, (void *) &state);
2863 
2864  /* Execute the sort */
2866 
2867  /*
2868  * Now scan the heap and "merge" it with the index
2869  */
2870  validate_index_heapscan(heapRelation,
2871  indexRelation,
2872  indexInfo,
2873  snapshot,
2874  &state);
2875 
2876  /* Done with tuplesort object */
2877  tuplesort_end(state.tuplesort);
2878 
2879  elog(DEBUG2,
2880  "validate_index found %.0f heap tuples, %.0f index tuples; inserted %.0f missing tuples",
2881  state.htups, state.itups, state.tups_inserted);
2882 
2883  /* Roll back any GUC changes executed by index functions */
2884  AtEOXact_GUC(false, save_nestlevel);
2885 
2886  /* Restore userid and security context */
2887  SetUserIdAndSecContext(save_userid, save_sec_context);
2888 
2889  /* Close rels, but keep locks */
2890  index_close(indexRelation, NoLock);
2891  heap_close(heapRelation, NoLock);
2892 }
2893 
2894 /*
2895  * itemptr_encode - Encode ItemPointer as int64/int8
2896  *
2897  * This representation must produce values encoded as int64 that sort in the
2898  * same order as their corresponding original TID values would (using the
2899  * default int8 opclass to produce a result equivalent to the default TID
2900  * opclass).
2901  *
2902  * As noted in validate_index(), this can be significantly faster.
2903  */
2904 static inline int64
2906 {
2907  BlockNumber block = ItemPointerGetBlockNumber(itemptr);
2908  OffsetNumber offset = ItemPointerGetOffsetNumber(itemptr);
2909  int64 encoded;
2910 
2911  /*
2912  * Use the 16 least significant bits for the offset. 32 adjacent bits are
2913  * used for the block number. Since remaining bits are unused, there
2914  * cannot be negative encoded values (We assume a two's complement
2915  * representation).
2916  */
2917  encoded = ((uint64) block << 16) | (uint16) offset;
2918 
2919  return encoded;
2920 }
2921 
2922 /*
2923  * itemptr_decode - Decode int64/int8 representation back to ItemPointer
2924  */
2925 static inline void
2926 itemptr_decode(ItemPointer itemptr, int64 encoded)
2927 {
2928  BlockNumber block = (BlockNumber) (encoded >> 16);
2929  OffsetNumber offset = (OffsetNumber) (encoded & 0xFFFF);
2930 
2931  ItemPointerSet(itemptr, block, offset);
2932 }
2933 
2934 /*
2935  * validate_index_callback - bulkdelete callback to collect the index TIDs
2936  */
2937 static bool
2938 validate_index_callback(ItemPointer itemptr, void *opaque)
2939 {
2940  v_i_state *state = (v_i_state *) opaque;
2941  int64 encoded = itemptr_encode(itemptr);
2942 
2943  tuplesort_putdatum(state->tuplesort, Int64GetDatum(encoded), false);
2944  state->itups += 1;
2945  return false; /* never actually delete anything */
2946 }
2947 
2948 /*
2949  * validate_index_heapscan - second table scan for concurrent index build
2950  *
2951  * This has much code in common with IndexBuildHeapScan, but it's enough
2952  * different that it seems cleaner to have two routines not one.
2953  */
2954 static void
2956  Relation indexRelation,
2957  IndexInfo *indexInfo,
2958  Snapshot snapshot,
2959  v_i_state *state)
2960 {
2961  HeapScanDesc scan;
2962  HeapTuple heapTuple;
2964  bool isnull[INDEX_MAX_KEYS];
2965  List *predicate;
2966  TupleTableSlot *slot;
2967  EState *estate;
2968  ExprContext *econtext;
2969  BlockNumber root_blkno = InvalidBlockNumber;
2970  OffsetNumber root_offsets[MaxHeapTuplesPerPage];
2971  bool in_index[MaxHeapTuplesPerPage];
2972 
2973  /* state variables for the merge */
2974  ItemPointer indexcursor = NULL;
2975  ItemPointerData decoded;
2976  bool tuplesort_empty = false;
2977 
2978  /*
2979  * sanity checks
2980  */
2981  Assert(OidIsValid(indexRelation->rd_rel->relam));
2982 
2983  /*
2984  * Need an EState for evaluation of index expressions and partial-index
2985  * predicates. Also a slot to hold the current tuple.
2986  */
2987  estate = CreateExecutorState();
2988  econtext = GetPerTupleExprContext(estate);
2989  slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
2990 
2991  /* Arrange for econtext's scan tuple to be the tuple under test */
2992  econtext->ecxt_scantuple = slot;
2993 
2994  /* Set up execution state for predicate, if any. */
2995  predicate = (List *)
2996  ExecPrepareExpr((Expr *) indexInfo->ii_Predicate,
2997  estate);
2998 
2999  /*
3000  * Prepare for scan of the base relation. We need just those tuples
3001  * satisfying the passed-in reference snapshot. We must disable syncscan
3002  * here, because it's critical that we read from block zero forward to
3003  * match the sorted TIDs.
3004  */
3005  scan = heap_beginscan_strat(heapRelation, /* relation */
3006  snapshot, /* snapshot */
3007  0, /* number of keys */
3008  NULL, /* scan key */
3009  true, /* buffer access strategy OK */
3010  false); /* syncscan not OK */
3011 
3012  /*
3013  * Scan all tuples matching the snapshot.
3014  */
3015  while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
3016  {
3017  ItemPointer heapcursor = &heapTuple->t_self;
3018  ItemPointerData rootTuple;
3019  OffsetNumber root_offnum;
3020 
3022 
3023  state->htups += 1;
3024 
3025  /*
3026  * As commented in IndexBuildHeapScan, we should index heap-only
3027  * tuples under the TIDs of their root tuples; so when we advance onto
3028  * a new heap page, build a map of root item offsets on the page.
3029  *
3030  * This complicates merging against the tuplesort output: we will
3031  * visit the live tuples in order by their offsets, but the root
3032  * offsets that we need to compare against the index contents might be
3033  * ordered differently. So we might have to "look back" within the
3034  * tuplesort output, but only within the current page. We handle that
3035  * by keeping a bool array in_index[] showing all the
3036  * already-passed-over tuplesort output TIDs of the current page. We
3037  * clear that array here, when advancing onto a new heap page.
3038  */
3039  if (scan->rs_cblock != root_blkno)
3040  {
3041  Page page = BufferGetPage(scan->rs_cbuf);
3042 
3044  heap_get_root_tuples(page, root_offsets);
3046 
3047  memset(in_index, 0, sizeof(in_index));
3048 
3049  root_blkno = scan->rs_cblock;
3050  }
3051 
3052  /* Convert actual tuple TID to root TID */
3053  rootTuple = *heapcursor;
3054  root_offnum = ItemPointerGetOffsetNumber(heapcursor);
3055 
3056  if (HeapTupleIsHeapOnly(heapTuple))
3057  {
3058  root_offnum = root_offsets[root_offnum - 1];
3059  if (!OffsetNumberIsValid(root_offnum))
3060  elog(ERROR, "failed to find parent tuple for heap-only tuple at (%u,%u) in table \"%s\"",
3061  ItemPointerGetBlockNumber(heapcursor),
3062  ItemPointerGetOffsetNumber(heapcursor),
3063  RelationGetRelationName(heapRelation));
3064  ItemPointerSetOffsetNumber(&rootTuple, root_offnum);
3065  }
3066 
3067  /*
3068  * "merge" by skipping through the index tuples until we find or pass
3069  * the current root tuple.
3070  */
3071  while (!tuplesort_empty &&
3072  (!indexcursor ||
3073  ItemPointerCompare(indexcursor, &rootTuple) < 0))
3074  {
3075  Datum ts_val;
3076  bool ts_isnull;
3077 
3078  if (indexcursor)
3079  {
3080  /*
3081  * Remember index items seen earlier on the current heap page
3082  */
3083  if (ItemPointerGetBlockNumber(indexcursor) == root_blkno)
3084  in_index[ItemPointerGetOffsetNumber(indexcursor) - 1] = true;
3085  }
3086 
3087  tuplesort_empty = !tuplesort_getdatum(state->tuplesort, true,
3088  &ts_val, &ts_isnull, NULL);
3089  Assert(tuplesort_empty || !ts_isnull);
3090  if (!tuplesort_empty)
3091  {
3092  itemptr_decode(&decoded, DatumGetInt64(ts_val));
3093  indexcursor = &decoded;
3094 
3095  /* If int8 is pass-by-ref, free (encoded) TID Datum memory */
3096 #ifndef USE_FLOAT8_BYVAL
3097  pfree(DatumGetPointer(ts_val));
3098 #endif
3099  }
3100  else
3101  {
3102  /* Be tidy */
3103  indexcursor = NULL;
3104  }
3105  }
3106 
3107  /*
3108  * If the tuplesort has overshot *and* we didn't see a match earlier,
3109  * then this tuple is missing from the index, so insert it.
3110  */
3111  if ((tuplesort_empty ||
3112  ItemPointerCompare(indexcursor, &rootTuple) > 0) &&
3113  !in_index[root_offnum - 1])
3114  {
3116 
3117  /* Set up for predicate or expression evaluation */
3118  ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);
3119 
3120  /*
3121  * In a partial index, discard tuples that don't satisfy the
3122  * predicate.
3123  */
3124  if (predicate != NIL)
3125  {
3126  if (!ExecQual(predicate, econtext, false))
3127  continue;
3128  }
3129 
3130  /*
3131  * For the current heap tuple, extract all the attributes we use
3132  * in this index, and note which are null. This also performs
3133  * evaluation of any expressions needed.
3134  */
3135  FormIndexDatum(indexInfo,
3136  slot,
3137  estate,
3138  values,
3139  isnull);
3140 
3141  /*
3142  * You'd think we should go ahead and build the index tuple here,
3143  * but some index AMs want to do further processing on the data
3144  * first. So pass the values[] and isnull[] arrays, instead.
3145  */
3146 
3147  /*
3148  * If the tuple is already committed dead, you might think we
3149  * could suppress uniqueness checking, but this is no longer true
3150  * in the presence of HOT, because the insert is actually a proxy
3151  * for a uniqueness check on the whole HOT-chain. That is, the
3152  * tuple we have here could be dead because it was already
3153  * HOT-updated, and if so the updating transaction will not have
3154  * thought it should insert index entries. The index AM will
3155  * check the whole HOT-chain and correctly detect a conflict if
3156  * there is one.
3157  */
3158 
3159  index_insert(indexRelation,
3160  values,
3161  isnull,
3162  &rootTuple,
3163  heapRelation,
3164  indexInfo->ii_Unique ?
3166  indexInfo);
3167 
3168  state->tups_inserted += 1;
3169  }
3170  }
3171 
3172  heap_endscan(scan);
3173 
3175 
3176  FreeExecutorState(estate);
3177 
3178  /* These may have been pointing to the now-gone estate */
3179  indexInfo->ii_ExpressionsState = NIL;
3180  indexInfo->ii_PredicateState = NIL;
3181 }
3182 
3183 
3184 /*
3185  * index_set_state_flags - adjust pg_index state flags
3186  *
3187  * This is used during CREATE/DROP INDEX CONCURRENTLY to adjust the pg_index
3188  * flags that denote the index's state. Because the update is not
3189  * transactional and will not roll back on error, this must only be used as
3190  * the last step in a transaction that has not made any transactional catalog
3191  * updates!
3192  *
3193  * Note that heap_inplace_update does send a cache inval message for the
3194  * tuple, so other sessions will hear about the update as soon as we commit.
3195  *
3196  * NB: In releases prior to PostgreSQL 9.4, the use of a non-transactional
3197  * update here would have been unsafe; now that MVCC rules apply even for
3198  * system catalog scans, we could potentially use a transactional update here
3199  * instead.
3200  */
3201 void
3203 {
3204  Relation pg_index;
3205  HeapTuple indexTuple;
3206  Form_pg_index indexForm;
3207 
3208  /* Assert that current xact hasn't done any transactional updates */
3210 
3211  /* Open pg_index and fetch a writable copy of the index's tuple */
3213 
3214  indexTuple = SearchSysCacheCopy1(INDEXRELID,
3215  ObjectIdGetDatum(indexId));
3216  if (!HeapTupleIsValid(indexTuple))
3217  elog(ERROR, "cache lookup failed for index %u", indexId);
3218  indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
3219 
3220  /* Perform the requested state change on the copy */
3221  switch (action)
3222  {
3224  /* Set indisready during a CREATE INDEX CONCURRENTLY sequence */
3225  Assert(indexForm->indislive);
3226  Assert(!indexForm->indisready);
3227  Assert(!indexForm->indisvalid);
3228  indexForm->indisready = true;
3229  break;
3231  /* Set indisvalid during a CREATE INDEX CONCURRENTLY sequence */
3232  Assert(indexForm->indislive);
3233  Assert(indexForm->indisready);
3234  Assert(!indexForm->indisvalid);
3235  indexForm->indisvalid = true;
3236  break;
3238 
3239  /*
3240  * Clear indisvalid during a DROP INDEX CONCURRENTLY sequence
3241  *
3242  * If indisready == true we leave it set so the index still gets
3243  * maintained by active transactions. We only need to ensure that
3244  * indisvalid is false. (We don't assert that either is initially
3245  * true, though, since we want to be able to retry a DROP INDEX
3246  * CONCURRENTLY that failed partway through.)
3247  *
3248  * Note: the CLUSTER logic assumes that indisclustered cannot be
3249  * set on any invalid index, so clear that flag too.
3250  */
3251  indexForm->indisvalid = false;
3252  indexForm->indisclustered = false;
3253  break;
3254  case INDEX_DROP_SET_DEAD:
3255 
3256  /*
3257  * Clear indisready/indislive during DROP INDEX CONCURRENTLY
3258  *
3259  * We clear both indisready and indislive, because we not only
3260  * want to stop updates, we want to prevent sessions from touching
3261  * the index at all.
3262  */
3263  Assert(!indexForm->indisvalid);
3264  indexForm->indisready = false;
3265  indexForm->indislive = false;
3266  break;
3267  }
3268 
3269  /* ... and write it back in-place */
3270  heap_inplace_update(pg_index, indexTuple);
3271 
3272  heap_close(pg_index, RowExclusiveLock);
3273 }
3274 
3275 
3276 /*
3277  * IndexGetRelation: given an index's relation OID, get the OID of the
3278  * relation it is an index on. Uses the system cache.
3279  */
3280 Oid
3281 IndexGetRelation(Oid indexId, bool missing_ok)
3282 {
3283  HeapTuple tuple;
3285  Oid result;
3286 
3287  tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexId));
3288  if (!HeapTupleIsValid(tuple))
3289  {
3290  if (missing_ok)
3291  return InvalidOid;
3292  elog(ERROR, "cache lookup failed for index %u", indexId);
3293  }
3294  index = (Form_pg_index) GETSTRUCT(tuple);
3295  Assert(index->indexrelid == indexId);
3296 
3297  result = index->indrelid;
3298  ReleaseSysCache(tuple);
3299  return result;
3300 }
3301 
3302 /*
3303  * reindex_index - This routine is used to recreate a single index
3304  */
3305 void
3306 reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
3307  int options)
3308 {
3309  Relation iRel,
3310  heapRelation;
3311  Oid heapId;
3312  IndexInfo *indexInfo;
3313  volatile bool skipped_constraint = false;
3314  PGRUsage ru0;
3315 
3316  pg_rusage_init(&ru0);
3317 
3318  /*
3319  * Open and lock the parent heap relation. ShareLock is sufficient since
3320  * we only need to be sure no schema or data changes are going on.
3321  */
3322  heapId = IndexGetRelation(indexId, false);
3323  heapRelation = heap_open(heapId, ShareLock);
3324 
3325  /*
3326  * Open the target index relation and get an exclusive lock on it, to
3327  * ensure that no one else is touching this particular index.
3328  */
3329  iRel = index_open(indexId, AccessExclusiveLock);
3330 
3331  /*
3332  * Don't allow reindex on temp tables of other backends ... their local
3333  * buffer manager is not going to cope.
3334  */
3335  if (RELATION_IS_OTHER_TEMP(iRel))
3336  ereport(ERROR,
3337  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3338  errmsg("cannot reindex temporary tables of other sessions")));
3339 
3340  /*
3341  * Also check for active uses of the index in the current transaction; we
3342  * don't want to reindex underneath an open indexscan.
3343  */
3344  CheckTableNotInUse(iRel, "REINDEX INDEX");
3345 
3346  /*
3347  * All predicate locks on the index are about to be made invalid. Promote
3348  * them to relation locks on the heap.
3349  */
3351 
3352  PG_TRY();
3353  {
3354  /* Suppress use of the target index while rebuilding it */
3355  SetReindexProcessing(heapId, indexId);
3356 
3357  /* Fetch info needed for index_build */
3358  indexInfo = BuildIndexInfo(iRel);
3359 
3360  /* If requested, skip checking uniqueness/exclusion constraints */
3361  if (skip_constraint_checks)
3362  {
3363  if (indexInfo->ii_Unique || indexInfo->ii_ExclusionOps != NULL)
3364  skipped_constraint = true;
3365  indexInfo->ii_Unique = false;
3366  indexInfo->ii_ExclusionOps = NULL;
3367  indexInfo->ii_ExclusionProcs = NULL;
3368  indexInfo->ii_ExclusionStrats = NULL;
3369  }
3370 
3371  /* We'll build a new physical relation for the index */
3374 
3375  /* Initialize the index and rebuild */
3376  /* Note: we do not need to re-establish pkey setting */
3377  index_build(heapRelation, iRel, indexInfo, false, true);
3378  }
3379  PG_CATCH();
3380  {
3381  /* Make sure flag gets cleared on error exit */
3383  PG_RE_THROW();
3384  }
3385  PG_END_TRY();
3387 
3388  /*
3389  * If the index is marked invalid/not-ready/dead (ie, it's from a failed
3390  * CREATE INDEX CONCURRENTLY, or a DROP INDEX CONCURRENTLY failed midway),
3391  * and we didn't skip a uniqueness check, we can now mark it valid. This
3392  * allows REINDEX to be used to clean up in such cases.
3393  *
3394  * We can also reset indcheckxmin, because we have now done a
3395  * non-concurrent index build, *except* in the case where index_build
3396  * found some still-broken HOT chains. If it did, and we don't have to
3397  * change any of the other flags, we just leave indcheckxmin alone (note
3398  * that index_build won't have changed it, because this is a reindex).
3399  * This is okay and desirable because not updating the tuple leaves the
3400  * index's usability horizon (recorded as the tuple's xmin value) the same
3401  * as it was.
3402  *
3403  * But, if the index was invalid/not-ready/dead and there were broken HOT
3404  * chains, we had better force indcheckxmin true, because the normal
3405  * argument that the HOT chains couldn't conflict with the index is
3406  * suspect for an invalid index. (A conflict is definitely possible if
3407  * the index was dead. It probably shouldn't happen otherwise, but let's
3408  * be conservative.) In this case advancing the usability horizon is
3409  * appropriate.
3410  *
3411  * Another reason for avoiding unnecessary updates here is that while
3412  * reindexing pg_index itself, we must not try to update tuples in it.
3413  * pg_index's indexes should always have these flags in their clean state,
3414  * so that won't happen.
3415  *
3416  * If early pruning/vacuuming is enabled for the heap relation, the
3417  * usability horizon must be advanced to the current transaction on every
3418  * build or rebuild. pg_index is OK in this regard because catalog tables
3419  * are not subject to early cleanup.
3420  */
3421  if (!skipped_constraint)
3422  {
3423  Relation pg_index;
3424  HeapTuple indexTuple;
3425  Form_pg_index indexForm;
3426  bool index_bad;
3427  bool early_pruning_enabled = EarlyPruningEnabled(heapRelation);
3428 
3430 
3431  indexTuple = SearchSysCacheCopy1(INDEXRELID,
3432  ObjectIdGetDatum(indexId));
3433  if (!HeapTupleIsValid(indexTuple))
3434  elog(ERROR, "cache lookup failed for index %u", indexId);
3435  indexForm = (Form_pg_index) GETSTRUCT(indexTuple);
3436 
3437  index_bad = (!indexForm->indisvalid ||
3438  !indexForm->indisready ||
3439  !indexForm->indislive);
3440  if (index_bad ||
3441  (indexForm->indcheckxmin && !indexInfo->ii_BrokenHotChain) ||
3442  early_pruning_enabled)
3443  {
3444  if (!indexInfo->ii_BrokenHotChain && !early_pruning_enabled)
3445  indexForm->indcheckxmin = false;
3446  else if (index_bad || early_pruning_enabled)
3447  indexForm->indcheckxmin = true;
3448  indexForm->indisvalid = true;
3449  indexForm->indisready = true;
3450  indexForm->indislive = true;
3451  CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple);
3452 
3453  /*
3454  * Invalidate the relcache for the table, so that after we commit
3455  * all sessions will refresh the table's index list. This ensures
3456  * that if anyone misses seeing the pg_index row during this
3457  * update, they'll refresh their list before attempting any update
3458  * on the table.
3459  */
3460  CacheInvalidateRelcache(heapRelation);
3461  }
3462 
3463  heap_close(pg_index, RowExclusiveLock);
3464  }
3465 
3466  /* Log what we did */
3467  if (options & REINDEXOPT_VERBOSE)
3468  ereport(INFO,
3469  (errmsg("index \"%s\" was reindexed",
3470  get_rel_name(indexId)),
3471  errdetail("%s.",
3472  pg_rusage_show(&ru0))));
3473 
3474  /* Close rels, but keep locks */
3475  index_close(iRel, NoLock);
3476  heap_close(heapRelation, NoLock);
3477 }
3478 
3479 /*
3480  * reindex_relation - This routine is used to recreate all indexes
3481  * of a relation (and optionally its toast relation too, if any).
3482  *
3483  * "flags" is a bitmask that can include any combination of these bits:
3484  *
3485  * REINDEX_REL_PROCESS_TOAST: if true, process the toast table too (if any).
3486  *
3487  * REINDEX_REL_SUPPRESS_INDEX_USE: if true, the relation was just completely
3488  * rebuilt by an operation such as VACUUM FULL or CLUSTER, and therefore its
3489  * indexes are inconsistent with it. This makes things tricky if the relation
3490  * is a system catalog that we might consult during the reindexing. To deal
3491  * with that case, we mark all of the indexes as pending rebuild so that they
3492  * won't be trusted until rebuilt. The caller is required to call us *without*
3493  * having made the rebuilt table visible by doing CommandCounterIncrement;
3494  * we'll do CCI after having collected the index list. (This way we can still
3495  * use catalog indexes while collecting the list.)
3496  *
3497  * REINDEX_REL_CHECK_CONSTRAINTS: if true, recheck unique and exclusion
3498  * constraint conditions, else don't. To avoid deadlocks, VACUUM FULL or
3499  * CLUSTER on a system catalog must omit this flag. REINDEX should be used to
3500  * rebuild an index if constraint inconsistency is suspected. For optimal
3501  * performance, other callers should include the flag only after transforming
3502  * the data in a manner that risks a change in constraint validity.
3503  *
3504  * REINDEX_REL_FORCE_INDEXES_UNLOGGED: if true, set the persistence of the
3505  * rebuilt indexes to unlogged.
3506  *
3507  * REINDEX_REL_FORCE_INDEXES_PERMANENT: if true, set the persistence of the
3508  * rebuilt indexes to permanent.
3509  *
3510  * Returns true if any indexes were rebuilt (including toast table's index
3511  * when relevant). Note that a CommandCounterIncrement will occur after each
3512  * index rebuild.
3513  */
3514 bool
3516 {
3517  Relation rel;
3518  Oid toast_relid;
3519  List *indexIds;
3520  bool is_pg_class;
3521  bool result;
3522 
3523  /*
3524  * Open and lock the relation. ShareLock is sufficient since we only need
3525  * to prevent schema and data changes in it. The lock level used here
3526  * should match ReindexTable().
3527  */
3528  rel = heap_open(relid, ShareLock);
3529 
3530  toast_relid = rel->rd_rel->reltoastrelid;
3531 
3532  /*
3533  * Get the list of index OIDs for this relation. (We trust to the
3534  * relcache to get this with a sequential scan if ignoring system
3535  * indexes.)
3536  */
3537  indexIds = RelationGetIndexList(rel);
3538 
3539  /*
3540  * reindex_index will attempt to update the pg_class rows for the relation
3541  * and index. If we are processing pg_class itself, we want to make sure
3542  * that the updates do not try to insert index entries into indexes we
3543  * have not processed yet. (When we are trying to recover from corrupted
3544  * indexes, that could easily cause a crash.) We can accomplish this
3545  * because CatalogUpdateIndexes will use the relcache's index list to know
3546  * which indexes to update. We just force the index list to be only the
3547  * stuff we've processed.
3548  *
3549  * It is okay to not insert entries into the indexes we have not processed
3550  * yet because all of this is transaction-safe. If we fail partway
3551  * through, the updated rows are dead and it doesn't matter whether they
3552  * have index entries. Also, a new pg_class index will be created with a
3553  * correct entry for its own pg_class row because we do
3554  * RelationSetNewRelfilenode() before we do index_build().
3555  *
3556  * Note that we also clear pg_class's rd_oidindex until the loop is done,
3557  * so that that index can't be accessed either. This means we cannot
3558  * safely generate new relation OIDs while in the loop; shouldn't be a
3559  * problem.
3560  */
3561  is_pg_class = (RelationGetRelid(rel) == RelationRelationId);
3562 
3563  /* Ensure rd_indexattr is valid; see comments for RelationSetIndexList */
3564  if (is_pg_class)
3566 
3567  PG_TRY();
3568  {
3569  List *doneIndexes;
3570  ListCell *indexId;
3571  char persistence;
3572 
3573  if (flags & REINDEX_REL_SUPPRESS_INDEX_USE)
3574  {
3575  /* Suppress use of all the indexes until they are rebuilt */
3576  SetReindexPending(indexIds);
3577 
3578  /*
3579  * Make the new heap contents visible --- now things might be
3580  * inconsistent!
3581  */
3583  }
3584 
3585  /*
3586  * Compute persistence of indexes: same as that of owning rel, unless
3587  * caller specified otherwise.
3588  */
3590  persistence = RELPERSISTENCE_UNLOGGED;
3591  else if (flags & REINDEX_REL_FORCE_INDEXES_PERMANENT)
3592  persistence = RELPERSISTENCE_PERMANENT;
3593  else
3594  persistence = rel->rd_rel->relpersistence;
3595 
3596  /* Reindex all the indexes. */
3597  doneIndexes = NIL;
3598  foreach(indexId, indexIds)
3599  {
3600  Oid indexOid = lfirst_oid(indexId);
3601 
3602  if (is_pg_class)
3603  RelationSetIndexList(rel, doneIndexes, InvalidOid);
3604 
3605  reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
3606  persistence, options);
3607 
3609 
3610  /* Index should no longer be in the pending list */
3611  Assert(!ReindexIsProcessingIndex(indexOid));
3612 
3613  if (is_pg_class)
3614  doneIndexes = lappend_oid(doneIndexes, indexOid);
3615  }
3616  }
3617  PG_CATCH();
3618  {
3619  /* Make sure list gets cleared on error exit */
3621  PG_RE_THROW();
3622  }
3623  PG_END_TRY();
3625 
3626  if (is_pg_class)
3627  RelationSetIndexList(rel, indexIds, ClassOidIndexId);
3628 
3629  /*
3630  * Close rel, but continue to hold the lock.
3631  */
3632  heap_close(rel, NoLock);
3633 
3634  result = (indexIds != NIL);
3635 
3636  /*
3637  * If the relation has a secondary toast rel, reindex that too while we
3638  * still hold the lock on the master table.
3639  */
3640  if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid))
3641  result |= reindex_relation(toast_relid, flags, options);
3642 
3643  return result;
3644 }
3645 
3646 
3647 /* ----------------------------------------------------------------
3648  * System index reindexing support
3649  *
3650  * When we are busy reindexing a system index, this code provides support
3651  * for preventing catalog lookups from using that index. We also make use
3652  * of this to catch attempted uses of user indexes during reindexing of
3653  * those indexes.
3654  * ----------------------------------------------------------------
3655  */
3656 
3660 
3661 /*
3662  * ReindexIsProcessingHeap
3663  * True if heap specified by OID is currently being reindexed.
3664  */
3665 bool
3667 {
3668  return heapOid == currentlyReindexedHeap;
3669 }
3670 
3671 /*
3672  * ReindexIsCurrentlyProcessingIndex
3673  * True if index specified by OID is currently being reindexed.
3674  */
3675 static bool
3677 {
3678  return indexOid == currentlyReindexedIndex;
3679 }
3680 
3681 /*
3682  * ReindexIsProcessingIndex
3683  * True if index specified by OID is currently being reindexed,
3684  * or should be treated as invalid because it is awaiting reindex.
3685  */
3686 bool
3688 {
3689  return indexOid == currentlyReindexedIndex ||
3690  list_member_oid(pendingReindexedIndexes, indexOid);
3691 }
3692 
3693 /*
3694  * SetReindexProcessing
3695  * Set flag that specified heap/index are being reindexed.
3696  *
3697  * NB: caller must use a PG_TRY block to ensure ResetReindexProcessing is done.
3698  */
3699 static void
3700 SetReindexProcessing(Oid heapOid, Oid indexOid)
3701 {
3702  Assert(OidIsValid(heapOid) && OidIsValid(indexOid));
3703  /* Reindexing is not re-entrant. */
3705  elog(ERROR, "cannot reindex while reindexing");
3706  currentlyReindexedHeap = heapOid;
3707  currentlyReindexedIndex = indexOid;
3708  /* Index is no longer "pending" reindex. */
3709  RemoveReindexPending(indexOid);
3710 }
3711 
3712 /*
3713  * ResetReindexProcessing
3714  * Unset reindexing status.
3715  */
3716 static void
3718 {
3721 }
3722 
3723 /*
3724  * SetReindexPending
3725  * Mark the given indexes as pending reindex.
3726  *
3727  * NB: caller must use a PG_TRY block to ensure ResetReindexPending is done.
3728  * Also, we assume that the current memory context stays valid throughout.
3729  */
3730 static void
3732 {
3733  /* Reindexing is not re-entrant. */
3734  if (pendingReindexedIndexes)
3735  elog(ERROR, "cannot reindex while reindexing");
3736  pendingReindexedIndexes = list_copy(indexes);
3737 }
3738 
3739 /*
3740  * RemoveReindexPending
3741  * Remove the given index from the pending list.
3742  */
3743 static void
3745 {
3746  pendingReindexedIndexes = list_delete_oid(pendingReindexedIndexes,
3747  indexOid);
3748 }
3749 
3750 /*
3751  * ResetReindexPending
3752  * Unset reindex-pending status.
3753  */
3754 static void
3756 {
3757  pendingReindexedIndexes = NIL;
3758 }
#define HeapTupleHeaderGetUpdateXid(tup)
Definition: htup_details.h:359
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
Definition: itemptr.c:52
signed short int16
Definition: c.h:252
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: index.c:1764
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
#define NIL
Definition: pg_list.h:69
Definition: c.h:474
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
Definition: execTuples.c:320
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
MemoryContext ii_Context
Definition: execnodes.h:82
Oid IndexGetRelation(Oid indexId, bool missing_ok)
Definition: index.c:3281
bool tuplesort_getdatum(Tuplesortstate *state, bool forward, Datum *val, bool *isNull, Datum *abbrev)
Definition: tuplesort.c:2183
#define Int8LessOperator
Definition: pg_operator.h:181
void RelationGetExclusionInfo(Relation indexRelation, Oid **operators, Oid **procs, uint16 **strategies)
Definition: relcache.c:4966
uint16 * ii_UniqueStrats
Definition: execnodes.h:76
BlockNumber rs_cblock
Definition: relscan.h:69
List * SystemFuncName(char *name)
LockRelId lockRelId
Definition: rel.h:44
static Oid currentlyReindexedHeap
Definition: index.c:3657
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
Definition: execQual.c:5004
#define Anum_pg_index_indisprimary
Definition: pg_index.h:78
void tuplesort_performsort(Tuplesortstate *state)
Definition: tuplesort.c:1763
void RelationSetNewRelfilenode(Relation relation, char persistence, TransactionId freezeXid, MultiXactId minmulti)
Definition: relcache.c:3414
#define DEBUG1
Definition: elog.h:25
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition: smgr.c:376
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
void tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
Definition: tuplesort.c:1475
List * ii_Predicate
Definition: execnodes.h:69
static bool ReindexIsCurrentlyProcessingIndex(Oid indexOid)
Definition: index.c:3676
static void itemptr_decode(ItemPointer itemptr, int64 encoded)
Definition: index.c:2926
void heap_endscan(HeapScanDesc scan)
Definition: heapam.c:1581
bool IsSystemRelation(Relation relation)
Definition: catalog.c:62
#define RELPERSISTENCE_UNLOGGED
Definition: pg_class.h:171
uint32 TransactionId
Definition: c.h:394
#define SECURITY_RESTRICTED_OPERATION
Definition: miscadmin.h:292
Snapshot RegisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:858
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:394
#define RelationGetDescr(relation)
Definition: rel.h:425
int LOCKMODE
Definition: lockdefs.h:26
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:772
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
void index_set_state_flags(Oid indexId, IndexStateFlagsAction action)
Definition: index.c:3202
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:273
static void SetReindexProcessing(Oid heapOid, Oid indexOid)
Definition: index.c:3700
static void SetReindexPending(List *indexes)
Definition: index.c:3731
#define PointerGetDatum(X)
Definition: postgres.h:564
Node * whenClause
Definition: parsenodes.h:2251
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
#define IndexRelationId
Definition: pg_index.h:29
#define IndexIsReady(indexForm)
Definition: pg_index.h:108
#define RelationGetForm(relation)
Definition: rel.h:407
char * pstrdup(const char *in)
Definition: mcxt.c:1165
void CommitTransactionCommand(void)
Definition: xact.c:2745
#define ANYELEMENTOID
Definition: pg_type.h:690
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
#define RelationRelationId
Definition: pg_class.h:29
bool analyze_only
Definition: genam.h:47
int2vector * buildint2vector(const int16 *int2s, int n)
Definition: int.c:112
ObjectAddress CreateTrigger(CreateTrigStmt *stmt, const char *queryString, Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, bool isInternal)
Definition: trigger.c:138
#define BTREE_AM_OID
Definition: pg_am.h:70
Oid dbId
Definition: rel.h:39
BufferAccessStrategy strategy
Definition: genam.h:51
static void InitializeAttributeOids(Relation indexRelation, int numatts, Oid indexoid)
Definition: index.c:488
Oid binary_upgrade_next_index_pg_class_oid
Definition: index.c:77
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define MaxHeapTuplesPerPage
Definition: htup_details.h:575
#define Int16GetDatum(X)
Definition: postgres.h:459
#define Anum_pg_index_indclass
Definition: pg_index.h:89
Definition: lock.h:179
static void ResetReindexPending(void)
Definition: index.c:3755
#define OperatorClassRelationId
Definition: pg_opclass.h:49
#define InvalidBuffer
Definition: buf.h:25
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, Buffer buffer)
Definition: tqual.c:1164
static List * pendingReindexedIndexes
Definition: index.c:3659
List * list_copy(const List *oldlist)
Definition: list.c:1160
void index_check_primary_key(Relation heapRel, IndexInfo *indexInfo, bool is_alter_table)
Definition: index.c:192
Definition: nodes.h:509
Oid * ii_ExclusionProcs
Definition: execnodes.h:72
Oid index_create(Relation heapRelation, const char *indexRelationName, Oid indexRelationId, Oid relFileNode, IndexInfo *indexInfo, List *indexColNames, Oid accessMethodObjectId, Oid tableSpaceId, Oid *collationObjectId, Oid *classObjectId, int16 *coloptions, Datum reloptions, bool isprimary, bool isconstraint, bool deferrable, bool initdeferred, bool allow_system_table_mods, bool skip_build, bool concurrent, bool is_internal, bool if_not_exists)
Definition: index.c:697
#define CONSTRAINT_EXCLUSION
void(* IndexBuildCallback)(Relation index, HeapTuple htup, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
Definition: index.h:24
#define AttributeRelationId
Definition: pg_attribute.h:33
void index_drop(Oid indexId, bool concurrent)
Definition: index.c:1344
int errcode(int sqlerrcode)
Definition: elog.c:575
Relation index
Definition: genam.h:46
#define MemSet(start, val, len)
Definition: c.h:853
AlterTableType subtype
Definition: parsenodes.h:1685
#define INFO
Definition: elog.h:33
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:135
uint32 BlockNumber
Definition: block.h:31
void RelationForgetRelation(Oid rid)
Definition: relcache.c:2679
void PopActiveSnapshot(void)
Definition: snapmgr.c:807
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
double htups
Definition: index.c:84
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
IndexInfo * BuildIndexInfo(Relation index)
Definition: index.c:1639
#define Anum_pg_index_indisexclusion
Definition: pg_index.h:79
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:287
void visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_frozen)
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
#define REINDEX_REL_SUPPRESS_INDEX_USE
Definition: index.h:123
Form_pg_class rd_rel
Definition: rel.h:113
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
unsigned int Oid
Definition: postgres_ext.h:31
#define Anum_pg_index_indcheckxmin
Definition: pg_index.h:83
#define CONSTRAINT_UNIQUE
int namestrcpy(Name name, const char *str)
Definition: name.c:217
Oid amkeytype
Definition: amapi.h:195
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:300
#define OidIsValid(objectId)
Definition: c.h:534
Oid * ii_UniqueOps
Definition: execnodes.h:74
struct IndexAmRoutine * rd_amroutine
Definition: rel.h:177
bool IsBinaryUpgrade
Definition: globals.c:101
Datum ExecEvalExprSwitchContext(ExprState *expression, ExprContext *econtext, bool *isNull)
Definition: execQual.c:4219
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define REINDEXOPT_VERBOSE
Definition: parsenodes.h:3096
signed int int32
Definition: c.h:253
static void ResetReindexProcessing(void)
Definition: index.c:3717
List * RelationGetIndexPredicate(Relation relation)
Definition: relcache.c:4676
#define Anum_pg_index_indrelid
Definition: pg_index.h:75
Tuplesortstate * tuplesort
Definition: index.c:82
uint16 OffsetNumber
Definition: off.h:24
HeapTupleHeader t_data
Definition: htup.h:67
void pg_rusage_init(PGRUsage *ru0)
Definition: pg_rusage.c:27
Definition: type.h:90
#define RELPERSISTENCE_PERMANENT
Definition: pg_class.h:170
Expr * make_ands_explicit(List *andclauses)
Definition: clauses.c:366
#define CONSTRAINT_PRIMARY
void InsertPgClassTuple(Relation pg_class_desc, Relation new_rel_desc, Oid new_rel_oid, Datum relacl, Datum reloptions)
Definition: heap.c:760
#define RelationOpenSmgr(relation)
Definition: rel.h:457
RangeVar * constrrel
Definition: parsenodes.h:2258
void FreeExecutorState(EState *estate)
Definition: execUtils.c:168
#define HeapTupleIsHotUpdated(tuple)
Definition: htup_details.h:677
#define GetPerTupleExprContext(estate)
Definition: executor.h:338
List * ii_ExpressionsState
Definition: execnodes.h:68
Form_pg_index rd_index
Definition: rel.h:155
static void UpdateIndexRelation(Oid indexoid, Oid heapoid, IndexInfo *indexInfo, Oid *collationOids, Oid *classOids, int16 *coloptions, bool primary, bool isexclusion, bool immediate, bool isvalid)
Definition: index.c:549
unsigned short uint16
Definition: c.h:264
void pfree(void *pointer)
Definition: mcxt.c:992
#define EarlyPruningEnabled(rel)
Definition: snapmgr.h:46
void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:312
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
Relation heap_create(const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, Oid relfilenode, TupleDesc tupDesc, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, bool allow_system_table_mods)
Definition: heap.c:248
Definition: rel.h:36
ambuild_function ambuild
Definition: amapi.h:198
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:299
IndexAmRoutine * GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
Definition: amapi.c:56
#define TRIGGER_TYPE_AFTER
Definition: pg_trigger.h:112
#define RelationIsValid(relation)
Definition: rel.h:386
void RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex)
Definition: relcache.c:4509
bool ReindexIsProcessingHeap(Oid heapOid)
Definition: index.c:3666
ItemPointerData t_self
Definition: htup.h:65
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:49
#define DatumGetInt64(X)
Definition: postgres.h:615
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition: lsyscache.c:1651
#define DEBUG2
Definition: elog.h:24
static void validate_index_heapscan(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, Snapshot snapshot, v_i_state *state)
Definition: index.c:2955
List * ii_PredicateState
Definition: execnodes.h:70
Tuplesortstate * tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, bool randomAccess)
Definition: tuplesort.c:1028
#define AttrNumberGetAttrOffset(attNum)
Definition: attnum.h:51
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:194
#define NoLock
Definition: lockdefs.h:34
LockInfoData rd_lockInfo
Definition: rel.h:116
#define IsNormalProcessingMode()
Definition: miscadmin.h:367
#define InvokeObjectPostAlterHookArg(classId, objectId, subId,auxiliaryId, is_internal)
Definition: objectaccess.h:166
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:216
List * RelationGetIndexExpressions(Relation relation)
Definition: relcache.c:4613
Oid * ii_UniqueProcs
Definition: execnodes.h:75
#define DEFAULT_COLLATION_OID
Definition: pg_collation.h:68
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:387
bool heap_attisnull(HeapTuple tup, int attnum)
Definition: heaptuple.c:297
#define RowExclusiveLock
Definition: lockdefs.h:38
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:5036
int errdetail(const char *fmt,...)
Definition: elog.c:873
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
Definition: lsyscache.c:163
IndexStateFlagsAction
Definition: index.h:32
#define Anum_pg_index_indisready
Definition: pg_index.h:84
const char * pg_rusage_show(const PGRUsage *ru0)
Definition: pg_rusage.c:40
#define InvalidTransactionId
Definition: transam.h:31
bool ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
Definition: execQual.c:5055
#define RelationGetRelationName(relation)
Definition: rel.h:433
static TransactionId OldestXmin
Definition: vacuumlazy.c:138
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
List * list_delete_oid(List *list, Oid datum)
Definition: list.c:636
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
bool ii_BrokenHotChain
Definition: execnodes.h:80
Oid * rd_opfamily
Definition: rel.h:178
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
HeapScanDesc heap_beginscan_catalog(Relation relation, int nkeys, ScanKey key)
Definition: heapam.c:1402
static TupleDesc ConstructTupleDescriptor(Relation heapRelation, IndexInfo *indexInfo, List *indexColNames, Oid accessMethodObjectId, Oid *collationObjectId, Oid *classObjectId)
Definition: index.c:275
void heap_setscanlimits(HeapScanDesc scan, BlockNumber startBlk, BlockNumber numBlks)
Definition: heapam.c:328
#define Anum_pg_index_indislive
Definition: pg_index.h:85
#define Natts_pg_index
Definition: pg_index.h:73
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:403
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:199
#define ClassOidIndexId
Definition: indexing.h:112
void CheckTableNotInUse(Relation rel, const char *stmt)
Definition: tablecmds.c:2950
#define Anum_pg_index_indkey
Definition: pg_index.h:87
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:2102
static void IndexCheckExclusion(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo)
Definition: index.c:2641
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:176
void heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
Definition: pruneheap.c:744
#define lnext(lc)
Definition: pg_list.h:105
void index_register(Oid heap, Oid ind, IndexInfo *indexInfo)
Definition: bootstrap.c:1054
bool ii_ReadyForInserts
Definition: execnodes.h:78
#define ereport(elevel, rest)
Definition: elog.h:122
EState * CreateExecutorState(void)
Definition: execUtils.c:72
void TransferPredicateLocksToHeapRelation(Relation relation)
Definition: predicate.c:3007
void UnregisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:900
List * lappend(List *list, void *datum)
Definition: list.c:128
void * ii_AmCache
Definition: execnodes.h:81
static Oid currentlyReindexedIndex
Definition: index.c:3658
void CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, bool allow_system_table_mods)
Definition: heap.c:485
#define WARNING
Definition: elog.h:40
void index_build(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, bool isprimary, bool isreindex)
Definition: index.c:2000
void validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
Definition: index.c:2803
static void AppendAttributeTuples(Relation indexRelation, int numatts)
Definition: index.c:506
#define RelationIsMapped(relation)
Definition: rel.h:450
FormData_pg_index * Form_pg_index
Definition: pg_index.h:67
float float4
Definition: c.h:377
Definition: c.h:463
#define ANYARRAYOID
Definition: pg_type.h:676
void RelationDropStorage(Relation rel)
Definition: storage.c:145
IndexBulkDeleteResult * index_bulk_delete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
Definition: indexam.c:743
uintptr_t Datum
Definition: postgres.h:374
void CommandCounterIncrement(void)
Definition: xact.c:921
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define SnapshotAny
Definition: tqual.h:28
int ii_NumIndexAttrs
Definition: execnodes.h:65
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
HeapTuple heap_getnext(HeapScanDesc scan, ScanDirection direction)
Definition: heapam.c:1781
static bool relationHasPrimaryKey(Relation rel)
Definition: index.c:142
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidMultiXactId
Definition: multixact.h:23
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
#define Anum_pg_index_indisunique
Definition: pg_index.h:77
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
Definition: objectaccess.h:147
#define CollationRelationId
Definition: pg_collation.h:30
static int64 itemptr_encode(ItemPointer itemptr)
Definition: index.c:2905
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
Definition: pg_depend.c:241
#define BoolGetDatum(X)
Definition: postgres.h:410
static void RemoveReindexPending(Oid indexOid)
Definition: index.c:3744
void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode)
Definition: lmgr.c:811
Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
Definition: heap.c:198
#define TRIGGER_TYPE_UPDATE
Definition: pg_trigger.h:102
#define InvalidOid
Definition: postgres_ext.h:36
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1062
void DeleteRelationTuple(Oid relid)
Definition: heap.c:1428
int maintenance_work_mem
Definition: globals.c:113
HeapScanDesc heap_beginscan_strat(Relation relation, Snapshot snapshot, int nkeys, ScanKey key, bool allow_strat, bool allow_sync)
Definition: heapam.c:1412
#define NOTICE
Definition: elog.h:37
#define INT8OID
Definition: pg_type.h:304
Buffer rs_cbuf
Definition: relscan.h:70
#define Anum_pg_index_indpred
Definition: pg_index.h:92
TransactionId GetOldestXmin(Relation rel, bool ignoreVacuum)
Definition: procarray.c:1305
int message_level
Definition: genam.h:49
int errmsg_internal(const char *fmt,...)
Definition: elog.c:827
double num_heap_tuples
Definition: genam.h:50
bool ii_Unique
Definition: execnodes.h:77
#define PG_CATCH()
Definition: elog.h:293
#define makeNode(_type_)
Definition: nodes.h:557
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define REINDEX_REL_FORCE_INDEXES_UNLOGGED
Definition: index.h:125
void XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, XLTW_Oper oper)
Definition: lmgr.c:554
#define NULL
Definition: c.h:226
List * ii_Expressions
Definition: execnodes.h:67
#define HeapTupleIsHeapOnly(tuple)
Definition: htup_details.h:686
#define Assert(condition)
Definition: c.h:671
#define Anum_pg_index_indisreplident
Definition: pg_index.h:86
oidvector * buildoidvector(const Oid *oids, int n)
Definition: oid.c:167
#define lfirst(lc)
Definition: pg_list.h:106
Definition: regguts.h:298
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:530
void StartTransactionCommand(void)
Definition: xact.c:2675
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:40
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:307
#define INDEX_MAX_KEYS
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define InvalidBlockNumber
Definition: block.h:33
#define REINDEX_REL_CHECK_CONSTRAINTS
Definition: index.h:124
Oid GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence)
Definition: catalog.c:386
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
#define TRIGGER_TYPE_INSERT
Definition: pg_trigger.h:100
AttrNumber ii_KeyAttrNumbers[INDEX_MAX_KEYS]
Definition: execnodes.h:66
#define ItemPointerGetOffsetNumber(pointer)
Definition: itemptr.h:76
void DeleteAttributeTuples(Oid relid)
Definition: heap.c:1457
#define PG_RE_THROW()
Definition: elog.h:314
int16 values[FLEXIBLE_ARRAY_MEMBER]
Definition: c.h:471
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:41
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4336
Snapshot GetLatestSnapshot(void)
Definition: snapmgr.c:375
void reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, int options)
Definition: index.c:3306
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool ignore_self)
Definition: dependency.c:1373
bool ii_Concurrent
Definition: execnodes.h:79
static void index_update_stats(Relation rel, bool hasindex, bool isprimary, double reltuples)
Definition: index.c:1843
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
#define DatumGetPointer(X)
Definition: postgres.h:557
double itups
Definition: index.c:84
void CacheInvalidateRelcache(Relation relation)
Definition: inval.c:1225
#define Anum_pg_index_indcollation
Definition: pg_index.h:88
void RemoveStatistics(Oid relid, AttrNumber attnum)
Definition: heap.c:2729
#define ItemPointerSetOffsetNumber(pointer, offsetNumber)
Definition: itemptr.h:107
static Datum values[MAXATTR]
Definition: bootstrap.c:162
void RelationInitIndexAccessInfo(Relation relation)
Definition: relcache.c:1504
#define Anum_pg_index_indisvalid
Definition: pg_index.h:82
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2525
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:158
void AlterTableInternal(Oid relid, List *cmds, bool recurse)
Definition: tablecmds.c:3053
#define AccessExclusiveLock
Definition: lockdefs.h:46
int NewGUCNestLevel(void)
Definition: guc.c:5022
void InsertPgAttributeTuple(Relation pg_attribute_rel, Form_pg_attribute new_attribute, CatalogIndexState indstate)
Definition: heap.c:595
double IndexBuildHeapScan(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, bool allow_sync, IndexBuildCallback callback, void *callback_state)
Definition: index.c:2169
Oid * ii_ExclusionOps
Definition: execnodes.h:71
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
void heap_inplace_update(Relation relation, HeapTuple tuple)
Definition: heapam.c:6233
#define Anum_pg_index_indimmediate
Definition: pg_index.h:80
#define Anum_pg_index_indnatts
Definition: pg_index.h:76
void list_free(List *list)
Definition: list.c:1133
#define Anum_pg_index_indisclustered
Definition: pg_index.h:81
ambuildempty_function ambuildempty
Definition: amapi.h:199
MemoryContext rd_indexcxt
Definition: rel.h:175
#define ShareLock
Definition: lockdefs.h:41
int i
void LockRelation(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:199
#define OffsetNumberIsValid(offsetNumber)
Definition: off.h:40
RangeVar * relation
Definition: parsenodes.h:2242
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
Definition: relcache.c:4759
Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: heaptuple.c:1143
#define NameStr(name)
Definition: c.h:495
#define RELKIND_INDEX
Definition: pg_class.h:161
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
#define CStringGetTextDatum(s)
Definition: builtins.h:90
char * nodeToString(const void *obj)
Definition: outfuncs.c:3981
#define REINDEX_REL_FORCE_INDEXES_PERMANENT
Definition: index.h:126
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:58
#define REINDEX_REL_PROCESS_TOAST
Definition: index.h:122
void BuildSpeculativeIndexInfo(Relation index, IndexInfo *ii)
Definition: index.c:1710
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
#define ConstraintRelationId
Definition: pg_constraint.h:29
ObjectAddress index_constraint_create(Relation heapRelation, Oid indexRelationId, IndexInfo *indexInfo, const char *constraintName, char constraintType, bool deferrable, bool initdeferred, bool mark_as_primary, bool update_pgindex, bool remove_old_dependencies, bool allow_system_table_mods, bool is_internal)
Definition: index.c:1147
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
Definition: inval.c:1261
#define elog
Definition: elog.h:219
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:66
void check_exclusion_constraint(Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, Datum *values, bool *isnull, EState *estate, bool newIndex)
Definition: execIndexing.c:867
Oid * rd_opcintype
Definition: rel.h:179
uint16 * ii_ExclusionStrats
Definition: execnodes.h:73
void tuplesort_end(Tuplesortstate *state)
Definition: tuplesort.c:1157
#define PG_TRY()
Definition: elog.h:284
bool ReindexIsProcessingIndex(Oid indexOid)
Definition: index.c:3687
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:68
static bool validate_index_callback(ItemPointer itemptr, void *opaque)
Definition: index.c:2938
bool reindex_relation(Oid relid, int flags, int options)
Definition: index.c:3515
Definition: pg_list.h:45
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1694
#define PointerIsValid(pointer)
Definition: c.h:522
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:413
Oid CreateConstraintEntry(const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isValidated, Oid relId, const int16 *constraintKey, int constraintNKeys, Oid domainId, Oid indexRelId, Oid foreignRelId, const int16 *foreignKey, const Oid *pfEqOp, const Oid *ppEqOp, const Oid *ffEqOp, int foreignNKeys, char foreignUpdateType, char foreignDeleteType, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, const char *conSrc, bool conIsLocal, int conInhCount, bool conNoInherit, bool is_internal)
Definition: pg_constraint.c:49
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
double tups_inserted
Definition: index.c:84
#define PG_END_TRY()
Definition: elog.h:300
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define Anum_pg_index_indoption
Definition: pg_index.h:90
#define Anum_pg_index_indexrelid
Definition: pg_index.h:74
double IndexBuildHeapRangeScan(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, bool allow_sync, bool anyvisible, BlockNumber start_blockno, BlockNumber numblocks, IndexBuildCallback callback, void *callback_state)
Definition: index.c:2194
Pointer Page
Definition: bufpage.h:74
#define lfirst_oid(lc)
Definition: pg_list.h:108
#define ItemPointerSet(pointer, blockNumber, offNum)
Definition: itemptr.h:86
#define Anum_pg_index_indexprs
Definition: pg_index.h:91
double index_tuples
Definition: genam.h:33
bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique, IndexInfo *indexInfo)
Definition: indexam.c:194
double heap_tuples
Definition: genam.h:32
Oid relId
Definition: rel.h:38
bool estimated_count
Definition: genam.h:48
#define RelationGetNamespace(relation)
Definition: rel.h:440
#define SearchSysCache2(cacheId, key1, key2)
Definition: syscache.h:151