aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/common/tupdesc.c12
-rw-r--r--src/backend/bootstrap/bootstrap.c5
-rw-r--r--src/backend/catalog/heap.c16
-rw-r--r--src/backend/catalog/index.c10
-rw-r--r--src/backend/commands/sequence.c5
-rw-r--r--src/backend/commands/tablecmds.c83
-rw-r--r--src/backend/commands/view.c5
-rw-r--r--src/backend/nodes/copyfuncs.c5
-rw-r--r--src/backend/nodes/equalfuncs.c6
-rw-r--r--src/backend/nodes/outfuncs.c7
-rw-r--r--src/backend/nodes/readfuncs.c12
-rw-r--r--src/backend/parser/gram.y6
12 files changed, 121 insertions, 51 deletions
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index ce4452eec51..5a1b912b379 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.89 2002/09/04 20:31:09 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.90 2002/09/22 19:42:50 tgl Exp $
*
* NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -271,7 +271,9 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
return false;
if (attr1->attisdropped != attr2->attisdropped)
return false;
- if (attr1->attisinherited != attr2->attisinherited)
+ if (attr1->attislocal != attr2->attislocal)
+ return false;
+ if (attr1->attinhcount != attr2->attinhcount)
return false;
}
if (tupdesc1->constr != NULL)
@@ -396,7 +398,8 @@ TupleDescInitEntry(TupleDesc desc,
att->attnotnull = false;
att->atthasdef = false;
att->attisdropped = false;
- att->attisinherited = false;
+ att->attislocal = true;
+ att->attinhcount = 0;
tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(oidtypeid),
@@ -543,7 +546,8 @@ BuildDescForRelation(List *schema)
desc->attrs[attnum - 1]->atthasdef = true;
}
- desc->attrs[attnum - 1]->attisinherited = entry->is_inherited;
+ desc->attrs[attnum - 1]->attislocal = entry->is_local;
+ desc->attrs[attnum - 1]->attinhcount = entry->inhcount;
}
if (constr->has_not_null || ndef > 0)
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 26e522f6cfa..b22631700b4 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.141 2002/09/04 20:31:13 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.142 2002/09/22 19:42:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -587,7 +587,7 @@ DefineAttr(char *name, char *type, int attnum)
namestrcpy(&attrtypes[attnum]->attname, name);
elog(DEBUG3, "column %s %s", NameStr(attrtypes[attnum]->attname), type);
- attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
+ attrtypes[attnum]->attnum = attnum + 1; /* fillatt */
typeoid = gettype(type);
@@ -640,6 +640,7 @@ DefineAttr(char *name, char *type, int attnum)
}
attrtypes[attnum]->attcacheoff = -1;
attrtypes[attnum]->atttypmod = -1;
+ attrtypes[attnum]->attislocal = true;
/*
* Mark as "not null" if type is fixed-width and prior columns are
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index fa5aec0203b..dea79dc4d6e 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.230 2002/09/22 00:37:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.231 2002/09/22 19:42:50 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -97,37 +97,37 @@ static void RemoveStatistics(Relation rel);
static FormData_pg_attribute a1 = {
0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
SelfItemPointerAttributeNumber, 0, -1, -1,
- false, 'p', false, 'i', true, false, false
+ false, 'p', false, 'i', true, false, false, true, 0
};
static FormData_pg_attribute a2 = {
0, {"oid"}, OIDOID, 0, sizeof(Oid),
ObjectIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false, false
+ true, 'p', false, 'i', true, false, false, true, 0
};
static FormData_pg_attribute a3 = {
0, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
MinTransactionIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false, false
+ true, 'p', false, 'i', true, false, false, true, 0
};
static FormData_pg_attribute a4 = {
0, {"cmin"}, CIDOID, 0, sizeof(CommandId),
MinCommandIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false, false
+ true, 'p', false, 'i', true, false, false, true, 0
};
static FormData_pg_attribute a5 = {
0, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
MaxTransactionIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false, false
+ true, 'p', false, 'i', true, false, false, true, 0
};
static FormData_pg_attribute a6 = {
0, {"cmax"}, CIDOID, 0, sizeof(CommandId),
MaxCommandIdAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false, false
+ true, 'p', false, 'i', true, false, false, true, 0
};
/*
@@ -139,7 +139,7 @@ static FormData_pg_attribute a6 = {
static FormData_pg_attribute a7 = {
0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
TableOidAttributeNumber, 0, -1, -1,
- true, 'p', false, 'i', true, false, false
+ true, 'p', false, 'i', true, false, false, true, 0
};
static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 23fd0f6a171..e917b684c3b 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.197 2002/09/22 00:37:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.198 2002/09/22 19:42:50 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -165,10 +165,11 @@ BuildFuncTupleDesc(Oid funcOid,
funcTupDesc->attrs[0]->atttypid = keyType;
funcTupDesc->attrs[0]->attlen = typeTup->typlen;
funcTupDesc->attrs[0]->attbyval = typeTup->typbyval;
- funcTupDesc->attrs[0]->attcacheoff = -1;
- funcTupDesc->attrs[0]->atttypmod = -1;
funcTupDesc->attrs[0]->attstorage = typeTup->typstorage;
funcTupDesc->attrs[0]->attalign = typeTup->typalign;
+ funcTupDesc->attrs[0]->attcacheoff = -1;
+ funcTupDesc->attrs[0]->atttypmod = -1;
+ funcTupDesc->attrs[0]->attislocal = true;
ReleaseSysCache(tuple);
@@ -259,7 +260,8 @@ ConstructTupleDescriptor(Relation heapRelation,
to->attcacheoff = -1;
to->attnotnull = false;
to->atthasdef = false;
- to->attisinherited = false;
+ to->attislocal = true;
+ to->attinhcount = 0;
/*
* 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 5906788247c..f6ace0d2d93 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.87 2002/09/04 20:31:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.88 2002/09/22 19:42:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -127,7 +127,8 @@ DefineSequence(CreateSeqStmt *seq)
coldef = makeNode(ColumnDef);
coldef->typename = typnam;
- coldef->is_inherited = false;
+ coldef->inhcount = 0;
+ coldef->is_local = true;
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 c79cd1f9edd..7b2bab71c34 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.42 2002/09/22 00:37:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.43 2002/09/22 19:42:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -609,6 +609,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
attributeName,
TypeNameToString(def->typename),
format_type_be(attribute->atttypid));
+ def->inhcount++;
/* Merge of NOT NULL constraints = OR 'em together */
def->is_not_null |= attribute->attnotnull;
/* Default and other constraints are handled below */
@@ -625,7 +626,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
typename->typeid = attribute->atttypid;
typename->typmod = attribute->atttypmod;
def->typename = typename;
- def->is_inherited = true;
+ def->inhcount = 1;
+ def->is_local = false;
def->is_not_null = attribute->attnotnull;
def->raw_default = NULL;
def->cooked_default = NULL;
@@ -758,6 +760,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
attributeName,
TypeNameToString(def->typename),
TypeNameToString(newdef->typename));
+ /* Mark the column as locally defined */
+ def->is_local = true;
/* Merge of NOT NULL constraints = OR 'em together */
def->is_not_null |= newdef->is_not_null;
/* If new def has a default, override previous default */
@@ -1155,7 +1159,7 @@ renameatt(Oid myrelid,
* if the attribute is inherited, forbid the renaming, unless we are
* already inside a recursive rename.
*/
- if (attform->attisinherited && !recursing)
+ if (attform->attinhcount > 0 && !recursing)
elog(ERROR, "renameatt: inherited attribute \"%s\" may not be renamed",
oldattname);
@@ -1628,7 +1632,8 @@ AlterTableAddColumn(Oid myrelid,
*children;
ColumnDef *colDefChild = copyObject(colDef);
- colDefChild->is_inherited = true;
+ colDefChild->inhcount = 1;
+ colDefChild->is_local = false;
/* this routine is actually in the planner */
children = find_all_inheritors(myrelid);
@@ -1742,7 +1747,8 @@ AlterTableAddColumn(Oid myrelid,
attribute->atthasdef = (colDef->raw_default != NULL ||
colDef->cooked_default != NULL);
attribute->attisdropped = false;
- attribute->attisinherited = colDef->is_inherited;
+ attribute->attislocal = colDef->is_local;
+ attribute->attinhcount = colDef->inhcount;
ReleaseSysCache(typeTuple);
@@ -2373,13 +2379,14 @@ AlterTableDropColumn(Oid myrelid, bool recurse, bool recursing,
RelationGetRelationName(rel));
/* Don't drop inherited columns */
- if (tupleDesc->attrs[attnum - 1]->attisinherited && !recursing)
+ if (tupleDesc->attrs[attnum - 1]->attinhcount > 0 && !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.
+ * to mark the inheritors' attribute as locally defined rather than
+ * inherited.
*/
if (!recurse && !recursing)
{
@@ -2396,6 +2403,7 @@ AlterTableDropColumn(Oid myrelid, bool recurse, bool recursing,
Oid childrelid = lfirsti(child);
Relation childrel;
HeapTuple tuple;
+ Form_pg_attribute childatt;
childrel = heap_open(childrelid, AccessExclusiveLock);
@@ -2403,43 +2411,84 @@ AlterTableDropColumn(Oid myrelid, bool recurse, bool recursing,
if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
elog(ERROR, "ALTER TABLE: relation %u has no column \"%s\"",
childrelid, colName);
+ childatt = (Form_pg_attribute) GETSTRUCT(tuple);
- ((Form_pg_attribute) GETSTRUCT(tuple))->attisinherited = false;
+ if (childatt->attinhcount <= 0)
+ elog(ERROR, "ALTER TABLE: relation %u has non-inherited column \"%s\"",
+ childrelid, colName);
+ childatt->attinhcount--;
+ childatt->attislocal = true;
simple_heap_update(attr_rel, &tuple->t_self, tuple);
/* keep the system catalog indexes current */
CatalogUpdateIndexes(attr_rel, tuple);
+ heap_freetuple(tuple);
+
heap_close(childrel, NoLock);
}
heap_close(attr_rel, RowExclusiveLock);
}
/*
- * Propagate to children if desired
+ * Propagate to children if desired. Unlike most other ALTER routines,
+ * we have to do this one level of recursion at a time; we can't use
+ * find_all_inheritors to do it in one pass.
*/
if (recurse)
{
+ Relation attr_rel;
List *child,
*children;
- /* this routine is actually in the planner */
- children = find_all_inheritors(myrelid);
+ /* We only want direct inheritors in this case */
+ children = find_inheritance_children(myrelid);
- /*
- * find_all_inheritors does the recursive search of the
- * inheritance hierarchy, so all we have to do is process all of
- * the relids in the list that it returns.
- */
+ attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock);
foreach(child, children)
{
Oid childrelid = lfirsti(child);
+ Relation childrel;
+ HeapTuple tuple;
+ Form_pg_attribute childatt;
if (childrelid == myrelid)
continue;
- AlterTableDropColumn(childrelid, false, true, colName, behavior);
+
+ 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);
+ childatt = (Form_pg_attribute) GETSTRUCT(tuple);
+
+ if (childatt->attinhcount <= 0)
+ elog(ERROR, "ALTER TABLE: relation %u has non-inherited column \"%s\"",
+ childrelid, colName);
+
+ if (childatt->attinhcount == 1 && !childatt->attislocal)
+ {
+ /* Time to delete this child column, too */
+ AlterTableDropColumn(childrelid, true, true, colName, behavior);
+ }
+ else
+ {
+ /* Child column must survive my deletion */
+ childatt->attinhcount--;
+
+ simple_heap_update(attr_rel, &tuple->t_self, tuple);
+
+ /* keep the system catalog indexes current */
+ CatalogUpdateIndexes(attr_rel, tuple);
+ }
+
+ heap_freetuple(tuple);
+
+ heap_close(childrel, NoLock);
}
+ heap_close(attr_rel, RowExclusiveLock);
}
/*
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index 0ce309750c9..17a5cdaa0d4 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.71 2002/09/04 20:31:17 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.72 2002/09/22 19:42:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -71,7 +71,8 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
typename->typmod = res->restypmod;
def->typename = typename;
- def->is_inherited = false;
+ def->inhcount = 0;
+ def->is_local = true;
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 73e240aca7c..bce849e4ec5 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.212 2002/09/18 21:35:20 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.213 2002/09/22 19:42:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1732,7 +1732,8 @@ _copyColumnDef(ColumnDef *from)
if (from->colname)
newnode->colname = pstrdup(from->colname);
Node_Copy(from, newnode, typename);
- newnode->is_inherited = from->is_inherited;
+ newnode->inhcount = from->inhcount;
+ newnode->is_local = from->is_local;
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 8c5d6a0337a..82d4fc6ab63 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.159 2002/09/18 21:35:20 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.160 2002/09/22 19:42:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1769,7 +1769,9 @@ _equalColumnDef(ColumnDef *a, ColumnDef *b)
return false;
if (!equal(a->typename, b->typename))
return false;
- if (a->is_inherited != b->is_inherited)
+ if (a->inhcount != b->inhcount)
+ return false;
+ if (a->is_local != b->is_local)
return false;
if (a->is_not_null != b->is_not_null)
return false;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index fde42291691..364aa774ada 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.174 2002/09/18 21:35:21 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.175 2002/09/22 19:42:51 tgl Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -176,8 +176,9 @@ _outColumnDef(StringInfo str, ColumnDef *node)
_outToken(str, node->colname);
appendStringInfo(str, " :typename ");
_outNode(str, node->typename);
- appendStringInfo(str, " :is_inherited %s :is_not_null %s :raw_default ",
- booltostr(node->is_inherited),
+ appendStringInfo(str, " :inhcount %d :is_local %s :is_not_null %s :raw_default ",
+ node->inhcount,
+ booltostr(node->is_local),
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 a4f0c81fa1e..fc4bb97e4a7 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.133 2002/09/18 21:35:21 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.134 2002/09/22 19:42:51 tgl Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -1526,9 +1526,13 @@ _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 :inhcount */
+ token = pg_strtok(&length); /* get :inhcount */
+ local_node->inhcount = atoi(token);
+
+ token = pg_strtok(&length); /* eat :is_local */
+ token = pg_strtok(&length); /* get :is_local */
+ local_node->is_local = strtobool(token);
token = pg_strtok(&length); /* eat :is_not_null */
token = pg_strtok(&length); /* get :is_not_null */
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index be45d7bde16..bbee0097243 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.368 2002/09/22 17:27:23 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.369 2002/09/22 19:42:51 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -1453,6 +1453,7 @@ columnDef: ColId Typename ColQualList opt_collate
n->colname = $1;
n->typename = $2;
n->constraints = $3;
+ n->is_local = true;
if ($4 != NULL)
elog(NOTICE,
@@ -1842,6 +1843,8 @@ CreateAsElement:
ColumnDef *n = makeNode(ColumnDef);
n->colname = $1;
n->typename = NULL;
+ n->inhcount = 0;
+ n->is_local = true;
n->is_not_null = false;
n->raw_default = NULL;
n->cooked_default = NULL;
@@ -4844,6 +4847,7 @@ TableFuncElement: ColId Typename
n->colname = $1;
n->typename = $2;
n->constraints = NIL;
+ n->is_local = true;
$$ = (Node *)n;
}
;