diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/command.c | 7 | ||||
-rw-r--r-- | src/backend/commands/creatinh.c | 166 | ||||
-rw-r--r-- | src/backend/commands/sequence.c | 3 | ||||
-rw-r--r-- | src/backend/commands/view.c | 5 |
4 files changed, 121 insertions, 60 deletions
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index 8872bcdfac7..3e71e7d1927 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.54 1999/09/18 19:06:40 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.55 1999/10/03 23:55:27 tgl Exp $ * * NOTES * The PortalExecutorHeapMemory crap needs to be eliminated @@ -324,7 +324,7 @@ PerformAddAttribute(char *relationName, */ if (colDef->is_not_null) elog(ERROR, "Can't add a NOT NULL attribute to an existing relation"); - if (colDef->defval) + if (colDef->raw_default || colDef->cooked_default) elog(ERROR, "ADD ATTRIBUTE: DEFAULT not yet implemented"); /* @@ -457,7 +457,8 @@ PerformAddAttribute(char *relationName, attribute->attisset = (bool) (tform->typtype == 'c'); attribute->attalign = tform->typalign; attribute->attnotnull = false; - attribute->atthasdef = (colDef->defval != NULL); + attribute->atthasdef = (colDef->raw_default != NULL || + colDef->cooked_default != NULL); heap_insert(attrdesc, attributeTuple); if (hasindex) diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index c146afa1db4..0b2d2360b3c 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.47 1999/09/23 17:02:40 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.48 1999/10/03 23:55:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -45,15 +45,19 @@ DefineRelation(CreateStmt *stmt, char relkind) List *schema = stmt->tableElts; int numberOfAttributes; Oid relationId; - List *inheritList = NULL; + Relation rel; + List *inheritList; TupleDesc descriptor; - List *constraints; + List *old_constraints; + List *rawDefaults; + List *listptr; + int i; + AttrNumber attnum; if (strlen(stmt->relname) >= NAMEDATALEN) - elog(ERROR, "the relation name %s is >= %d characters long", stmt->relname, - NAMEDATALEN); - StrNCpy(relname, stmt->relname, NAMEDATALEN); /* make full length for - * copy */ + elog(ERROR, "the relation name %s is >= %d characters long", + stmt->relname, NAMEDATALEN); + StrNCpy(relname, stmt->relname, NAMEDATALEN); /* ---------------- * Handle parameters @@ -66,8 +70,7 @@ DefineRelation(CreateStmt *stmt, char relkind) * generate relation schema, including inherited attributes. * ---------------- */ - schema = MergeAttributes(schema, inheritList, &constraints); - constraints = nconc(constraints, stmt->constraints); + schema = MergeAttributes(schema, inheritList, &old_constraints); numberOfAttributes = length(schema); if (numberOfAttributes <= 0) @@ -78,53 +81,53 @@ DefineRelation(CreateStmt *stmt, char relkind) /* ---------------- * create a relation descriptor from the relation schema - * and create the relation. + * and create the relation. Note that in this stage only + * inherited (pre-cooked) defaults and constraints will be + * included into the new relation. (BuildDescForRelation + * takes care of the inherited defaults, but we have to copy + * inherited constraints here.) * ---------------- */ descriptor = BuildDescForRelation(schema, relname); - if (constraints != NIL) + if (old_constraints != NIL) { - List *entry; - int nconstr = length(constraints), - ncheck = 0, - i; - ConstrCheck *check = (ConstrCheck *) palloc(nconstr * sizeof(ConstrCheck)); + ConstrCheck *check = (ConstrCheck *) palloc(length(old_constraints) * + sizeof(ConstrCheck)); + int ncheck = 0; - foreach(entry, constraints) + foreach(listptr, old_constraints) { - Constraint *cdef = (Constraint *) lfirst(entry); + Constraint *cdef = (Constraint *) lfirst(listptr); - if (cdef->contype == CONSTR_CHECK) + if (cdef->contype != CONSTR_CHECK) + continue; + + if (cdef->name != NULL) { - if (cdef->name != NULL) - { - for (i = 0; i < ncheck; i++) - { - if (strcmp(check[i].ccname, cdef->name) == 0) - elog(ERROR, - "DefineRelation: name (%s) of CHECK constraint duplicated", - cdef->name); - } - check[ncheck].ccname = cdef->name; - } - else + for (i = 0; i < ncheck; i++) { - check[ncheck].ccname = (char *) palloc(NAMEDATALEN); - snprintf(check[ncheck].ccname, NAMEDATALEN, "$%d", ncheck + 1); + if (strcmp(check[i].ccname, cdef->name) == 0) + elog(ERROR, "Duplicate CHECK constraint name: '%s'", + cdef->name); } - check[ncheck].ccbin = NULL; - check[ncheck].ccsrc = (char *) cdef->def; - ncheck++; + check[ncheck].ccname = cdef->name; } + else + { + check[ncheck].ccname = (char *) palloc(NAMEDATALEN); + snprintf(check[ncheck].ccname, NAMEDATALEN, "$%d", ncheck + 1); + } + Assert(cdef->raw_expr == NULL && cdef->cooked_expr != NULL); + check[ncheck].ccbin = pstrdup(cdef->cooked_expr); + ncheck++; } if (ncheck > 0) { - if (ncheck < nconstr) - check = (ConstrCheck *) repalloc(check, ncheck * sizeof(ConstrCheck)); if (descriptor->constr == NULL) { descriptor->constr = (TupleConstr *) palloc(sizeof(TupleConstr)); + descriptor->constr->defval = NULL; descriptor->constr->num_defval = 0; descriptor->constr->has_not_null = false; } @@ -137,6 +140,61 @@ DefineRelation(CreateStmt *stmt, char relkind) relkind, stmt->istemp); StoreCatalogInheritance(relationId, inheritList); + + /* + * Now add any newly specified column default values + * and CHECK constraints to the new relation. These are passed + * to us in the form of raw parsetrees; we need to transform + * them to executable expression trees before they can be added. + * The most convenient way to do that is to apply the parser's + * transformExpr routine, but transformExpr doesn't work unless + * we have a pre-existing relation. So, the transformation has + * to be postponed to this final step of CREATE TABLE. + * + * First, scan schema to find new column defaults. + */ + rawDefaults = NIL; + attnum = 0; + + foreach(listptr, schema) + { + ColumnDef *colDef = lfirst(listptr); + RawColumnDefault *rawEnt; + + attnum++; + + if (colDef->raw_default == NULL) + continue; + Assert(colDef->cooked_default == NULL); + + rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault)); + rawEnt->attnum = attnum; + rawEnt->raw_default = colDef->raw_default; + rawDefaults = lappend(rawDefaults, rawEnt); + } + + /* If no raw defaults and no constraints, nothing to do. */ + if (rawDefaults == NIL && stmt->constraints == NIL) + return; + + /* + * We must bump the command counter to make the newly-created + * relation tuple visible for opening. + */ + CommandCounterIncrement(); + /* + * Open the new relation. + */ + rel = heap_openr(relname, AccessExclusiveLock); + /* + * Parse and add the defaults/constraints. + */ + AddRelationRawConstraints(rel, rawDefaults, stmt->constraints); + /* + * Clean up. We keep lock on new relation (although it shouldn't + * be visible to anyone else anyway, until commit). + */ + heap_close(rel, NoLock); } /* @@ -164,18 +222,14 @@ RemoveRelation(char *name) * Exceptions: * BadArg if name is invalid * - * * Note: * Rows are removed, indices are truncated and reconstructed. */ - void TruncateRelation(char *name) { - - AssertArg(name); - heap_truncate(name); - + AssertArg(name); + heap_truncate(name); } /* @@ -316,22 +370,25 @@ MergeAttributes(List *schema, List *supers, List **supconstr) typename->typmod = attribute->atttypmod; def->typename = typename; def->is_not_null = attribute->attnotnull; - def->defval = NULL; + def->raw_default = NULL; + def->cooked_default = NULL; if (attribute->atthasdef) { - AttrDefault *attrdef = constr->defval; + AttrDefault *attrdef; int i; - Assert(constr != NULL && constr->num_defval > 0); + Assert(constr != NULL); + attrdef = constr->defval; for (i = 0; i < constr->num_defval; i++) { - if (attrdef[i].adnum != attrno + 1) - continue; - def->defval = pstrdup(attrdef[i].adsrc); - break; + if (attrdef[i].adnum == attrno + 1) + { + def->cooked_default = pstrdup(attrdef[i].adbin); + break; + } } - Assert(def->defval != NULL); + Assert(def->cooked_default != NULL); } partialResult = lcons(def, partialResult); } @@ -343,14 +400,15 @@ MergeAttributes(List *schema, List *supers, List **supconstr) for (i = 0; i < constr->num_check; i++) { - Constraint *cdef = (Constraint *) makeNode(Constraint); + Constraint *cdef = makeNode(Constraint); cdef->contype = CONSTR_CHECK; if (check[i].ccname[0] == '$') cdef->name = NULL; else cdef->name = pstrdup(check[i].ccname); - cdef->def = (void *) pstrdup(check[i].ccsrc); + cdef->raw_expr = NULL; + cdef->cooked_expr = pstrdup(check[i].ccbin); constraints = lappend(constraints, cdef); } } diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index be47d32f9f9..228aaba7990 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -96,7 +96,8 @@ DefineSequence(CreateSeqStmt *seq) typnam->typmod = -1; coldef = makeNode(ColumnDef); coldef->typename = typnam; - coldef->defval = NULL; + coldef->raw_default = NULL; + coldef->cooked_default = NULL; coldef->is_not_null = false; null[i - 1] = ' '; diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 5baf4eceac8..a88b1840dd3 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: view.c,v 1.37 1999/07/17 20:16:54 momjian Exp $ + * $Id: view.c,v 1.38 1999/10/03 23:55:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -76,7 +76,8 @@ DefineVirtualRelation(char *relname, List *tlist) def->typename = typename; def->is_not_null = false; - def->defval = (char *) NULL; + def->raw_default = NULL; + def->cooked_default = NULL; attrList = lappend(attrList, def); } |