summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane2002-08-30 19:23:20 +0000
committerTom Lane2002-08-30 19:23:20 +0000
commite2d156fa6e8a72fe36b956ea12f2eb09c9320792 (patch)
tree5ad356c7ce82255f91a5ec6d36d911c2116f9f3e /src/backend
parent96fd7192e7102f9cfc10415c614e3dec19a5227e (diff)
Add attisinherited column to pg_attribute; use it to guard against
column additions, deletions, and renames that would let a child table get out of sync with its parent. Patch by Alvaro Herrera, with some kibitzing by Tom Lane.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/common/tupdesc.c14
-rw-r--r--src/backend/catalog/index.c3
-rw-r--r--src/backend/commands/sequence.c3
-rw-r--r--src/backend/commands/tablecmds.c193
-rw-r--r--src/backend/commands/view.c3
-rw-r--r--src/backend/nodes/copyfuncs.c3
-rw-r--r--src/backend/nodes/equalfuncs.c4
-rw-r--r--src/backend/nodes/outfuncs.c5
-rw-r--r--src/backend/nodes/readfuncs.c6
-rw-r--r--src/backend/tcop/utility.c10
10 files changed, 162 insertions, 82 deletions
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index 8637c72b492..f90717aa12a 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.86 2002/08/29 00:17:02 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.87 2002/08/30 19:23:18 tgl Exp $
*
* NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -231,6 +231,9 @@ FreeTupleDesc(TupleDesc tupdesc)
}
+/*
+ * Compare two TupleDesc structures for logical equality
+ */
bool
equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
{
@@ -264,8 +267,12 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
return false;
if (attr1->attnotnull != attr2->attnotnull)
return false;
+ if (attr1->atthasdef != attr2->atthasdef)
+ return false;
if (attr1->attisdropped != attr2->attisdropped)
return false;
+ if (attr1->attisinherited != attr2->attisinherited)
+ return false;
}
if (tupdesc1->constr != NULL)
{
@@ -389,6 +396,7 @@ TupleDescInitEntry(TupleDesc desc,
att->attnotnull = false;
att->atthasdef = false;
att->attisdropped = false;
+ att->attisinherited = false;
tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(oidtypeid),
@@ -514,7 +522,7 @@ BuildDescForRelation(List *schema)
typenameTypeId(entry->typename),
atttypmod, attdim, attisset);
- /* This is for constraints */
+ /* Fill in additional stuff not handled by TupleDescInitEntry */
if (entry->is_not_null)
constr->has_not_null = true;
desc->attrs[attnum - 1]->attnotnull = entry->is_not_null;
@@ -533,7 +541,9 @@ BuildDescForRelation(List *schema)
desc->attrs[attnum - 1]->atthasdef = true;
}
+ desc->attrs[attnum - 1]->attisinherited = entry->is_inherited;
}
+
if (constr->has_not_null || ndef > 0)
{
desc->constr = constr;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 0aaeaa6d6d4..bf6608eb403 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.191 2002/08/29 15:56:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.192 2002/08/30 19:23:18 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -259,6 +259,7 @@ ConstructTupleDescriptor(Relation heapRelation,
to->attcacheoff = -1;
to->attnotnull = false;
to->atthasdef = false;
+ to->attisinherited = false;
/*
* We do not yet have the correct relation OID for the index, so
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index a33fcd24a40..3d3f4a95581 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.84 2002/08/06 02:36:34 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.85 2002/08/30 19:23:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -127,6 +127,7 @@ DefineSequence(CreateSeqStmt *seq)
coldef = makeNode(ColumnDef);
coldef->typename = typnam;
+ coldef->is_inherited = false;
coldef->is_not_null = true;
coldef->raw_default = NULL;
coldef->cooked_default = NULL;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 04b0266dbc5..8529c15fdb5 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.36 2002/08/29 00:17:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.37 2002/08/30 19:23:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,6 +35,7 @@
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
+#include "optimizer/plancat.h"
#include "optimizer/planmain.h"
#include "optimizer/prep.h"
#include "parser/gramparse.h"
@@ -614,6 +615,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
typename->typeid = attribute->atttypid;
typename->typmod = attribute->atttypmod;
def->typename = typename;
+ def->is_inherited = true;
def->is_not_null = attribute->attnotnull;
def->raw_default = NULL;
def->cooked_default = NULL;
@@ -1049,14 +1051,16 @@ setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
* delete original attribute from attribute catalog
*/
void
-renameatt(Oid relid,
+renameatt(Oid myrelid,
const char *oldattname,
const char *newattname,
- bool recurse)
+ bool recurse,
+ bool recursing)
{
Relation targetrelation;
Relation attrelation;
HeapTuple atttup;
+ Form_pg_attribute attform;
List *indexoidlist;
List *indexoidscan;
@@ -1064,7 +1068,7 @@ renameatt(Oid relid,
* Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction.
*/
- targetrelation = relation_open(relid, AccessExclusiveLock);
+ targetrelation = relation_open(myrelid, AccessExclusiveLock);
/*
* permissions checking. this would normally be done in utility.c,
@@ -1076,7 +1080,7 @@ renameatt(Oid relid,
&& IsSystemRelation(targetrelation))
elog(ERROR, "renameatt: class \"%s\" is a system catalog",
RelationGetRelationName(targetrelation));
- if (!pg_class_ownercheck(relid, GetUserId()))
+ if (!pg_class_ownercheck(myrelid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER,
RelationGetRelationName(targetrelation));
@@ -1095,7 +1099,7 @@ renameatt(Oid relid,
*children;
/* this routine is actually in the planner */
- children = find_all_inheritors(relid);
+ children = find_all_inheritors(myrelid);
/*
* find_all_inheritors does the recursive search of the
@@ -1106,34 +1110,53 @@ renameatt(Oid relid,
{
Oid childrelid = lfirsti(child);
- if (childrelid == relid)
+ if (childrelid == myrelid)
continue;
/* note we need not recurse again! */
- renameatt(childrelid, oldattname, newattname, false);
+ renameatt(childrelid, oldattname, newattname, false, true);
}
}
+ else
+ {
+ /*
+ * If we are told not to recurse, there had better not be any
+ * child tables; else the rename would put them out of step.
+ */
+ if (!recursing &&
+ find_inheritance_children(myrelid) != NIL)
+ elog(ERROR, "Inherited attribute \"%s\" must be renamed in child tables too",
+ oldattname);
+ }
attrelation = heap_openr(AttributeRelationName, RowExclusiveLock);
- atttup = SearchSysCacheCopyAttName(relid, oldattname);
+ atttup = SearchSysCacheCopyAttName(myrelid, oldattname);
if (!HeapTupleIsValid(atttup))
elog(ERROR, "renameatt: attribute \"%s\" does not exist",
oldattname);
+ attform = (Form_pg_attribute) GETSTRUCT(atttup);
- if (((Form_pg_attribute) GETSTRUCT(atttup))->attnum < 0)
+ if (attform->attnum < 0)
elog(ERROR, "renameatt: system attribute \"%s\" may not be renamed",
oldattname);
+ /*
+ * if the attribute is inherited, forbid the renaming, unless we
+ * are already inside a recursive rename.
+ */
+ if (attform->attisinherited && !recursing)
+ elog(ERROR, "renameatt: inherited attribute \"%s\" may not be renamed",
+ oldattname);
+
/* should not already exist */
/* this test is deliberately not attisdropped-aware */
if (SearchSysCacheExists(ATTNAME,
- ObjectIdGetDatum(relid),
+ ObjectIdGetDatum(myrelid),
PointerGetDatum(newattname),
0, 0))
elog(ERROR, "renameatt: attribute \"%s\" exists", newattname);
- namestrcpy(&(((Form_pg_attribute) GETSTRUCT(atttup))->attname),
- newattname);
+ namestrcpy(&(attform->attname), newattname);
simple_heap_update(attrelation, &atttup->t_self, atttup);
@@ -1223,7 +1246,7 @@ renameatt(Oid relid,
* sequence, AFAIK there's no need for it to be there.
*/
void
-renamerel(Oid relid, const char *newrelname)
+renamerel(Oid myrelid, const char *newrelname)
{
Relation targetrelation;
Relation relrelation; /* for RELATION relation */
@@ -1237,7 +1260,7 @@ renamerel(Oid relid, const char *newrelname)
* Grab an exclusive lock on the target table or index, which we will
* NOT release until end of transaction.
*/
- targetrelation = relation_open(relid, AccessExclusiveLock);
+ targetrelation = relation_open(myrelid, AccessExclusiveLock);
oldrelname = pstrdup(RelationGetRelationName(targetrelation));
namespaceId = RelationGetNamespace(targetrelation);
@@ -1258,7 +1281,7 @@ renamerel(Oid relid, const char *newrelname)
relrelation = heap_openr(RelationRelationName, RowExclusiveLock);
reltup = SearchSysCacheCopy(RELOID,
- PointerGetDatum(relid),
+ PointerGetDatum(myrelid),
0, 0, 0);
if (!HeapTupleIsValid(reltup))
elog(ERROR, "renamerel: relation \"%s\" does not exist",
@@ -1293,12 +1316,12 @@ renamerel(Oid relid, const char *newrelname)
if (relhastriggers)
{
/* update tgargs where relname is primary key */
- update_ri_trigger_args(relid,
+ update_ri_trigger_args(myrelid,
oldrelname,
newrelname,
false, true);
/* update tgargs where relname is foreign key */
- update_ri_trigger_args(relid,
+ update_ri_trigger_args(myrelid,
oldrelname,
newrelname,
true, true);
@@ -1532,35 +1555,12 @@ update_ri_trigger_args(Oid relid,
* (formerly known as PerformAddAttribute)
*
* adds an additional attribute to a relation
- *
- * Adds attribute field(s) to a relation. Each new attribute
- * is given attnums in sequential order and is added to the
- * ATTRIBUTE relation. If the AMI fails, defunct tuples will
- * remain in the ATTRIBUTE relation for later vacuuming.
- * Later, there may be some reserved attribute names???
- *
- * (If needed, can instead use elog to handle exceptions.)
- *
- * Note:
- * Initial idea of ordering the tuple attributes so that all
- * the variable length domains occured last was scratched. Doing
- * so would not speed access too much (in general) and would create
- * many complications in formtuple, heap_getattr, and addattribute.
- *
- * scan attribute catalog for name conflict (within rel)
- * scan type catalog for absence of data type (if not arg)
- * create attnum magically???
- * create attribute tuple
- * insert attribute in attribute catalog
- * modify reldesc
- * create new relation tuple
- * insert new relation in relation catalog
- * delete original relation from relation catalog
* ----------------
*/
void
AlterTableAddColumn(Oid myrelid,
- bool inherits,
+ bool recurse,
+ bool recursing,
ColumnDef *colDef)
{
Relation rel,
@@ -1610,10 +1610,13 @@ AlterTableAddColumn(Oid myrelid,
* whole transaction to abort, which is what we want -- all or
* nothing.
*/
- if (inherits)
+ if (recurse)
{
List *child,
*children;
+ ColumnDef *colDefChild = copyObject(colDef);
+
+ colDefChild->is_inherited = true;
/* this routine is actually in the planner */
children = find_all_inheritors(myrelid);
@@ -1630,9 +1633,19 @@ AlterTableAddColumn(Oid myrelid,
if (childrelid == myrelid)
continue;
- AlterTableAddColumn(childrelid, false, colDef);
+ AlterTableAddColumn(childrelid, false, true, colDefChild);
}
}
+ else
+ {
+ /*
+ * If we are told not to recurse, there had better not be any
+ * child tables; else the addition would put them out of step.
+ */
+ if (!recursing &&
+ find_inheritance_children(myrelid) != NIL)
+ elog(ERROR, "Attribute must be added to child tables too");
+ }
/*
* OK, get on with it...
@@ -1716,6 +1729,7 @@ AlterTableAddColumn(Oid myrelid,
attribute->atthasdef = (colDef->raw_default != NULL ||
colDef->cooked_default != NULL);
attribute->attisdropped = false;
+ attribute->attisinherited = colDef->is_inherited;
ReleaseSysCache(typeTuple);
@@ -1786,8 +1800,8 @@ AlterTableAddColumn(Oid myrelid,
* ALTER TABLE ALTER COLUMN DROP NOT NULL
*/
void
-AlterTableAlterColumnDropNotNull(Oid myrelid,
- bool inh, const char *colName)
+AlterTableAlterColumnDropNotNull(Oid myrelid, bool recurse,
+ const char *colName)
{
Relation rel;
HeapTuple tuple;
@@ -1813,7 +1827,7 @@ AlterTableAlterColumnDropNotNull(Oid myrelid,
/*
* Propagate to children if desired
*/
- if (inh)
+ if (recurse)
{
List *child,
*children;
@@ -1920,8 +1934,8 @@ AlterTableAlterColumnDropNotNull(Oid myrelid,
* ALTER TABLE ALTER COLUMN SET NOT NULL
*/
void
-AlterTableAlterColumnSetNotNull(Oid myrelid,
- bool inh, const char *colName)
+AlterTableAlterColumnSetNotNull(Oid myrelid, bool recurse,
+ const char *colName)
{
Relation rel;
HeapTuple tuple;
@@ -1947,7 +1961,7 @@ AlterTableAlterColumnSetNotNull(Oid myrelid,
/*
* Propagate to children if desired
*/
- if (inh)
+ if (recurse)
{
List *child,
*children;
@@ -2035,8 +2049,8 @@ AlterTableAlterColumnSetNotNull(Oid myrelid,
* ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
*/
void
-AlterTableAlterColumnDefault(Oid myrelid,
- bool inh, const char *colName,
+AlterTableAlterColumnDefault(Oid myrelid, bool recurse,
+ const char *colName,
Node *newDefault)
{
Relation rel;
@@ -2065,7 +2079,7 @@ AlterTableAlterColumnDefault(Oid myrelid,
/*
* Propagate to children if desired
*/
- if (inh)
+ if (recurse)
{
List *child,
*children;
@@ -2134,8 +2148,8 @@ AlterTableAlterColumnDefault(Oid myrelid,
* ALTER TABLE ALTER COLUMN SET STATISTICS / STORAGE
*/
void
-AlterTableAlterColumnFlags(Oid myrelid,
- bool inh, const char *colName,
+AlterTableAlterColumnFlags(Oid myrelid, bool recurse,
+ const char *colName,
Node *flagValue, const char *flagType)
{
Relation rel;
@@ -2213,7 +2227,7 @@ AlterTableAlterColumnFlags(Oid myrelid,
/*
* Propagate to children if desired
*/
- if (inh)
+ if (recurse)
{
List *child,
*children;
@@ -2284,8 +2298,8 @@ AlterTableAlterColumnFlags(Oid myrelid,
* ALTER TABLE DROP COLUMN
*/
void
-AlterTableDropColumn(Oid myrelid,
- bool inh, const char *colName,
+AlterTableDropColumn(Oid myrelid, bool recurse, bool recursing,
+ const char *colName,
DropBehavior behavior)
{
Relation rel;
@@ -2344,10 +2358,54 @@ AlterTableDropColumn(Oid myrelid,
elog(ERROR, "ALTER TABLE: Cannot drop last column from table \"%s\"",
RelationGetRelationName(rel));
+ /* Don't drop inherited columns */
+ if (tupleDesc->attrs[attnum - 1]->attisinherited && !recursing)
+ elog(ERROR, "ALTER TABLE: Cannot drop inherited column \"%s\"",
+ colName);
+
+ /*
+ * If we are asked to drop ONLY in this table (no recursion),
+ * we need to mark the inheritors' attribute as non-inherited.
+ */
+ if (!recurse && !recursing)
+ {
+ Relation attr_rel;
+ List *child,
+ *children;
+
+ /* We only want direct inheritors in this case */
+ children = find_inheritance_children(myrelid);
+
+ attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock);
+ foreach(child, children)
+ {
+ Oid childrelid = lfirsti(child);
+ Relation childrel;
+ HeapTuple tuple;
+
+ childrel = heap_open(childrelid, AccessExclusiveLock);
+
+ tuple = SearchSysCacheCopyAttName(childrelid, colName);
+ if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
+ elog(ERROR, "ALTER TABLE: relation %u has no column \"%s\"",
+ childrelid, colName);
+
+ ((Form_pg_attribute) GETSTRUCT(tuple))->attisinherited = false;
+
+ simple_heap_update(attr_rel, &tuple->t_self, tuple);
+
+ /* keep the system catalog indexes current */
+ CatalogUpdateIndexes(attr_rel, tuple);
+
+ heap_close(childrel, NoLock);
+ }
+ heap_close(attr_rel, RowExclusiveLock);
+ }
+
/*
* Propagate to children if desired
*/
- if (inh)
+ if (recurse)
{
List *child,
*children;
@@ -2366,8 +2424,7 @@ AlterTableDropColumn(Oid myrelid,
if (childrelid == myrelid)
continue;
- AlterTableDropColumn(childrelid,
- false, colName, behavior);
+ AlterTableDropColumn(childrelid, false, true, colName, behavior);
}
}
@@ -2388,8 +2445,8 @@ AlterTableDropColumn(Oid myrelid,
* ALTER TABLE ADD CONSTRAINT
*/
void
-AlterTableAddConstraint(Oid myrelid,
- bool inh, List *newConstraints)
+AlterTableAddConstraint(Oid myrelid, bool recurse,
+ List *newConstraints)
{
Relation rel;
List *listptr;
@@ -2413,7 +2470,7 @@ AlterTableAddConstraint(Oid myrelid,
if (!pg_class_ownercheck(myrelid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
- if (inh)
+ if (recurse)
{
List *child,
*children;
@@ -3092,8 +3149,8 @@ fkMatchTypeToString(char match_type)
* ALTER TABLE DROP CONSTRAINT
*/
void
-AlterTableDropConstraint(Oid myrelid,
- bool inh, const char *constrName,
+AlterTableDropConstraint(Oid myrelid, bool recurse,
+ const char *constrName,
DropBehavior behavior)
{
Relation rel;
@@ -3121,7 +3178,7 @@ AlterTableDropConstraint(Oid myrelid,
/*
* Process child tables if requested.
*/
- if (inh)
+ if (recurse)
{
List *child,
*children;
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index faaff48fa05..c635a28571d 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: view.c,v 1.67 2002/07/16 22:12:19 tgl Exp $
+ * $Id: view.c,v 1.68 2002/08/30 19:23:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -68,6 +68,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist)
typename->typmod = res->restypmod;
def->typename = typename;
+ def->is_inherited = false;
def->is_not_null = false;
def->raw_default = NULL;
def->cooked_default = NULL;
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index b3920e38b2d..5b35eea170a 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.207 2002/08/27 04:55:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.208 2002/08/30 19:23:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1729,6 +1729,7 @@ _copyColumnDef(ColumnDef *from)
if (from->colname)
newnode->colname = pstrdup(from->colname);
Node_Copy(from, newnode, typename);
+ newnode->is_inherited = from->is_inherited;
newnode->is_not_null = from->is_not_null;
Node_Copy(from, newnode, raw_default);
if (from->cooked_default)
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 408a94ff1b3..7c9127dbf4f 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.155 2002/08/27 04:55:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.156 2002/08/30 19:23:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1748,6 +1748,8 @@ _equalColumnDef(ColumnDef *a, ColumnDef *b)
return false;
if (!equal(a->typename, b->typename))
return false;
+ if (a->is_inherited != b->is_inherited)
+ return false;
if (a->is_not_null != b->is_not_null)
return false;
if (!equal(a->raw_default, b->raw_default))
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index ca88b520f96..a92750caef1 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.170 2002/08/29 00:17:04 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.171 2002/08/30 19:23:19 tgl Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -176,7 +176,8 @@ _outColumnDef(StringInfo str, ColumnDef *node)
_outToken(str, node->colname);
appendStringInfo(str, " :typename ");
_outNode(str, node->typename);
- appendStringInfo(str, " :is_not_null %s :raw_default ",
+ appendStringInfo(str, " :is_inherited %s :is_not_null %s :raw_default ",
+ booltostr(node->is_inherited),
booltostr(node->is_not_null));
_outNode(str, node->raw_default);
appendStringInfo(str, " :cooked_default ");
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index b54a70159c8..2799bb74604 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.129 2002/08/26 17:53:58 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.130 2002/08/30 19:23:19 tgl Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -1485,6 +1485,10 @@ _readColumnDef(void)
token = pg_strtok(&length); /* eat :typename */
local_node->typename = nodeRead(true); /* now read it */
+ token = pg_strtok(&length); /* eat :is_inherited */
+ token = pg_strtok(&length); /* get :is_inherited */
+ local_node->is_inherited = strtobool(token);
+
token = pg_strtok(&length); /* eat :is_not_null */
token = pg_strtok(&length); /* get :is_not_null */
local_node->is_not_null = strtobool(token);
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 65745be3c00..17a2533b775 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.174 2002/08/29 00:17:04 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.175 2002/08/30 19:23:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -430,7 +430,8 @@ ProcessUtility(Node *parsetree,
renameatt(relid,
stmt->oldname, /* old att name */
stmt->newname, /* new att name */
- interpretInhOption(stmt->relation->inhOpt)); /* recursive? */
+ interpretInhOption(stmt->relation->inhOpt), /* recursive? */
+ false); /* recursing already? */
break;
case RENAME_TRIGGER:
renametrig(relid,
@@ -470,6 +471,7 @@ ProcessUtility(Node *parsetree,
*/
AlterTableAddColumn(relid,
interpretInhOption(stmt->relation->inhOpt),
+ false,
(ColumnDef *) stmt->def);
break;
case 'T': /* ALTER COLUMN DEFAULT */
@@ -505,13 +507,13 @@ ProcessUtility(Node *parsetree,
&(stmt->subtype));
break;
case 'D': /* DROP COLUMN */
- /*
- * XXX We don't actually recurse yet, but what we should do would be:
+ /*
* Recursively drop column from table and,
* if requested, from descendants
*/
AlterTableDropColumn(relid,
interpretInhOption(stmt->relation->inhOpt),
+ false,
stmt->name,
stmt->behavior);
break;