aboutsummaryrefslogtreecommitdiff
path: root/src/backend/catalog/heap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/heap.c')
-rw-r--r--src/backend/catalog/heap.c190
1 files changed, 95 insertions, 95 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 910d3db063f..5206d5e5162 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -2708,7 +2708,7 @@ MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr,
bool found;
Relation conDesc;
SysScanDesc conscan;
- ScanKeyData skey[2];
+ ScanKeyData skey[3];
HeapTuple tup;
/* Search for a pg_constraint entry with same name and relation */
@@ -2717,120 +2717,120 @@ MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr,
found = false;
ScanKeyInit(&skey[0],
+ Anum_pg_constraint_conrelid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(RelationGetRelid(rel)));
+ ScanKeyInit(&skey[1],
+ Anum_pg_constraint_contypid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(InvalidOid));
+ ScanKeyInit(&skey[2],
Anum_pg_constraint_conname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(ccname));
- ScanKeyInit(&skey[1],
- Anum_pg_constraint_connamespace,
- BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(RelationGetNamespace(rel)));
-
- conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
- NULL, 2, skey);
+ conscan = systable_beginscan(conDesc, ConstraintRelidTypidNameIndexId, true,
+ NULL, 3, skey);
- while (HeapTupleIsValid(tup = systable_getnext(conscan)))
+ /* There can be at most one matching row */
+ if (HeapTupleIsValid(tup = systable_getnext(conscan)))
{
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);
- if (con->conrelid == RelationGetRelid(rel))
+ /* Found it. Conflicts if not identical check constraint */
+ if (con->contype == CONSTRAINT_CHECK)
{
- /* Found it. Conflicts if not identical check constraint */
- if (con->contype == CONSTRAINT_CHECK)
- {
- Datum val;
- bool isnull;
-
- val = fastgetattr(tup,
- Anum_pg_constraint_conbin,
- conDesc->rd_att, &isnull);
- if (isnull)
- elog(ERROR, "null conbin for rel %s",
- RelationGetRelationName(rel));
- if (equal(expr, stringToNode(TextDatumGetCString(val))))
- found = true;
- }
+ Datum val;
+ bool isnull;
+
+ val = fastgetattr(tup,
+ Anum_pg_constraint_conbin,
+ conDesc->rd_att, &isnull);
+ if (isnull)
+ elog(ERROR, "null conbin for rel %s",
+ RelationGetRelationName(rel));
+ if (equal(expr, stringToNode(TextDatumGetCString(val))))
+ found = true;
+ }
- /*
- * If the existing constraint is purely inherited (no local
- * definition) then interpret addition of a local constraint as a
- * legal merge. This allows ALTER ADD CONSTRAINT on parent and
- * child tables to be given in either order with same end state.
- * However if the relation is a partition, all inherited
- * constraints are always non-local, including those that were
- * merged.
- */
- if (is_local && !con->conislocal && !rel->rd_rel->relispartition)
- allow_merge = true;
+ /*
+ * If the existing constraint is purely inherited (no local
+ * definition) then interpret addition of a local constraint as a
+ * legal merge. This allows ALTER ADD CONSTRAINT on parent and child
+ * tables to be given in either order with same end state. However if
+ * the relation is a partition, all inherited constraints are always
+ * non-local, including those that were merged.
+ */
+ if (is_local && !con->conislocal && !rel->rd_rel->relispartition)
+ allow_merge = true;
- if (!found || !allow_merge)
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("constraint \"%s\" for relation \"%s\" already exists",
- ccname, RelationGetRelationName(rel))));
+ if (!found || !allow_merge)
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("constraint \"%s\" for relation \"%s\" already exists",
+ ccname, RelationGetRelationName(rel))));
- /* If the child constraint is "no inherit" then cannot merge */
- if (con->connoinherit)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"",
- ccname, RelationGetRelationName(rel))));
+ /* If the child constraint is "no inherit" then cannot merge */
+ if (con->connoinherit)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"",
+ ccname, RelationGetRelationName(rel))));
- /*
- * Must not change an existing inherited constraint to "no
- * inherit" status. That's because inherited constraints should
- * be able to propagate to lower-level children.
- */
- if (con->coninhcount > 0 && is_no_inherit)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"",
- ccname, RelationGetRelationName(rel))));
+ /*
+ * Must not change an existing inherited constraint to "no inherit"
+ * status. That's because inherited constraints should be able to
+ * propagate to lower-level children.
+ */
+ if (con->coninhcount > 0 && is_no_inherit)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"",
+ ccname, RelationGetRelationName(rel))));
- /*
- * If the child constraint is "not valid" then cannot merge with a
- * valid parent constraint
- */
- if (is_initially_valid && !con->convalidated)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"",
- ccname, RelationGetRelationName(rel))));
+ /*
+ * If the child constraint is "not valid" then cannot merge with a
+ * valid parent constraint.
+ */
+ if (is_initially_valid && !con->convalidated)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"",
+ ccname, RelationGetRelationName(rel))));
- /* OK to update the tuple */
- ereport(NOTICE,
- (errmsg("merging constraint \"%s\" with inherited definition",
- ccname)));
+ /* OK to update the tuple */
+ ereport(NOTICE,
+ (errmsg("merging constraint \"%s\" with inherited definition",
+ ccname)));
- tup = heap_copytuple(tup);
- con = (Form_pg_constraint) GETSTRUCT(tup);
+ tup = heap_copytuple(tup);
+ con = (Form_pg_constraint) GETSTRUCT(tup);
- /*
- * In case of partitions, an inherited constraint must be
- * inherited only once since it cannot have multiple parents and
- * it is never considered local.
- */
- if (rel->rd_rel->relispartition)
- {
- con->coninhcount = 1;
- con->conislocal = false;
- }
+ /*
+ * In case of partitions, an inherited constraint must be inherited
+ * only once since it cannot have multiple parents and it is never
+ * considered local.
+ */
+ if (rel->rd_rel->relispartition)
+ {
+ con->coninhcount = 1;
+ con->conislocal = false;
+ }
+ else
+ {
+ if (is_local)
+ con->conislocal = true;
else
- {
- if (is_local)
- con->conislocal = true;
- else
- con->coninhcount++;
- }
+ con->coninhcount++;
+ }
- if (is_no_inherit)
- {
- Assert(is_local);
- con->connoinherit = true;
- }
- CatalogTupleUpdate(conDesc, &tup->t_self, tup);
- break;
+ if (is_no_inherit)
+ {
+ Assert(is_local);
+ con->connoinherit = true;
}
+
+ CatalogTupleUpdate(conDesc, &tup->t_self, tup);
}
systable_endscan(conscan);