Commit b992e200 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

NOT NULL implementation (submitted by Robson Paniago de Miranda).

parent b99c63cf
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be * some of the executor utility code such as "ExecTypeFromTL" should be
...@@ -60,6 +60,7 @@ CreateTemplateTupleDesc(int natts) ...@@ -60,6 +60,7 @@ CreateTemplateTupleDesc(int natts)
size = natts * sizeof (AttributeTupleForm); size = natts * sizeof (AttributeTupleForm);
desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
desc->attrs = (AttributeTupleForm*) palloc(size); desc->attrs = (AttributeTupleForm*) palloc(size);
desc->constr = NULL;
memset(desc->attrs, 0, size); memset(desc->attrs, 0, size);
desc->natts = natts; desc->natts = natts;
...@@ -87,7 +88,7 @@ CreateTupleDesc(int natts, AttributeTupleForm* attrs) ...@@ -87,7 +88,7 @@ CreateTupleDesc(int natts, AttributeTupleForm* attrs)
desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
desc->attrs = attrs; desc->attrs = attrs;
desc->natts = natts; desc->natts = natts;
desc->constr = NULL;
return (desc); return (desc);
} }
...@@ -117,6 +118,11 @@ CreateTupleDescCopy(TupleDesc tupdesc) ...@@ -117,6 +118,11 @@ CreateTupleDescCopy(TupleDesc tupdesc)
tupdesc->attrs[i], tupdesc->attrs[i],
ATTRIBUTE_TUPLE_SIZE); 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; return desc;
} }
...@@ -379,6 +385,15 @@ BuildDescForRelation(List *schema, char *relname) ...@@ -379,6 +385,15 @@ BuildDescForRelation(List *schema, char *relname)
if (entry->typename->typlen > 0) { if (entry->typename->typlen > 0) {
desc->attrs[attnum - 1]->attlen = entry->typename->typlen; 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; return desc;
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
* heap_creatr() - Create an uncataloged heap relation * heap_creatr() - Create an uncataloged heap relation
...@@ -72,57 +72,57 @@ ...@@ -72,57 +72,57 @@
static FormData_pg_attribute a1 = { static FormData_pg_attribute a1 = {
0xffffffff, {"ctid"}, 27l, 0l, 0l, 0l, sizeof (ItemPointerData), 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 = { static FormData_pg_attribute a2 = {
0xffffffff, {"oid"}, 26l, 0l, 0l, 0l, sizeof(Oid), 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 = { static FormData_pg_attribute a3 = {
0xffffffff, {"xmin"}, 28l, 0l, 0l, 0l, sizeof (TransactionId), 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 = { static FormData_pg_attribute a4 = {
0xffffffff, {"cmin"}, 29l, 0l, 0l, 0l, sizeof (CommandId), 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 = { static FormData_pg_attribute a5 = {
0xffffffff, {"xmax"}, 28l, 0l, 0l, 0l, sizeof (TransactionId), 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 = { static FormData_pg_attribute a6 = {
0xffffffff, {"cmax"}, 29l, 0l, 0l, 0l, sizeof (CommandId), 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 = { static FormData_pg_attribute a7 = {
0xffffffff, {"chain"}, 27l, 0l, 0l, 0l, sizeof (ItemPointerData), 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 = { static FormData_pg_attribute a8 = {
0xffffffff, {"anchor"}, 27l, 0l, 0l, 0l, sizeof (ItemPointerData), 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 = { static FormData_pg_attribute a9 = {
0xffffffff, {"tmin"}, 20l, 0l, 0l, 0l, sizeof (AbsoluteTime), 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 = { static FormData_pg_attribute a10 = {
0xffffffff, {"tmax"}, 20l, 0l, 0l, 0l, sizeof (AbsoluteTime), 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 = { static FormData_pg_attribute a11 = {
0xffffffff, {"vtype"}, 18l, 0l, 0l, 0l, sizeof (char), 0xffffffff, {"vtype"}, 18l, 0l, 0l, 0l, sizeof (char),
VersionTypeAttributeNumber, 0, '\001', '\001', 0l, 'c' VersionTypeAttributeNumber, 0, '\001', '\001', 0l, 'c', '\0'
}; };
static AttributeTupleForm HeapAtt[] = static AttributeTupleForm HeapAtt[] =
...@@ -565,7 +565,6 @@ AddNewAttributeTuples(Oid new_rel_oid, ...@@ -565,7 +565,6 @@ AddNewAttributeTuples(Oid new_rel_oid,
(char *) *dpp); (char *) *dpp);
heap_insert(rdesc, tup); heap_insert(rdesc, tup);
if (hasindex) if (hasindex)
CatalogIndexInsert(idescs, Num_pg_attr_indices, rdesc, tup); CatalogIndexInsert(idescs, Num_pg_attr_indices, rdesc, tup);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
...@@ -112,17 +112,17 @@ static void DefaultBuild(Relation heapRelation, Relation indexRelation, ...@@ -112,17 +112,17 @@ static void DefaultBuild(Relation heapRelation, Relation indexRelation,
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
static FormData_pg_attribute sysatts[] = { static FormData_pg_attribute sysatts[] = {
{ 0l, {"ctid"}, 27l, 0l, 0l, 0l, 6, -1, 0, '\0', '\001', 0l, 'i' }, { 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' }, { 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' }, { 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' }, { 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' }, { 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' }, { 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' }, { 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' }, { 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' }, { 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' }, { 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' }, { 0l, {"vtype"}, 18l, 0l, 0l, 0l, 1, -11, 0, '\001', '\001', 0l, 'c', '\0' },
}; };
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* The PortalExecutorHeapMemory crap needs to be eliminated * The PortalExecutorHeapMemory crap needs to be eliminated
...@@ -279,7 +279,11 @@ PerformAddAttribute(char *relationName, ...@@ -279,7 +279,11 @@ PerformAddAttribute(char *relationName,
elog(WARN, "PerformAddAttribute: you do not own class \"%s\"", elog(WARN, "PerformAddAttribute: you do not own class \"%s\"",
relationName); relationName);
#endif #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 * if the first element in the 'schema' list is a "*" then we are
* supposed to add this attribute to all classes that inherit from * supposed to add this attribute to all classes that inherit from
...@@ -454,6 +458,7 @@ PerformAddAttribute(char *relationName, ...@@ -454,6 +458,7 @@ PerformAddAttribute(char *relationName,
attribute->attcacheoff = -1; attribute->attcacheoff = -1;
attribute->attisset = (bool) (form->typtype == 'c'); attribute->attisset = (bool) (form->typtype == 'c');
attribute->attalign = form->typalign; attribute->attalign = form->typalign;
attribute->attnotnull = false;
heap_insert(attrdesc, attributeTuple); heap_insert(attrdesc, attributeTuple);
if (hasindex) if (hasindex)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -602,6 +602,22 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
tuple = heap_formtuple(tupDesc, values, nulls); tuple = heap_formtuple(tupDesc, values, nulls);
if (oids) if (oids)
tuple->t_oid = loaded_oid; 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); heap_insert(rel, tuple);
if (has_index) { if (has_index) {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -276,14 +276,16 @@ MergeAttributes(List *schema, List *supers)
AttributeTupleForm attribute = tupleDesc->attrs[attrno]; AttributeTupleForm attribute = tupleDesc->attrs[attrno];
char *attributeName; char *attributeName;
char *attributeType; char *attributeType;
AttrConstr constraints;
HeapTuple tuple; HeapTuple tuple;
ColumnDef *def; ColumnDef *def;
TypeName *typename; TypeName *typename;
/* /*
* form name and type * form name, type and constraints
*/ */
attributeName = (attribute->attname).data; attributeName = (attribute->attname).data;
constraints.has_not_null = attribute->attnotnull;
tuple = tuple =
SearchSysCacheTuple(TYPOID, SearchSysCacheTuple(TYPOID,
ObjectIdGetDatum(attribute->atttypid), ObjectIdGetDatum(attribute->atttypid),
...@@ -311,6 +313,7 @@ MergeAttributes(List *schema, List *supers) ...@@ -311,6 +313,7 @@ MergeAttributes(List *schema, List *supers)
def->colname = pstrdup(attributeName); def->colname = pstrdup(attributeName);
typename->name = pstrdup(attributeType); typename->name = pstrdup(attributeType);
def->typename = typename; def->typename = typename;
def->is_not_null = constraints.has_not_null;
partialResult = lcons(def, partialResult); partialResult = lcons(def, partialResult);
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -401,6 +401,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
if (resultRelation != 0 && operation != CMD_SELECT) { if (resultRelation != 0 && operation != CMD_SELECT) {
/* ---------------- /* ----------------
* if we have a result relation, open it and * if we have a result relation, open it and
* initialize the result relation info stuff. * initialize the result relation info stuff.
* ---------------- * ----------------
*/ */
...@@ -910,6 +911,21 @@ ExecAppend(TupleTableSlot *slot, ...@@ -910,6 +911,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 * insert the tuple
* ---------------- * ----------------
...@@ -1030,6 +1046,21 @@ ExecReplace(TupleTableSlot *slot, ...@@ -1030,6 +1046,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 * replace the heap tuple
* *
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -135,7 +135,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr); ...@@ -135,7 +135,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
def_list, opt_indirection, group_clause, groupby_list def_list, opt_indirection, group_clause, groupby_list
%type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy, %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, %type <ival> copy_dirn, archive_type, OptArchiveType, OptArchiveLocation,
def_type, opt_direction, remove_type, opt_column, event def_type, opt_direction, remove_type, opt_column, event
...@@ -333,14 +333,20 @@ AddAttrStmt: ALTER TABLE relation_name opt_inh_star ADD COLUMN columnDef ...@@ -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); $$ = makeNode(ColumnDef);
$$->colname = $1; $$->colname = $1;
$$->typename = $2; $$->typename = $2;
$$->is_not_null = $3;
} }
; ;
opt_null: PNULL { $$ = false; }
| NOT PNULL { $$ = true; }
| NOTNULL { $$ = true; }
| /* EMPTY */ { $$ = false; }
;
/***************************************************************************** /*****************************************************************************
* *
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -529,6 +529,10 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, ...@@ -529,6 +529,10 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
* ---------------- * ----------------
*/ */
need = natts; 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); pg_attribute_tuple = heap_getnext(pg_attribute_scan, 0, (Buffer *) NULL);
while (HeapTupleIsValid(pg_attribute_tuple) && need > 0) { while (HeapTupleIsValid(pg_attribute_tuple) && need > 0) {
attp = (AttributeTupleForm) GETSTRUCT(pg_attribute_tuple); attp = (AttributeTupleForm) GETSTRUCT(pg_attribute_tuple);
...@@ -540,6 +544,11 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo, ...@@ -540,6 +544,11 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]), memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]),
(char *) attp, (char *) attp,
ATTRIBUTE_TUPLE_SIZE); ATTRIBUTE_TUPLE_SIZE);
/* Update if this attribute have a constraint */
if (attp->attnotnull)
relation->rd_att->constr->has_not_null = true;
need--; need--;
} }
pg_attribute_tuple = heap_getnext(pg_attribute_scan, pg_attribute_tuple = heap_getnext(pg_attribute_scan,
...@@ -568,6 +577,10 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo, ...@@ -568,6 +577,10 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
HeapTuple atttup; HeapTuple atttup;
int i; 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); attrel = heap_openr(AttributeRelationName);
for (i = 1; i <= relation->rd_rel->relnatts; i++) { for (i = 1; i <= relation->rd_rel->relnatts; i++) {
...@@ -585,6 +598,10 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo, ...@@ -585,6 +598,10 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
memmove((char *) (relation->rd_att->attrs[i - 1]), memmove((char *) (relation->rd_att->attrs[i - 1]),
(char *) attp, (char *) attp,
ATTRIBUTE_TUPLE_SIZE); ATTRIBUTE_TUPLE_SIZE);
/* Update if this attribute have a constraint */
if (attp->attnotnull)
relation->rd_att->constr->has_not_null = true;
} }
heap_close(attrel); heap_close(attrel);
...@@ -1229,6 +1246,8 @@ RelationFlushRelation(Relation *relationPtr, ...@@ -1229,6 +1246,8 @@ RelationFlushRelation(Relation *relationPtr,
for (i = 0; i < relation->rd_rel->relnatts; i++, p++) for (i = 0; i < relation->rd_rel->relnatts; i++, p++)
pfree (*p); pfree (*p);
pfree (relation->rd_att->attrs); pfree (relation->rd_att->attrs);
if (relation->rd_att->constr)
pfree (relation->rd_att->constr);
pfree (relation->rd_att); pfree (relation->rd_att);
#if 0 #if 0
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.36 1997/07/28 23:53:54 momjian Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.37 1997/08/19 04:44:38 vadim Exp $
* *
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
* *
...@@ -798,6 +798,8 @@ clearTableInfo(TableInfo *tblinfo, int numTables) ...@@ -798,6 +798,8 @@ clearTableInfo(TableInfo *tblinfo, int numTables)
if ( tblinfo[i].sequence ) if ( tblinfo[i].sequence )
continue; continue;
if (tblinfo[i].notnull) free (tblinfo[i].notnull);
/* Process Attributes */ /* Process Attributes */
for(j=0;j<tblinfo[i].numatts;j++) { for(j=0;j<tblinfo[i].numatts;j++) {
if(tblinfo[i].attnames[j]) free (tblinfo[i].attnames[j]); if(tblinfo[i].attnames[j]) free (tblinfo[i].attnames[j]);
...@@ -1233,6 +1235,7 @@ getTableAttrs(TableInfo* tblinfo, int numTables) ...@@ -1233,6 +1235,7 @@ getTableAttrs(TableInfo* tblinfo, int numTables)
int i_attname; int i_attname;
int i_typname; int i_typname;
int i_attlen; int i_attlen;
int i_attnotnull;
PGresult *res; PGresult *res;
int ntups; int ntups;
...@@ -1255,7 +1258,7 @@ getTableAttrs(TableInfo* tblinfo, int numTables) ...@@ -1255,7 +1258,7 @@ getTableAttrs(TableInfo* tblinfo, int numTables)
tblinfo[i].relname, tblinfo[i].relname,
g_comment_end); g_comment_end);
sprintf(q,"SELECT a.attnum, a.attname, t.typname, a.attlen " sprintf(q,"SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull "
"from pg_attribute a, pg_type t " "from pg_attribute a, pg_type t "
"where a.attrelid = '%s'::oid and a.atttypid = t.oid " "where a.attrelid = '%s'::oid and a.atttypid = t.oid "
"and a.attnum > 0 order by attnum", "and a.attnum > 0 order by attnum",
...@@ -1272,12 +1275,14 @@ getTableAttrs(TableInfo* tblinfo, int numTables) ...@@ -1272,12 +1275,14 @@ getTableAttrs(TableInfo* tblinfo, int numTables)
i_attname = PQfnumber(res,"attname"); i_attname = PQfnumber(res,"attname");
i_typname = PQfnumber(res,"typname"); i_typname = PQfnumber(res,"typname");
i_attlen = PQfnumber(res,"attlen"); i_attlen = PQfnumber(res,"attlen");
i_attnotnull = PQfnumber(res,"attnotnull");
tblinfo[i].numatts = ntups; tblinfo[i].numatts = ntups;
tblinfo[i].attnames = (char**) malloc( ntups * sizeof(char*)); tblinfo[i].attnames = (char**) malloc( ntups * sizeof(char*));
tblinfo[i].typnames = (char**) malloc( ntups * sizeof(char*)); tblinfo[i].typnames = (char**) malloc( ntups * sizeof(char*));
tblinfo[i].attlen = (int*) malloc(ntups * sizeof(int)); tblinfo[i].attlen = (int*) malloc(ntups * sizeof(int));
tblinfo[i].inhAttrs = (int*) malloc (ntups * sizeof(int)); tblinfo[i].inhAttrs = (int*) malloc (ntups * sizeof(int));
tblinfo[i].notnull = (bool*) malloc (ntups * sizeof(bool));
tblinfo[i].parentRels = NULL; tblinfo[i].parentRels = NULL;
tblinfo[i].numParents = 0; tblinfo[i].numParents = 0;
for (j=0;j<ntups;j++) { for (j=0;j<ntups;j++) {
...@@ -1287,6 +1292,7 @@ getTableAttrs(TableInfo* tblinfo, int numTables) ...@@ -1287,6 +1292,7 @@ getTableAttrs(TableInfo* tblinfo, int numTables)
if (tblinfo[i].attlen[j] > 0) if (tblinfo[i].attlen[j] > 0)
tblinfo[i].attlen[j] = tblinfo[i].attlen[j] - 4; tblinfo[i].attlen[j] = tblinfo[i].attlen[j] - 4;
tblinfo[i].inhAttrs[j] = 0; /* this flag is set in flagInhAttrs()*/ tblinfo[i].inhAttrs[j] = 0; /* this flag is set in flagInhAttrs()*/
tblinfo[i].notnull[j] = PQgetvalue(res,j,i_attnotnull)[0]=='t'?true:false;
} }
PQclear(res); PQclear(res);
} }
...@@ -1766,6 +1772,7 @@ void dumpTables(FILE* fout, TableInfo *tblinfo, int numTables, ...@@ -1766,6 +1772,7 @@ void dumpTables(FILE* fout, TableInfo *tblinfo, int numTables,
tblinfo[i].typnames[j]); tblinfo[i].typnames[j]);
actual_atts++; actual_atts++;
} }
sprintf(q, "%s%s NULL", q, tblinfo[i].notnull[j]?" NOT":"");
} }
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_dump.h,v 1.17 1997/07/23 17:15:13 momjian Exp $ * $Id: pg_dump.h,v 1.18 1997/08/19 04:44:40 vadim Exp $
* *
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
* *
...@@ -70,6 +70,7 @@ typedef struct _tableInfo { ...@@ -70,6 +70,7 @@ typedef struct _tableInfo {
an inherited attribute */ an inherited attribute */
char **attnames; /* the attribute names */ char **attnames; /* the attribute names */
char **typnames; /* fill out attributes */ char **typnames; /* fill out attributes */
bool *notnull; /* Not null constraints of an attribute */
int numParents; /* number of (immediate) parent supertables */ int numParents; /* number of (immediate) parent supertables */
char **parentRels; /* names of parent relations, NULL char **parentRels; /* names of parent relations, NULL
if numParents == 0 */ if numParents == 0 */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.82 1997/08/17 00:48:45 scrappy Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.83 1997/08/19 04:45:02 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -422,7 +422,7 @@ tableDesc(PsqlSettings * ps, char *table) ...@@ -422,7 +422,7 @@ tableDesc(PsqlSettings * ps, char *table)
table[i] = tolower(table[i]); table[i] = tolower(table[i]);
descbuf[0] = '\0'; descbuf[0] = '\0';
strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen"); strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull");
strcat(descbuf, " FROM pg_class c, pg_attribute a, pg_type t "); strcat(descbuf, " FROM pg_class c, pg_attribute a, pg_type t ");
strcat(descbuf, " WHERE c.relname = '"); strcat(descbuf, " WHERE c.relname = '");
strcat(descbuf, table); strcat(descbuf, table);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: psqlHelp.h,v 1.20 1997/07/24 19:11:53 momjian Exp $ * $Id: psqlHelp.h,v 1.21 1997/08/19 04:45:04 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -76,7 +76,7 @@ static struct _helpStruct QL_HELP[] = { ...@@ -76,7 +76,7 @@ static struct _helpStruct QL_HELP[] = {
"create sequence <sequence_name>\n\t[increment <NUMBER>]\n\t[start <NUMBER>]\n\t[minvalue <NUMBER>]\n\t[maxvalue <NUMBER>]\n\t[cache <NUMBER>]\n\t[cycle];"}, "create sequence <sequence_name>\n\t[increment <NUMBER>]\n\t[start <NUMBER>]\n\t[minvalue <NUMBER>]\n\t[maxvalue <NUMBER>]\n\t[cache <NUMBER>]\n\t[cycle];"},
{ "create table", { "create table",
"create a new table", "create a new table",
"create table <class_name> ( <attr1> <type1>,... <attrN> <typeN>)\n\t[inherits (<class_name1>,...<class_nameN>\n\tarchive=<archive_mode>\n\tstore=<smgr_name>\n\tarch_store=<smgr_name>];"}, "create table <class_name> ( <attr1> <type1> [[not] null],... <attrN> <typeN>)\n\t[inherits (<class_name1>,...<class_nameN>\n\tarchive=<archive_mode>\n\tstore=<smgr_name>\n\tarch_store=<smgr_name>];"},
{ "create type", { "create type",
"create a new user-defined base data type", "create a new user-defined base data type",
"create type <typename> (\n\tinternallength = (<number> | variable),\n\t[externallength = (<number>|variable),]\n\tinput=<input_function>, output = <output_function>\n\t[,element = <typename>][,delimiter=<character>][,default=\'<string>\']\n\t[,send = <send_function>][,receive = <receive_function>][,passedbyvalue]);"}, "create type <typename> (\n\tinternallength = (<number> | variable),\n\t[externallength = (<number>|variable),]\n\tinput=<input_function>, output = <output_function>\n\t[,element = <typename>][,delimiter=<character>][,default=\'<string>\']\n\t[,send = <send_function>][,receive = <receive_function>][,passedbyvalue]);"},
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: tupdesc.h,v 1.5 1996/11/04 07:45:28 scrappy Exp $ * $Id: tupdesc.h,v 1.6 1997/08/19 04:45:20 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -17,6 +17,13 @@ ...@@ -17,6 +17,13 @@
#include <access/attnum.h> #include <access/attnum.h>
#include <catalog/pg_attribute.h> #include <catalog/pg_attribute.h>
typedef struct attrConstr {
/*------------------------------------------------------------------------
This structure contains flags to the constraints of a tuple
------------------------------------------------------------------------*/
bool has_not_null;
} AttrConstr;
typedef struct tupleDesc { typedef struct tupleDesc {
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
This structure contains all the attribute information (i.e. from Class This structure contains all the attribute information (i.e. from Class
...@@ -26,6 +33,7 @@ typedef struct tupleDesc { ...@@ -26,6 +33,7 @@ typedef struct tupleDesc {
/* Number of attributes in the tuple */ /* Number of attributes in the tuple */
AttributeTupleForm *attrs; AttributeTupleForm *attrs;
/* attrs[N] is a pointer to the description of Attribute Number N+1. */ /* attrs[N] is a pointer to the description of Attribute Number N+1. */
AttrConstr *constr;
} *TupleDesc; } *TupleDesc;
extern TupleDesc CreateTemplateTupleDesc(int natts); extern TupleDesc CreateTemplateTupleDesc(int natts);
......
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: parsenodes.h,v 1.16 1997/05/22 00:16:13 scrappy Exp $ * $Id: parsenodes.h,v 1.17 1997/08/19 04:46:15 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -607,6 +607,7 @@ typedef struct ColumnDef { ...@@ -607,6 +607,7 @@ typedef struct ColumnDef {
NodeTag type; NodeTag type;
char *colname; /* name of column */ char *colname; /* name of column */
TypeName *typename; /* type of column */ TypeName *typename; /* type of column */
bool is_not_null; /* flag to NOT NULL constraint */
} ColumnDef; } ColumnDef;
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment