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