diff options
author | Vadim B. Mikheev <vadim4o@yahoo.com> | 1997-08-19 04:46:15 +0000 |
---|---|---|
committer | Vadim B. Mikheev <vadim4o@yahoo.com> | 1997-08-19 04:46:15 +0000 |
commit | b992e200b8872ecb6652ec85111995f8d4c5aee0 (patch) | |
tree | 52ce3eed9d36e779fe3fa729c12757b13a521b56 /src/backend | |
parent | b99c63cfc029cc0552e98f652d1734aec1124a5b (diff) | |
download | postgresql-b992e200b8872ecb6652ec85111995f8d4c5aee0.tar.gz postgresql-b992e200b8872ecb6652ec85111995f8d4c5aee0.zip |
NOT NULL implementation (submitted by Robson Paniago de Miranda).
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/common/tupdesc.c | 19 | ||||
-rw-r--r-- | src/backend/catalog/heap.c | 25 | ||||
-rw-r--r-- | src/backend/catalog/index.c | 24 | ||||
-rw-r--r-- | src/backend/commands/command.c | 9 | ||||
-rw-r--r-- | src/backend/commands/copy.c | 18 | ||||
-rw-r--r-- | src/backend/commands/creatinh.c | 9 | ||||
-rw-r--r-- | src/backend/executor/execMain.c | 33 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 12 | ||||
-rw-r--r-- | src/backend/utils/cache/relcache.c | 25 |
9 files changed, 134 insertions, 40 deletions
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index f0c8cbec6b1..c86027bc1d7 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.13 1997/08/18 20:51:31 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.14 1997/08/19 04:42:31 vadim Exp $ * * NOTES * some of the executor utility code such as "ExecTypeFromTL" should be @@ -60,6 +60,7 @@ CreateTemplateTupleDesc(int natts) size = natts * sizeof (AttributeTupleForm); desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); desc->attrs = (AttributeTupleForm*) palloc(size); + desc->constr = NULL; memset(desc->attrs, 0, size); desc->natts = natts; @@ -87,7 +88,7 @@ CreateTupleDesc(int natts, AttributeTupleForm* attrs) desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); desc->attrs = attrs; desc->natts = natts; - + desc->constr = NULL; return (desc); } @@ -117,6 +118,11 @@ CreateTupleDescCopy(TupleDesc tupdesc) tupdesc->attrs[i], ATTRIBUTE_TUPLE_SIZE); } + if (tupdesc->constr) { + desc->constr = (AttrConstr *) palloc(sizeof(struct attrConstr)); + memmove(desc->constr, tupdesc->constr, sizeof(struct attrConstr)); + } else + desc->constr = NULL; return desc; } @@ -379,6 +385,15 @@ BuildDescForRelation(List *schema, char *relname) if (entry->typename->typlen > 0) { desc->attrs[attnum - 1]->attlen = entry->typename->typlen; } + + /* This is for constraints */ + if (entry->is_not_null) { + if (!desc->constr) + desc->constr = (AttrConstr *) palloc(sizeof(struct attrConstr)); + desc->constr->has_not_null = true; + } + desc->attrs[attnum-1]->attnotnull = entry->is_not_null; + } return desc; } diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 61c38d0dd99..986c7a0826a 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.15 1997/08/12 22:52:07 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.16 1997/08/19 04:42:54 vadim Exp $ * * INTERFACE ROUTINES * heap_creatr() - Create an uncataloged heap relation @@ -72,57 +72,57 @@ static FormData_pg_attribute a1 = { 0xffffffff, {"ctid"}, 27l, 0l, 0l, 0l, sizeof (ItemPointerData), - SelfItemPointerAttributeNumber, 0, '\0', '\001', 0l, 'i' + SelfItemPointerAttributeNumber, 0, '\0', '\001', 0l, 'i', '\0' }; static FormData_pg_attribute a2 = { 0xffffffff, {"oid"}, 26l, 0l, 0l, 0l, sizeof(Oid), - ObjectIdAttributeNumber, 0, '\001', '\001', 0l, 'i' + ObjectIdAttributeNumber, 0, '\001', '\001', 0l, 'i','\0' }; static FormData_pg_attribute a3 = { 0xffffffff, {"xmin"}, 28l, 0l, 0l, 0l, sizeof (TransactionId), - MinTransactionIdAttributeNumber, 0, '\0', '\001', 0l, 'i', + MinTransactionIdAttributeNumber, 0, '\0', '\001', 0l, 'i', '\0' }; static FormData_pg_attribute a4 = { 0xffffffff, {"cmin"}, 29l, 0l, 0l, 0l, sizeof (CommandId), - MinCommandIdAttributeNumber, 0, '\001', '\001', 0l, 's' + MinCommandIdAttributeNumber, 0, '\001', '\001', 0l, 's', '\0' }; static FormData_pg_attribute a5 = { 0xffffffff, {"xmax"}, 28l, 0l, 0l, 0l, sizeof (TransactionId), - MaxTransactionIdAttributeNumber, 0, '\0', '\001', 0l, 'i' + MaxTransactionIdAttributeNumber, 0, '\0', '\001', 0l, 'i', '\0' }; static FormData_pg_attribute a6 = { 0xffffffff, {"cmax"}, 29l, 0l, 0l, 0l, sizeof (CommandId), - MaxCommandIdAttributeNumber, 0, '\001', '\001', 0l, 's' + MaxCommandIdAttributeNumber, 0, '\001', '\001', 0l, 's', '\0' }; static FormData_pg_attribute a7 = { 0xffffffff, {"chain"}, 27l, 0l, 0l, 0l, sizeof (ItemPointerData), - ChainItemPointerAttributeNumber, 0, '\0', '\001', 0l, 'i', + ChainItemPointerAttributeNumber, 0, '\0', '\001', 0l, 'i', '\0' }; static FormData_pg_attribute a8 = { 0xffffffff, {"anchor"}, 27l, 0l, 0l, 0l, sizeof (ItemPointerData), - AnchorItemPointerAttributeNumber, 0, '\0', '\001', 0l, 'i' + AnchorItemPointerAttributeNumber, 0, '\0', '\001', 0l, 'i', '\0' }; static FormData_pg_attribute a9 = { 0xffffffff, {"tmin"}, 20l, 0l, 0l, 0l, sizeof (AbsoluteTime), - MinAbsoluteTimeAttributeNumber, 0, '\001', '\001', 0l, 'i' + MinAbsoluteTimeAttributeNumber, 0, '\001', '\001', 0l, 'i', '\0' }; static FormData_pg_attribute a10 = { 0xffffffff, {"tmax"}, 20l, 0l, 0l, 0l, sizeof (AbsoluteTime), - MaxAbsoluteTimeAttributeNumber, 0, '\001', '\001', 0l, 'i' + MaxAbsoluteTimeAttributeNumber, 0, '\001', '\001', 0l, 'i', '\0' }; static FormData_pg_attribute a11 = { 0xffffffff, {"vtype"}, 18l, 0l, 0l, 0l, sizeof (char), - VersionTypeAttributeNumber, 0, '\001', '\001', 0l, 'c' + VersionTypeAttributeNumber, 0, '\001', '\001', 0l, 'c', '\0' }; static AttributeTupleForm HeapAtt[] = @@ -565,7 +565,6 @@ AddNewAttributeTuples(Oid new_rel_oid, (char *) *dpp); heap_insert(rdesc, tup); - if (hasindex) CatalogIndexInsert(idescs, Num_pg_attr_indices, rdesc, tup); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 89497ee6eb5..8c453f60471 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.16 1997/08/12 22:52:09 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.17 1997/08/19 04:42:55 vadim Exp $ * * * INTERFACE ROUTINES @@ -112,17 +112,17 @@ static void DefaultBuild(Relation heapRelation, Relation indexRelation, * ---------------------------------------------------------------- */ static FormData_pg_attribute sysatts[] = { - { 0l, {"ctid"}, 27l, 0l, 0l, 0l, 6, -1, 0, '\0', '\001', 0l, 'i' }, - { 0l, {"oid"}, 26l, 0l, 0l, 0l, 4, -2, 0, '\001', '\001', 0l, 'i' }, - { 0l, {"xmin"}, 28l, 0l, 0l, 0l, 5, -3, 0, '\0', '\001', 0l, 'i' }, - { 0l, {"cmin"}, 29l, 0l, 0l, 0l, 1, -4, 0, '\001', '\001', 0l, 's' }, - { 0l, {"xmax"}, 28l, 0l, 0l, 0l, 5, -5, 0, '\0', '\001', 0l, 'i' }, - { 0l, {"cmax"}, 29l, 0l, 0l, 0l, 1, -6, 0, '\001', '\001', 0l, 's' }, - { 0l, {"chain"}, 27l, 0l, 0l, 0l, 6, -7, 0, '\0', '\001', 0l, 'i' }, - { 0l, {"anchor"}, 27l, 0l, 0l, 0l, 6, -8, 0, '\0', '\001', 0l, 'i' }, - { 0l, {"tmin"}, 20l, 0l, 0l, 0l, 4, -9, 0, '\001', '\001', 0l, 'i' }, - { 0l, {"tmax"}, 20l, 0l, 0l, 0l, 4, -10, 0, '\001', '\001', 0l, 'i' }, - { 0l, {"vtype"}, 18l, 0l, 0l, 0l, 1, -11, 0, '\001', '\001', 0l, 'c' }, + { 0l, {"ctid"}, 27l, 0l, 0l, 0l, 6, -1, 0, '\0', '\001', 0l, 'i', '\0' }, + { 0l, {"oid"}, 26l, 0l, 0l, 0l, 4, -2, 0, '\001', '\001', 0l, 'i', '\0' }, + { 0l, {"xmin"}, 28l, 0l, 0l, 0l, 5, -3, 0, '\0', '\001', 0l, 'i', '\0' }, + { 0l, {"cmin"}, 29l, 0l, 0l, 0l, 1, -4, 0, '\001', '\001', 0l, 's', '\0' }, + { 0l, {"xmax"}, 28l, 0l, 0l, 0l, 5, -5, 0, '\0', '\001', 0l, 'i', '\0' }, + { 0l, {"cmax"}, 29l, 0l, 0l, 0l, 1, -6, 0, '\001', '\001', 0l, 's', '\0' }, + { 0l, {"chain"}, 27l, 0l, 0l, 0l, 6, -7, 0, '\0', '\001', 0l, 'i', '\0' }, + { 0l, {"anchor"}, 27l, 0l, 0l, 0l, 6, -8, 0, '\0', '\001', 0l, 'i', '\0' }, + { 0l, {"tmin"}, 20l, 0l, 0l, 0l, 4, -9, 0, '\001', '\001', 0l, 'i', '\0' }, + { 0l, {"tmax"}, 20l, 0l, 0l, 0l, 4, -10, 0, '\001', '\001', 0l, 'i', '\0' }, + { 0l, {"vtype"}, 18l, 0l, 0l, 0l, 1, -11, 0, '\001', '\001', 0l, 'c', '\0' }, }; /* ---------------------------------------------------------------- diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index 74941993e47..6cbe9bda767 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.9 1997/08/18 20:52:11 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.10 1997/08/19 04:43:27 vadim Exp $ * * NOTES * The PortalExecutorHeapMemory crap needs to be eliminated @@ -279,7 +279,11 @@ PerformAddAttribute(char *relationName, elog(WARN, "PerformAddAttribute: you do not own class \"%s\"", relationName); #endif - + /* + * we can't add a not null attribute + */ + if (colDef->is_not_null) + elog(WARN,"Can't add a not null attribute to a existent relation"); /* * if the first element in the 'schema' list is a "*" then we are * supposed to add this attribute to all classes that inherit from @@ -454,6 +458,7 @@ PerformAddAttribute(char *relationName, attribute->attcacheoff = -1; attribute->attisset = (bool) (form->typtype == 'c'); attribute->attalign = form->typalign; + attribute->attnotnull = false; heap_insert(attrdesc, attributeTuple); if (hasindex) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index b44414000b2..ee7948ac425 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -6,7 +6,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.25 1997/08/18 02:14:34 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.26 1997/08/19 04:43:28 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -602,6 +602,22 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim) tuple = heap_formtuple(tupDesc, values, nulls); if (oids) tuple->t_oid = loaded_oid; + + /* ---------------- + * Check the constraints of a tuple + * ---------------- + */ + + if (rel->rd_att->constr && rel->rd_att->constr->has_not_null) + { + int attrChk; + for (attrChk = 1; attrChk <= rel->rd_att->natts; attrChk++) { + if (rel->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull(tuple,attrChk)) + elog(WARN,"CopyFrom: Fail to add null value in not null attribute %s", + rel->rd_att->attrs[attrChk-1]->attname.data); + } + } + heap_insert(rel, tuple); if (has_index) { diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index 1113a84e26f..28143a993b6 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.11 1997/08/18 20:52:16 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.12 1997/08/19 04:43:30 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -276,14 +276,16 @@ MergeAttributes(List *schema, List *supers) AttributeTupleForm attribute = tupleDesc->attrs[attrno]; char *attributeName; char *attributeType; + AttrConstr constraints; HeapTuple tuple; ColumnDef *def; TypeName *typename; /* - * form name and type + * form name, type and constraints */ attributeName = (attribute->attname).data; + constraints.has_not_null = attribute->attnotnull; tuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(attribute->atttypid), @@ -311,7 +313,8 @@ MergeAttributes(List *schema, List *supers) def->colname = pstrdup(attributeName); typename->name = pstrdup(attributeType); def->typename = typename; - partialResult = lcons(def, partialResult); + def->is_not_null = constraints.has_not_null; + partialResult = lcons(def, partialResult); } /* diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index b79be5d746f..b839ececc09 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.15 1997/08/18 20:52:25 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.16 1997/08/19 04:43:45 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -401,6 +401,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) if (resultRelation != 0 && operation != CMD_SELECT) { /* ---------------- * if we have a result relation, open it and + * initialize the result relation info stuff. * ---------------- */ @@ -911,6 +912,21 @@ ExecAppend(TupleTableSlot *slot, */ /* ---------------- + * Check the constraints of a tuple + * ---------------- + */ + + if (resultRelationDesc->rd_att->constr && resultRelationDesc->rd_att->constr->has_not_null) + { + int attrChk; + for (attrChk = 1; attrChk <= resultRelationDesc->rd_att->natts; attrChk++) { + if (resultRelationDesc->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull(tuple,attrChk)) + elog(WARN,"ExecAppend: Fail to add null value in not null attribute %s", + resultRelationDesc->rd_att->attrs[attrChk-1]->attname.data); + } + } + + /* ---------------- * insert the tuple * ---------------- */ @@ -1031,6 +1047,21 @@ ExecReplace(TupleTableSlot *slot, */ /* ---------------- + * Check the constraints of a tuple + * ---------------- + */ + + if (resultRelationDesc->rd_att->constr && resultRelationDesc->rd_att->constr->has_not_null) + { + int attrChk; + for (attrChk = 1; attrChk <= resultRelationDesc->rd_att->natts; attrChk++) { + if (resultRelationDesc->rd_att->attrs[attrChk-1]->attnotnull && heap_attisnull(tuple,attrChk)) + elog(WARN,"ExecReplace: Fail to update null value in not null attribute %s", + resultRelationDesc->rd_att->attrs[attrChk-1]->attname.data); + } + } + + /* ---------------- * replace the heap tuple * * Don't want to continue if our heap_replace didn't actually diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 32d32e6b535..0cd06b75dc7 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.35 1997/08/12 20:15:33 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.36 1997/08/19 04:44:01 vadim Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -135,7 +135,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr); def_list, opt_indirection, group_clause, groupby_list %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy, - index_opt_unique, opt_verbose, opt_analyze + index_opt_unique, opt_verbose, opt_analyze, opt_null %type <ival> copy_dirn, archive_type, OptArchiveType, OptArchiveLocation, def_type, opt_direction, remove_type, opt_column, event @@ -333,14 +333,20 @@ AddAttrStmt: ALTER TABLE relation_name opt_inh_star ADD COLUMN columnDef } ; -columnDef: Id Typename +columnDef: Id Typename opt_null { $$ = makeNode(ColumnDef); $$->colname = $1; $$->typename = $2; + $$->is_not_null = $3; } ; +opt_null: PNULL { $$ = false; } + | NOT PNULL { $$ = true; } + | NOTNULL { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; /***************************************************************************** * diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index d7bb7e79faf..585d82fc126 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.13 1997/08/18 20:53:48 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.14 1997/08/19 04:44:21 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -506,7 +506,7 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, HeapScanDesc pg_attribute_scan; ScanKeyData key; int need; - + /* ---------------- * form a scan key * ---------------- @@ -529,6 +529,10 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, * ---------------- */ need = natts; + if (!relation->rd_att->constr) + relation->rd_att->constr = (AttrConstr *) palloc(sizeof(struct attrConstr)); + relation->rd_att->constr->has_not_null = false; + pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL); while (HeapTupleIsValid(pg_attribute_tuple) && need > 0) { attp = (AttributeTupleForm) GETSTRUCT(pg_attribute_tuple); @@ -540,6 +544,11 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]), (char *) attp, ATTRIBUTE_TUPLE_SIZE); + + /* Update if this attribute have a constraint */ + if (attp->attnotnull) + relation->rd_att->constr->has_not_null = true; + need--; } pg_attribute_tuple = heap_getnext(pg_attribute_scan, @@ -567,6 +576,10 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo, Relation attrel; HeapTuple atttup; int i; + + if (!relation->rd_att->constr) + relation->rd_att->constr = (AttrConstr *) palloc(sizeof(struct attrConstr)); + relation->rd_att->constr->has_not_null = false; attrel = heap_openr(AttributeRelationName); @@ -585,6 +598,10 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo, memmove((char *) (relation->rd_att->attrs[i - 1]), (char *) attp, ATTRIBUTE_TUPLE_SIZE); + + /* Update if this attribute have a constraint */ + if (attp->attnotnull) + relation->rd_att->constr->has_not_null = true; } heap_close(attrel); @@ -1229,7 +1246,9 @@ RelationFlushRelation(Relation *relationPtr, for (i = 0; i < relation->rd_rel->relnatts; i++, p++) pfree (*p); pfree (relation->rd_att->attrs); - pfree (relation->rd_att); + if (relation->rd_att->constr) + pfree (relation->rd_att->constr); + pfree (relation->rd_att); #if 0 if (relation->rd_rules) { |