Skip to content

Commit 6b603e6

Browse files
committed
Add DOMAIN check constraints.
Rod Taylor
1 parent 2986aa6 commit 6b603e6

File tree

29 files changed

+641
-147
lines changed

29 files changed

+641
-147
lines changed

doc/src/sgml/ref/create_domain.sgml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_domain.sgml,v 1.6 2002/09/20 03:39:15 momjian Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_domain.sgml,v 1.7 2002/11/15 02:50:05 momjian Exp $
33
PostgreSQL documentation
44
-->
55

@@ -200,16 +200,6 @@ CREATE TABLE countrylist (id INT4, country country_code);
200200
</para>
201201
</refsect1>
202202

203-
<refsect1 id="SQL-CREATEDOMAIN-compatibility">
204-
<title>Compatibility</title>
205-
206-
<para>
207-
SQL99 defines CREATE DOMAIN, but says that the only allowed constraint
208-
type is CHECK constraints. CHECK constraints for domains are not yet
209-
supported by <productname>PostgreSQL</productname>.
210-
</para>
211-
</refsect1>
212-
213203
<refsect1 id="SQL-CREATEDOMAIN-see-also">
214204
<title>See Also</title>
215205

src/backend/catalog/heap.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.234 2002/11/11 22:19:21 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.235 2002/11/15 02:50:05 momjian Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -1500,7 +1500,8 @@ AddRelationRawConstraints(Relation rel,
15001500

15011501
ccname = cdef->name;
15021502
/* Check against pre-existing constraints */
1503-
if (ConstraintNameIsUsed(RelationGetRelid(rel),
1503+
if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
1504+
RelationGetRelid(rel),
15041505
RelationGetNamespace(rel),
15051506
ccname))
15061507
elog(ERROR, "constraint \"%s\" already exists for relation \"%s\"",
@@ -1534,7 +1535,8 @@ AddRelationRawConstraints(Relation rel,
15341535
* pre-existing constraints, nor with any auto-generated
15351536
* names so far.
15361537
*/
1537-
ccname = GenerateConstraintName(RelationGetRelid(rel),
1538+
ccname = GenerateConstraintName(CONSTRAINT_RELATION,
1539+
RelationGetRelid(rel),
15381540
RelationGetNamespace(rel),
15391541
&constr_name_ctr);
15401542

@@ -1565,7 +1567,7 @@ AddRelationRawConstraints(Relation rel,
15651567
/*
15661568
* Transform raw parsetree to executable expression.
15671569
*/
1568-
expr = transformExpr(pstate, cdef->raw_expr);
1570+
expr = transformExpr(pstate, cdef->raw_expr, NULL);
15691571

15701572
/*
15711573
* Make sure it yields a boolean result.
@@ -1694,7 +1696,7 @@ cookDefault(ParseState *pstate,
16941696
/*
16951697
* Transform raw parsetree to executable expression.
16961698
*/
1697-
expr = transformExpr(pstate, raw_default);
1699+
expr = transformExpr(pstate, raw_default, NULL);
16981700

16991701
/*
17001702
* Make sure default expr does not refer to any vars.

src/backend/catalog/pg_constraint.c

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.7 2002/09/22 00:37:09 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.8 2002/11/15 02:50:05 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -190,6 +190,19 @@ CreateConstraintEntry(const char *constraintName,
190190
}
191191
}
192192

193+
if (OidIsValid(domainId))
194+
{
195+
/*
196+
* Register auto dependency from constraint to owning domain
197+
*/
198+
ObjectAddress domobject;
199+
200+
domobject.classId = RelOid_pg_type;
201+
domobject.objectId = domainId;
202+
203+
recordDependencyOn(&conobject, &domobject, DEPENDENCY_AUTO);
204+
}
205+
193206
if (OidIsValid(foreignRelId))
194207
{
195208
/*
@@ -262,7 +275,7 @@ CreateConstraintEntry(const char *constraintName,
262275
* this test is not very meaningful.
263276
*/
264277
bool
265-
ConstraintNameIsUsed(Oid relId, Oid relNamespace, const char *cname)
278+
ConstraintNameIsUsed(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, const char *cname)
266279
{
267280
bool found;
268281
Relation conDesc;
@@ -280,7 +293,7 @@ ConstraintNameIsUsed(Oid relId, Oid relNamespace, const char *cname)
280293

281294
ScanKeyEntryInitialize(&skey[1], 0x0,
282295
Anum_pg_constraint_connamespace, F_OIDEQ,
283-
ObjectIdGetDatum(relNamespace));
296+
ObjectIdGetDatum(objNamespace));
284297

285298
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
286299
SnapshotNow, 2, skey);
@@ -289,7 +302,12 @@ ConstraintNameIsUsed(Oid relId, Oid relNamespace, const char *cname)
289302
{
290303
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);
291304

292-
if (con->conrelid == relId)
305+
if (conCat == CONSTRAINT_RELATION && con->conrelid == objId)
306+
{
307+
found = true;
308+
break;
309+
}
310+
else if (conCat == CONSTRAINT_DOMAIN && con->contypid == objId)
293311
{
294312
found = true;
295313
break;
@@ -314,7 +332,7 @@ ConstraintNameIsUsed(Oid relId, Oid relNamespace, const char *cname)
314332
* someone else might choose the same name concurrently!
315333
*/
316334
char *
317-
GenerateConstraintName(Oid relId, Oid relNamespace, int *counter)
335+
GenerateConstraintName(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, int *counter)
318336
{
319337
bool found;
320338
Relation conDesc;
@@ -347,7 +365,7 @@ GenerateConstraintName(Oid relId, Oid relNamespace, int *counter)
347365

348366
ScanKeyEntryInitialize(&skey[1], 0x0,
349367
Anum_pg_constraint_connamespace, F_OIDEQ,
350-
ObjectIdGetDatum(relNamespace));
368+
ObjectIdGetDatum(objNamespace));
351369

352370
conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
353371
SnapshotNow, 2, skey);
@@ -356,7 +374,12 @@ GenerateConstraintName(Oid relId, Oid relNamespace, int *counter)
356374
{
357375
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);
358376

359-
if (con->conrelid == relId)
377+
if (conCat == CONSTRAINT_RELATION && con->conrelid == objId)
378+
{
379+
found = true;
380+
break;
381+
}
382+
else if (conCat == CONSTRAINT_DOMAIN && con->contypid == objId)
360383
{
361384
found = true;
362385
break;
@@ -415,10 +438,13 @@ RemoveConstraintById(Oid conId)
415438
con = (Form_pg_constraint) GETSTRUCT(tup);
416439

417440
/*
418-
* If the constraint is for a relation, open and exclusive-lock the
419-
* relation it's for.
441+
* If the constraint is for a relation, open and exclusive-lock
442+
* the relation it's for.
443+
*
444+
* If the constraint is for a domain, open and lock the pg_type entry
445+
* tye constraint is used on.
420446
*
421-
* XXX not clear what we should lock, if anything, for other constraints.
447+
* XXX not clear what we should lock, if anything, for assert constraints.
422448
*/
423449
if (OidIsValid(con->conrelid))
424450
{
@@ -463,6 +489,34 @@ RemoveConstraintById(Oid conId)
463489
/* Keep lock on constraint's rel until end of xact */
464490
heap_close(rel, NoLock);
465491
}
492+
/* Lock the domain row in pg_type */
493+
else if (OidIsValid(con->contypid))
494+
{
495+
Relation typRel;
496+
HeapTuple typTup;
497+
ScanKeyData typKey[1];
498+
SysScanDesc typScan;
499+
500+
typRel = heap_openr(TypeRelationName, RowExclusiveLock);
501+
502+
ScanKeyEntryInitialize(&typKey[0], 0x0,
503+
Anum_pg_constraint_contypid, F_OIDEQ,
504+
ObjectIdGetDatum(con->contypid));
505+
506+
typScan = systable_beginscan(typRel, TypeOidIndex, true,
507+
SnapshotNow, 1, typKey);
508+
509+
typTup = systable_getnext(typScan);
510+
511+
if (!HeapTupleIsValid(typTup))
512+
elog(ERROR, "RemoveConstraintById: Type %d does not exist",
513+
con->contypid);
514+
515+
systable_endscan(typScan);
516+
517+
/* Keep lock on domain type until end of xact */
518+
heap_close(typRel, NoLock);
519+
}
466520

467521
/* Fry the constraint itself */
468522
simple_heap_delete(conDesc, &tup->t_self);

src/backend/commands/tablecmds.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.53 2002/11/11 22:19:21 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.54 2002/11/15 02:50:05 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2632,14 +2632,16 @@ AlterTableAddConstraint(Oid myrelid, bool recurse,
26322632
*/
26332633
if (constr->name)
26342634
{
2635-
if (ConstraintNameIsUsed(RelationGetRelid(rel),
2635+
if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
2636+
RelationGetRelid(rel),
26362637
RelationGetNamespace(rel),
26372638
constr->name))
26382639
elog(ERROR, "constraint \"%s\" already exists for relation \"%s\"",
26392640
constr->name, RelationGetRelationName(rel));
26402641
}
26412642
else
2642-
constr->name = GenerateConstraintName(RelationGetRelid(rel),
2643+
constr->name = GenerateConstraintName(CONSTRAINT_RELATION,
2644+
RelationGetRelid(rel),
26432645
RelationGetNamespace(rel),
26442646
&counter);
26452647

@@ -2668,15 +2670,17 @@ AlterTableAddConstraint(Oid myrelid, bool recurse,
26682670
*/
26692671
if (fkconstraint->constr_name)
26702672
{
2671-
if (ConstraintNameIsUsed(RelationGetRelid(rel),
2673+
if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
2674+
RelationGetRelid(rel),
26722675
RelationGetNamespace(rel),
26732676
fkconstraint->constr_name))
26742677
elog(ERROR, "constraint \"%s\" already exists for relation \"%s\"",
26752678
fkconstraint->constr_name,
26762679
RelationGetRelationName(rel));
26772680
}
26782681
else
2679-
fkconstraint->constr_name = GenerateConstraintName(RelationGetRelid(rel),
2682+
fkconstraint->constr_name = GenerateConstraintName(CONSTRAINT_RELATION,
2683+
RelationGetRelid(rel),
26802684
RelationGetNamespace(rel),
26812685
&counter);
26822686

@@ -2734,7 +2738,7 @@ AlterTableAddCheckConstraint(Relation rel, Constraint *constr)
27342738
/*
27352739
* Convert the A_EXPR in raw_expr into an EXPR
27362740
*/
2737-
expr = transformExpr(pstate, constr->raw_expr);
2741+
expr = transformExpr(pstate, constr->raw_expr, NULL);
27382742

27392743
/*
27402744
* Make sure it yields a boolean result.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy