mirror of
https://github.com/postgres/postgres.git
synced 2025-11-03 09:13:20 +03:00
NOT NULL implementation (submitted by Robson Paniago de Miranda).
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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' },
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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.
|
||||
* ----------------
|
||||
*/
|
||||
@@ -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
|
||||
* ----------------
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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; }
|
||||
;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
||||
25
src/backend/utils/cache/relcache.c
vendored
25
src/backend/utils/cache/relcache.c
vendored
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user