← Back to Overview

src/backend/catalog/index.c

Coverage: 3/3 lines (100.0%)
Total Lines
3
modified
Covered
3
100.0%
Uncovered
0
0.0%
Keyboard navigation
index_constraint_create() lines 1903-2129
Modified Lines Coverage: 3/3 lines (100.0%)
LineHitsSourceCommit
1903 - index_constraint_create(Relation heapRelation, -
1904 - Oid indexRelationId, -
1905 - Oid parentConstraintId, -
1906 - const IndexInfo *indexInfo, -
1907 - const char *constraintName, -
1908 - char constraintType, -
1909 - uint16 constr_flags, -
1910 - bool allow_system_table_mods, -
1911 - bool is_internal) -
1912 - { -
1913 - Oid namespaceId = RelationGetNamespace(heapRelation); -
1914 - ObjectAddress myself, -
1915 - idxaddr; -
1916 - Oid conOid; -
1917 - bool deferrable; -
1918 - bool initdeferred; -
1919 - bool mark_as_primary; -
1920 - bool islocal; -
1921 - bool noinherit; -
1922 - bool is_without_overlaps; -
1923 - int16 inhcount; -
1924 - -
1925 - deferrable = (constr_flags & INDEX_CONSTR_CREATE_DEFERRABLE) != 0; -
1926 - initdeferred = (constr_flags & INDEX_CONSTR_CREATE_INIT_DEFERRED) != 0; -
1927 - mark_as_primary = (constr_flags & INDEX_CONSTR_CREATE_MARK_AS_PRIMARY) != 0; -
1928 - is_without_overlaps = (constr_flags & INDEX_CONSTR_CREATE_WITHOUT_OVERLAPS) != 0; -
1929 - -
1930 - /* constraint creation support doesn't work while bootstrapping */ -
1931 - Assert(!IsBootstrapProcessingMode()); -
1932 - -
1933 - /* enforce system-table restriction */ -
1934 - if (!allow_system_table_mods && -
1935 - IsSystemRelation(heapRelation) && -
1936 - IsNormalProcessingMode()) -
1937 - ereport(ERROR, -
1938 - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), -
1939 - errmsg("user-defined indexes on system catalog tables are not supported"))); -
1940 - -
1941 - /* primary/unique constraints shouldn't have any expressions */ -
1942 - if (indexInfo->ii_Expressions && -
1943 - constraintType != CONSTRAINT_EXCLUSION) -
1944 - elog(ERROR, "constraints cannot have index expressions"); -
1945 - -
1946 - /* -
1947 - * If we're manufacturing a constraint for a pre-existing index, we need -
1948 - * to get rid of the existing auto dependencies for the index (the ones -
1949 - * that index_create() would have made instead of calling this function). -
1950 - * -
1951 - * Note: this code would not necessarily do the right thing if the index -
1952 - * has any expressions or predicate, but we'd never be turning such an -
1953 - * index into a UNIQUE or PRIMARY KEY constraint. -
1954 - */ -
1955 - if (constr_flags & INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS) -
1956 - deleteDependencyRecordsForClass(RelationRelationId, indexRelationId, -
1957 - RelationRelationId, DEPENDENCY_AUTO); -
1958 - -
1959 - if (OidIsValid(parentConstraintId)) -
1960 - { -
1961 - islocal = false; -
1962 - inhcount = 1; -
1963 - noinherit = false; -
1964 - } -
1965 - else -
1966 - { -
1967 - islocal = true; -
1968 - inhcount = 0; -
1969 - noinherit = true; -
1970 - } -
1971 - -
1972 - /* -
1973 - * Construct a pg_constraint entry. -
1974 - */ -
1975 - conOid = CreateConstraintEntry(constraintName, -
1976 - namespaceId, -
1977 - constraintType, -
1978 - deferrable, -
1979 - initdeferred, -
1980 - true, /* Is Enforced */ -
1981 - true, -
1982 - parentConstraintId, -
1983 - RelationGetRelid(heapRelation), -
1984 - indexInfo->ii_IndexAttrNumbers, -
1985 - indexInfo->ii_NumIndexKeyAttrs, -
1986 - indexInfo->ii_NumIndexAttrs, -
1987 - InvalidOid, /* no domain */ -
1988 - indexRelationId, /* index OID */ -
1989 - InvalidOid, /* no foreign key */ -
1990 - NULL, -
1991 - NULL, -
1992 - NULL, -
1993 - NULL, -
1994 - 0, -
1995 - ' ', -
1996 - ' ', -
1997 - NULL, -
1998 - 0, -
1999 - ' ', -
2000 - indexInfo->ii_ExclusionOps, -
2001 - NULL, /* no check constraint */ -
2002 - NULL, -
2003 - islocal, -
2004 - inhcount, -
2005 - noinherit, -
2006 - is_without_overlaps, -
2007 - is_internal); -
2008 - -
2009 - /* -
2010 - * Register the index as internally dependent on the constraint. -
2011 - * -
2012 - * Note that the constraint has a dependency on the table, so we don't -
2013 - * need (or want) any direct dependency from the index to the table. -
2014 - */ -
2015 - ObjectAddressSet(myself, ConstraintRelationId, conOid); -
2016 - ObjectAddressSet(idxaddr, RelationRelationId, indexRelationId); -
2017 - recordDependencyOn(&idxaddr, &myself, DEPENDENCY_INTERNAL); -
2018 - -
2019 - /* -
2020 - * Also, if this is a constraint on a partition, give it partition-type -
2021 - * dependencies on the parent constraint as well as the table. -
2022 - */ -
2023 - if (OidIsValid(parentConstraintId)) -
2024 - { -
2025 - ObjectAddress referenced; -
2026 - -
2027 - ObjectAddressSet(referenced, ConstraintRelationId, parentConstraintId); -
2028 - recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI); -
2029 - ObjectAddressSet(referenced, RelationRelationId, -
2030 - RelationGetRelid(heapRelation)); -
2031 - recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC); -
2032 - } -
2033 - -
2034 - /* -
2035 - * If the constraint is deferrable, create the deferred uniqueness -
2036 - * checking trigger. (The trigger will be given an internal dependency on -
2037 - * the constraint by CreateTrigger.) -
2038 - */ -
2039 - if (deferrable) -
2040 - { -
2041 - CreateTrigStmt *trigger = makeNode(CreateTrigStmt); -
2042 - -
2043 - trigger->replace = false; -
2044 111 trigger->tgenabled = TRIGGER_FIRES_ON_ORIGIN; 39ae762CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled
2045 - trigger->isconstraint = true; -
2046 - trigger->trigname = (constraintType == CONSTRAINT_PRIMARY) ? -
2047 - "PK_ConstraintTrigger" : -
2048 - "Unique_ConstraintTrigger"; -
2049 - trigger->relation = NULL; -
2050 - trigger->funcname = SystemFuncName("unique_key_recheck"); -
2051 - trigger->args = NIL; -
2052 - trigger->row = true; -
2053 - trigger->timing = TRIGGER_TYPE_AFTER; -
2054 - trigger->events = TRIGGER_TYPE_INSERT | TRIGGER_TYPE_UPDATE; -
2055 - trigger->columns = NIL; -
2056 - trigger->whenClause = NULL; -
2057 - trigger->transitionRels = NIL; -
2058 - trigger->deferrable = true; -
2059 - trigger->initdeferred = initdeferred; -
2060 - trigger->constrrel = NULL; -
2061 111 trigger->trigcomment = NULL; e73f551CREATE TABLE LIKE INCLUDING TRIGGERS
2062 111 trigger->transformed = true; e73f551CREATE TABLE LIKE INCLUDING TRIGGERS
2063 - -
2064 - (void) CreateTrigger(trigger, NULL, RelationGetRelid(heapRelation), -
2065 - InvalidOid, conOid, indexRelationId, InvalidOid, -
2066 - InvalidOid, NULL, true, false); -
2067 - } -
2068 - -
2069 - /* -
2070 - * If needed, mark the index as primary and/or deferred in pg_index. -
2071 - * -
2072 - * Note: When making an existing index into a constraint, caller must have -
2073 - * a table lock that prevents concurrent table updates; otherwise, there -
2074 - * is a risk that concurrent readers of the table will miss seeing this -
2075 - * index at all. -
2076 - */ -
2077 - if ((constr_flags & INDEX_CONSTR_CREATE_UPDATE_INDEX) && -
2078 - (mark_as_primary || deferrable)) -
2079 - { -
2080 - Relation pg_index; -
2081 - HeapTuple indexTuple; -
2082 - Form_pg_index indexForm; -
2083 - bool dirty = false; -
2084 - bool marked_as_primary = false; -
2085 - -
2086 - pg_index = table_open(IndexRelationId, RowExclusiveLock); -
2087 - -
2088 - indexTuple = SearchSysCacheCopy1(INDEXRELID, -
2089 - ObjectIdGetDatum(indexRelationId)); -
2090 - if (!HeapTupleIsValid(indexTuple)) -
2091 - elog(ERROR, "cache lookup failed for index %u", indexRelationId); -
2092 - indexForm = (Form_pg_index) GETSTRUCT(indexTuple); -
2093 - -
2094 - if (mark_as_primary && !indexForm->indisprimary) -
2095 - { -
2096 - indexForm->indisprimary = true; -
2097 - dirty = true; -
2098 - marked_as_primary = true; -
2099 - } -
2100 - -
2101 - if (deferrable && indexForm->indimmediate) -
2102 - { -
2103 - indexForm->indimmediate = false; -
2104 - dirty = true; -
2105 - } -
2106 - -
2107 - if (dirty) -
2108 - { -
2109 - CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple); -
2110 - -
2111 - /* -
2112 - * When we mark an existing index as primary, force a relcache -
2113 - * flush on its parent table, so that all sessions will become -
2114 - * aware that the table now has a primary key. This is important -
2115 - * because it affects some replication behaviors. -
2116 - */ -
2117 - if (marked_as_primary) -
2118 - CacheInvalidateRelcache(heapRelation); -
2119 - -
2120 - InvokeObjectPostAlterHookArg(IndexRelationId, indexRelationId, 0, -
2121 - InvalidOid, is_internal); -
2122 - } -
2123 - -
2124 - heap_freetuple(indexTuple); -
2125 - table_close(pg_index, RowExclusiveLock); -
2126 - } -
2127 - -
2128 - return myself; -
2129 - } -