Commit 5af19e42 authored by Tom Lane's avatar Tom Lane

Add more dependency insertions --- this completes the basic pg_depend

functionality.  Of note: dropping a table that has a SERIAL column
defined now drops the associated sequence automatically.
parent cdebcad6
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.140 2002/07/12 18:43:12 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.141 2002/07/16 22:12:18 tgl Exp $
--> -->
<appendix id="release"> <appendix id="release">
...@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without ...@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters. worries about funny characters.
--> -->
<literallayout><![CDATA[ <literallayout><![CDATA[
Sequences created by SERIAL column definitions now auto-drop with the column
Most forms of DROP now support RESTRICT and CASCADE options Most forms of DROP now support RESTRICT and CASCADE options
Recursive SQL functions can be defined Recursive SQL functions can be defined
User-defined procedural languages can register a validator function to check new functions as they are created User-defined procedural languages can register a validator function to check new functions as they are created
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.208 2002/07/16 05:53:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.209 2002/07/16 22:12:18 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -97,37 +97,37 @@ static void RemoveStatistics(Relation rel); ...@@ -97,37 +97,37 @@ static void RemoveStatistics(Relation rel);
static FormData_pg_attribute a1 = { static FormData_pg_attribute a1 = {
0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData), 0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
SelfItemPointerAttributeNumber, 0, -1, -1, SelfItemPointerAttributeNumber, 0, -1, -1,
false, 'p', false, 'i', false, false false, 'p', false, 'i', true, false
}; };
static FormData_pg_attribute a2 = { static FormData_pg_attribute a2 = {
0, {"oid"}, OIDOID, 0, sizeof(Oid), 0, {"oid"}, OIDOID, 0, sizeof(Oid),
ObjectIdAttributeNumber, 0, -1, -1, ObjectIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', false, false true, 'p', false, 'i', true, false
}; };
static FormData_pg_attribute a3 = { static FormData_pg_attribute a3 = {
0, {"xmin"}, XIDOID, 0, sizeof(TransactionId), 0, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
MinTransactionIdAttributeNumber, 0, -1, -1, MinTransactionIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', false, false true, 'p', false, 'i', true, false
}; };
static FormData_pg_attribute a4 = { static FormData_pg_attribute a4 = {
0, {"cmin"}, CIDOID, 0, sizeof(CommandId), 0, {"cmin"}, CIDOID, 0, sizeof(CommandId),
MinCommandIdAttributeNumber, 0, -1, -1, MinCommandIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', false, false true, 'p', false, 'i', true, false
}; };
static FormData_pg_attribute a5 = { static FormData_pg_attribute a5 = {
0, {"xmax"}, XIDOID, 0, sizeof(TransactionId), 0, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
MaxTransactionIdAttributeNumber, 0, -1, -1, MaxTransactionIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', false, false true, 'p', false, 'i', true, false
}; };
static FormData_pg_attribute a6 = { static FormData_pg_attribute a6 = {
0, {"cmax"}, CIDOID, 0, sizeof(CommandId), 0, {"cmax"}, CIDOID, 0, sizeof(CommandId),
MaxCommandIdAttributeNumber, 0, -1, -1, MaxCommandIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', false, false true, 'p', false, 'i', true, false
}; };
/* /*
...@@ -139,7 +139,7 @@ static FormData_pg_attribute a6 = { ...@@ -139,7 +139,7 @@ static FormData_pg_attribute a6 = {
static FormData_pg_attribute a7 = { static FormData_pg_attribute a7 = {
0, {"tableoid"}, OIDOID, 0, sizeof(Oid), 0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
TableOidAttributeNumber, 0, -1, -1, TableOidAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', false, false true, 'p', false, 'i', true, false
}; };
static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7}; static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
...@@ -416,6 +416,8 @@ AddNewAttributeTuples(Oid new_rel_oid, ...@@ -416,6 +416,8 @@ AddNewAttributeTuples(Oid new_rel_oid,
bool hasindex; bool hasindex;
Relation idescs[Num_pg_attr_indices]; Relation idescs[Num_pg_attr_indices];
int natts = tupdesc->natts; int natts = tupdesc->natts;
ObjectAddress myself,
referenced;
/* /*
* open pg_attribute * open pg_attribute
...@@ -430,7 +432,8 @@ AddNewAttributeTuples(Oid new_rel_oid, ...@@ -430,7 +432,8 @@ AddNewAttributeTuples(Oid new_rel_oid,
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs); CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
/* /*
* first we add the user attributes.. * First we add the user attributes. This is also a convenient place
* to add dependencies on their datatypes.
*/ */
dpp = tupdesc->attrs; dpp = tupdesc->attrs;
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
...@@ -451,11 +454,22 @@ AddNewAttributeTuples(Oid new_rel_oid, ...@@ -451,11 +454,22 @@ AddNewAttributeTuples(Oid new_rel_oid,
CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup); CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);
heap_freetuple(tup); heap_freetuple(tup);
myself.classId = RelOid_pg_class;
myself.objectId = new_rel_oid;
myself.objectSubId = i+1;
referenced.classId = RelOid_pg_type;
referenced.objectId = (*dpp)->atttypid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
dpp++; dpp++;
} }
/* /*
* next we add the system attributes. Skip OID if rel has no OIDs. * Next we add the system attributes. Skip OID if rel has no OIDs.
* Skip all for a view. We don't bother with making datatype
* dependencies here, since presumably all these types are pinned.
*/ */
if (relkind != RELKIND_VIEW) if (relkind != RELKIND_VIEW)
{ {
...@@ -493,7 +507,7 @@ AddNewAttributeTuples(Oid new_rel_oid, ...@@ -493,7 +507,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
} }
/* /*
* close pg_attribute indices * clean up
*/ */
if (hasindex) if (hasindex)
CatalogCloseIndices(Num_pg_attr_indices, idescs); CatalogCloseIndices(Num_pg_attr_indices, idescs);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.49 2002/06/20 20:29:26 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.50 2002/07/16 22:12:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_aggregate.h" #include "catalog/pg_aggregate.h"
...@@ -53,6 +54,8 @@ AggregateCreate(const char *aggName, ...@@ -53,6 +54,8 @@ AggregateCreate(const char *aggName,
Oid procOid; Oid procOid;
TupleDesc tupDesc; TupleDesc tupDesc;
int i; int i;
ObjectAddress myself,
referenced;
/* sanity checks */ /* sanity checks */
if (!aggName) if (!aggName)
...@@ -187,4 +190,29 @@ AggregateCreate(const char *aggName, ...@@ -187,4 +190,29 @@ AggregateCreate(const char *aggName,
} }
heap_close(aggdesc, RowExclusiveLock); heap_close(aggdesc, RowExclusiveLock);
/*
* Create dependencies for the aggregate (above and beyond those
* already made by ProcedureCreate). Note: we don't need an explicit
* dependency on aggTransType since we depend on it indirectly through
* transfn.
*/
myself.classId = RelOid_pg_proc;
myself.objectId = procOid;
myself.objectSubId = 0;
/* Depends on transition function */
referenced.classId = RelOid_pg_proc;
referenced.objectId = transfn;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* Depends on final function, if any */
if (OidIsValid(finalfn))
{
referenced.classId = RelOid_pg_proc;
referenced.objectId = finalfn;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.2 2002/07/16 05:53:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.3 2002/07/16 22:12:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -198,17 +198,11 @@ CreateConstraintEntry(const char *constraintName, ...@@ -198,17 +198,11 @@ CreateConstraintEntry(const char *constraintName,
if (OidIsValid(foreignRelId)) if (OidIsValid(foreignRelId))
{ {
/* /*
* Register dependency from constraint to foreign relation, * Register normal dependency from constraint to foreign relation,
* or to specific column(s) if any are mentioned. * or to specific column(s) if any are mentioned.
*
* In normal case of two separate relations, make this a NORMAL
* dependency (so dropping the FK table would require CASCADE).
* However, for a self-reference just make it AUTO.
*/ */
DependencyType deptype;
ObjectAddress relobject; ObjectAddress relobject;
deptype = (foreignRelId == relId) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL;
relobject.classId = RelOid_pg_class; relobject.classId = RelOid_pg_class;
relobject.objectId = foreignRelId; relobject.objectId = foreignRelId;
if (foreignNKeys > 0) if (foreignNKeys > 0)
...@@ -217,14 +211,14 @@ CreateConstraintEntry(const char *constraintName, ...@@ -217,14 +211,14 @@ CreateConstraintEntry(const char *constraintName,
{ {
relobject.objectSubId = foreignKey[i]; relobject.objectSubId = foreignKey[i];
recordDependencyOn(&conobject, &relobject, deptype); recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);
} }
} }
else else
{ {
relobject.objectSubId = 0; relobject.objectSubId = 0;
recordDependencyOn(&conobject, &relobject, deptype); recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);
} }
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.2 2002/07/16 05:53:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.3 2002/07/16 22:12:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -121,6 +121,43 @@ recordMultipleDependencies(const ObjectAddress *depender, ...@@ -121,6 +121,43 @@ recordMultipleDependencies(const ObjectAddress *depender,
heap_close(dependDesc, RowExclusiveLock); heap_close(dependDesc, RowExclusiveLock);
} }
/*
* deleteDependencyRecordsFor -- delete all records with given depender
* classId/objectId.
*
* This is used when redefining an existing object. Links leading to the
* object do not change, and links leading from it will be recreated
* (possibly with some differences from before).
*/
void
deleteDependencyRecordsFor(Oid classId, Oid objectId)
{
Relation depRel;
ScanKeyData key[2];
SysScanDesc scan;
HeapTuple tup;
depRel = heap_openr(DependRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&key[0], 0x0,
Anum_pg_depend_classid, F_OIDEQ,
ObjectIdGetDatum(classId));
ScanKeyEntryInitialize(&key[1], 0x0,
Anum_pg_depend_objid, F_OIDEQ,
ObjectIdGetDatum(objectId));
scan = systable_beginscan(depRel, DependDependerIndex, true,
SnapshotNow, 2, key);
while (HeapTupleIsValid(tup = systable_getnext(scan)))
{
simple_heap_delete(depRel, &tup->t_self);
}
systable_endscan(scan);
heap_close(depRel, RowExclusiveLock);
}
/* /*
* isObjectPinned() * isObjectPinned()
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.70 2002/06/20 20:29:26 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.71 2002/07/16 22:12:18 tgl Exp $
* *
* NOTES * NOTES
* these routines moved here from commands/define.c and somewhat cleaned up. * these routines moved here from commands/define.c and somewhat cleaned up.
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
...@@ -56,6 +57,8 @@ static Oid get_other_operator(List *otherOp, ...@@ -56,6 +57,8 @@ static Oid get_other_operator(List *otherOp,
Oid leftTypeId, Oid rightTypeId, Oid leftTypeId, Oid rightTypeId,
bool isCommutator); bool isCommutator);
static void makeOperatorDependencies(HeapTuple tuple, Oid pg_operator_relid);
/* /*
* Check whether a proposed operator name is legal * Check whether a proposed operator name is legal
...@@ -271,6 +274,9 @@ OperatorShellMake(const char *operatorName, ...@@ -271,6 +274,9 @@ OperatorShellMake(const char *operatorName,
CatalogCloseIndices(Num_pg_operator_indices, idescs); CatalogCloseIndices(Num_pg_operator_indices, idescs);
} }
/* Add dependencies for the entry */
makeOperatorDependencies(tup, RelationGetRelid(pg_operator_desc));
heap_freetuple(tup); heap_freetuple(tup);
/* /*
...@@ -659,6 +665,9 @@ OperatorCreate(const char *operatorName, ...@@ -659,6 +665,9 @@ OperatorCreate(const char *operatorName,
CatalogCloseIndices(Num_pg_operator_indices, idescs); CatalogCloseIndices(Num_pg_operator_indices, idescs);
} }
/* Add dependencies for the entry */
makeOperatorDependencies(tup, RelationGetRelid(pg_operator_desc));
heap_close(pg_operator_desc, RowExclusiveLock); heap_close(pg_operator_desc, RowExclusiveLock);
/* /*
...@@ -893,3 +902,89 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId) ...@@ -893,3 +902,89 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
heap_close(pg_operator_desc, RowExclusiveLock); heap_close(pg_operator_desc, RowExclusiveLock);
} }
/*
* Create dependencies for a new operator (either a freshly inserted
* complete operator, a new shell operator, or a just-updated shell).
*
* NB: the OidIsValid tests in this routine are *all* necessary, in case
* the given operator is a shell.
*/
static void
makeOperatorDependencies(HeapTuple tuple, Oid pg_operator_relid)
{
Form_pg_operator oper = (Form_pg_operator) GETSTRUCT(tuple);
ObjectAddress myself,
referenced;
myself.classId = pg_operator_relid;
myself.objectId = tuple->t_data->t_oid;
myself.objectSubId = 0;
/* In case we are updating a shell, delete any existing entries */
deleteDependencyRecordsFor(myself.classId, myself.objectId);
/* Dependency on left type */
if (OidIsValid(oper->oprleft))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = oper->oprleft;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Dependency on right type */
if (OidIsValid(oper->oprright))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = oper->oprright;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Dependency on result type */
if (OidIsValid(oper->oprresult))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = oper->oprresult;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/*
* NOTE: we do not consider the operator to depend on the associated
* operators oprcom, oprnegate, oprlsortop, oprrsortop, oprltcmpop,
* oprgtcmpop. We would not want to delete this operator if those
* go away, but only reset the link fields; which is not a function
* that the dependency code can presently handle. (Something could
* perhaps be done with objectSubId though.) For now, it's okay to
* let those links dangle if a referenced operator is removed.
*/
/* Dependency on implementation function */
if (OidIsValid(oper->oprcode))
{
referenced.classId = RelOid_pg_proc;
referenced.objectId = oper->oprcode;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Dependency on restriction selectivity function */
if (OidIsValid(oper->oprrest))
{
referenced.classId = RelOid_pg_proc;
referenced.objectId = oper->oprrest;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Dependency on join selectivity function */
if (OidIsValid(oper->oprjoin))
{
referenced.classId = RelOid_pg_proc;
referenced.objectId = oper->oprjoin;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
}
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.76 2002/06/20 20:29:26 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.77 2002/07/16 22:12:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
...@@ -76,6 +77,9 @@ ProcedureCreate(const char *procedureName, ...@@ -76,6 +77,9 @@ ProcedureCreate(const char *procedureName,
NameData procname; NameData procname;
TupleDesc tupDesc; TupleDesc tupDesc;
Oid retval; Oid retval;
bool is_update;
ObjectAddress myself,
referenced;
/* /*
* sanity checks * sanity checks
...@@ -227,6 +231,7 @@ ProcedureCreate(const char *procedureName, ...@@ -227,6 +231,7 @@ ProcedureCreate(const char *procedureName,
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);
ReleaseSysCache(oldtup); ReleaseSysCache(oldtup);
is_update = true;
} }
else else
{ {
...@@ -237,6 +242,7 @@ ProcedureCreate(const char *procedureName, ...@@ -237,6 +242,7 @@ ProcedureCreate(const char *procedureName,
tup = heap_formtuple(tupDesc, values, nulls); tup = heap_formtuple(tupDesc, values, nulls);
simple_heap_insert(rel, tup); simple_heap_insert(rel, tup);
is_update = false;
} }
/* Need to update indices for either the insert or update case */ /* Need to update indices for either the insert or update case */
...@@ -250,6 +256,45 @@ ProcedureCreate(const char *procedureName, ...@@ -250,6 +256,45 @@ ProcedureCreate(const char *procedureName,
} }
retval = tup->t_data->t_oid; retval = tup->t_data->t_oid;
/*
* Create dependencies for the new function. If we are updating an
* existing function, first delete any existing pg_depend entries.
*/
if (is_update)
deleteDependencyRecordsFor(RelOid_pg_proc, retval);
myself.classId = RelOid_pg_proc;
myself.objectId = retval;
myself.objectSubId = 0;
/* dependency on implementation language */
referenced.classId = get_system_catalog_relid(LanguageRelationName);
referenced.objectId = languageObjectId;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* dependency on return type */
if (OidIsValid(returnType))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = returnType;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* dependency on input types */
for (i = 0; i < parameterCount; i++)
{
if (OidIsValid(typev[i]))
{
referenced.classId = RelOid_pg_type;
referenced.objectId = typev[i];
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
}
heap_freetuple(tup); heap_freetuple(tup);
heap_close(rel, RowExclusiveLock); heap_close(rel, RowExclusiveLock);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.35 2002/07/12 18:43:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.36 2002/07/16 22:12:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -49,6 +49,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) ...@@ -49,6 +49,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
HeapTuple tup; HeapTuple tup;
TupleDesc tupDesc; TupleDesc tupDesc;
int i; int i;
ObjectAddress myself,
referenced;
/* /*
* Check permission * Check permission
...@@ -91,7 +93,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) ...@@ -91,7 +93,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
NameListToString(stmt->plvalidator)); NameListToString(stmt->plvalidator));
} }
else else
valProcOid = 0; valProcOid = InvalidOid;
/* /*
* Insert the new language into pg_language * Insert the new language into pg_language
...@@ -128,6 +130,28 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) ...@@ -128,6 +130,28 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
CatalogCloseIndices(Num_pg_language_indices, idescs); CatalogCloseIndices(Num_pg_language_indices, idescs);
} }
/*
* Create dependencies for language
*/
myself.classId = RelationGetRelid(rel);
myself.objectId = tup->t_data->t_oid;
myself.objectSubId = 0;
/* dependency on the PL handler function */
referenced.classId = RelOid_pg_proc;
referenced.objectId = procOid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* dependency on the validator function, if any */
if (OidIsValid(valProcOid))
{
referenced.classId = RelOid_pg_proc;
referenced.objectId = valProcOid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
heap_close(rel, RowExclusiveLock); heap_close(rel, RowExclusiveLock);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.82 2002/06/20 20:29:27 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.83 2002/07/16 22:12:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -124,11 +124,15 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -124,11 +124,15 @@ DefineSequence(CreateSeqStmt *seq)
typnam->setof = FALSE; typnam->setof = FALSE;
typnam->arrayBounds = NIL; typnam->arrayBounds = NIL;
typnam->typmod = -1; typnam->typmod = -1;
coldef = makeNode(ColumnDef); coldef = makeNode(ColumnDef);
coldef->typename = typnam; coldef->typename = typnam;
coldef->is_not_null = true;
coldef->raw_default = NULL; coldef->raw_default = NULL;
coldef->cooked_default = NULL; coldef->cooked_default = NULL;
coldef->is_not_null = false; coldef->constraints = NIL;
coldef->support = NULL;
null[i - 1] = ' '; null[i - 1] = ' ';
switch (i) switch (i)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.22 2002/07/16 05:53:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.23 2002/07/16 22:12:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -239,6 +239,10 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -239,6 +239,10 @@ DefineRelation(CreateStmt *stmt, char relkind)
* So, the transformation has to be postponed to this final step of * So, the transformation has to be postponed to this final step of
* CREATE TABLE. * CREATE TABLE.
* *
* Another task that's conveniently done at this step is to add
* dependency links between columns and supporting relations (such
* as SERIAL sequences).
*
* First, scan schema to find new column defaults. * First, scan schema to find new column defaults.
*/ */
rawDefaults = NIL; rawDefaults = NIL;
...@@ -247,18 +251,35 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -247,18 +251,35 @@ DefineRelation(CreateStmt *stmt, char relkind)
foreach(listptr, schema) foreach(listptr, schema)
{ {
ColumnDef *colDef = lfirst(listptr); ColumnDef *colDef = lfirst(listptr);
RawColumnDefault *rawEnt;
attnum++; attnum++;
if (colDef->raw_default == NULL) if (colDef->raw_default != NULL)
continue; {
Assert(colDef->cooked_default == NULL); RawColumnDefault *rawEnt;
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault)); Assert(colDef->cooked_default == NULL);
rawEnt->attnum = attnum;
rawEnt->raw_default = colDef->raw_default; rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
rawDefaults = lappend(rawDefaults, rawEnt); rawEnt->attnum = attnum;
rawEnt->raw_default = colDef->raw_default;
rawDefaults = lappend(rawDefaults, rawEnt);
}
if (colDef->support != NULL)
{
/* Create dependency for supporting relation for this column */
ObjectAddress colobject,
suppobject;
colobject.classId = RelOid_pg_class;
colobject.objectId = relationId;
colobject.objectSubId = attnum;
suppobject.classId = RelOid_pg_class;
suppobject.objectId = RangeVarGetRelid(colDef->support, false);
suppobject.objectSubId = 0;
recordDependencyOn(&suppobject, &colobject, DEPENDENCY_INTERNAL);
}
} }
/* /*
...@@ -533,6 +554,7 @@ MergeAttributes(List *schema, List *supers, bool istemp, ...@@ -533,6 +554,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
def->raw_default = NULL; def->raw_default = NULL;
def->cooked_default = NULL; def->cooked_default = NULL;
def->constraints = NIL; def->constraints = NIL;
def->support = NULL;
inhSchema = lappend(inhSchema, def); inhSchema = lappend(inhSchema, def);
newattno[parent_attno - 1] = ++child_attno; newattno[parent_attno - 1] = ++child_attno;
} }
...@@ -1524,6 +1546,8 @@ AlterTableAddColumn(Oid myrelid, ...@@ -1524,6 +1546,8 @@ AlterTableAddColumn(Oid myrelid,
HeapTuple typeTuple; HeapTuple typeTuple;
Form_pg_type tform; Form_pg_type tform;
int attndims; int attndims;
ObjectAddress myself,
referenced;
/* /*
* Grab an exclusive lock on the target table, which we will NOT * Grab an exclusive lock on the target table, which we will NOT
...@@ -1697,6 +1721,17 @@ AlterTableAddColumn(Oid myrelid, ...@@ -1697,6 +1721,17 @@ AlterTableAddColumn(Oid myrelid,
heap_close(rel, NoLock); /* close rel but keep lock! */ heap_close(rel, NoLock); /* close rel but keep lock! */
/*
* Add datatype dependency for the new column.
*/
myself.classId = RelOid_pg_class;
myself.objectId = myrelid;
myself.objectSubId = i;
referenced.classId = RelOid_pg_type;
referenced.objectId = attribute->atttypid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* /*
* Make our catalog updates visible for subsequent steps. * Make our catalog updates visible for subsequent steps.
*/ */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.5 2002/07/12 18:43:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.6 2002/07/16 22:12:19 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -358,15 +358,18 @@ DefineDomain(CreateDomainStmt *stmt) ...@@ -358,15 +358,18 @@ DefineDomain(CreateDomainStmt *stmt)
char typtype; char typtype;
Datum datum; Datum datum;
bool isnull; bool isnull;
Node *defaultExpr = NULL;
char *defaultValue = NULL; char *defaultValue = NULL;
char *defaultValueBin = NULL; char *defaultValueBin = NULL;
bool typNotNull = false; bool typNotNull = false;
bool nullDefined = false;
Oid basetypelem; Oid basetypelem;
int32 typNDims = length(stmt->typename->arrayBounds); int32 typNDims = length(stmt->typename->arrayBounds);
HeapTuple typeTup; HeapTuple typeTup;
List *schema = stmt->constraints; List *schema = stmt->constraints;
List *listptr; List *listptr;
Oid basetypeoid; Oid basetypeoid;
Oid domainoid;
Form_pg_type baseType; Form_pg_type baseType;
/* Convert list of names to a name and namespace */ /* Convert list of names to a name and namespace */
...@@ -459,8 +462,6 @@ DefineDomain(CreateDomainStmt *stmt) ...@@ -459,8 +462,6 @@ DefineDomain(CreateDomainStmt *stmt)
foreach(listptr, schema) foreach(listptr, schema)
{ {
Constraint *colDef = lfirst(listptr); Constraint *colDef = lfirst(listptr);
bool nullDefined = false;
Node *expr;
ParseState *pstate; ParseState *pstate;
switch (colDef->contype) switch (colDef->contype)
...@@ -473,47 +474,45 @@ DefineDomain(CreateDomainStmt *stmt) ...@@ -473,47 +474,45 @@ DefineDomain(CreateDomainStmt *stmt)
* don't want to cook or fiddle too much. * don't want to cook or fiddle too much.
*/ */
case CONSTR_DEFAULT: case CONSTR_DEFAULT:
if (defaultExpr)
elog(ERROR, "CREATE DOMAIN has multiple DEFAULT expressions");
/* Create a dummy ParseState for transformExpr */ /* Create a dummy ParseState for transformExpr */
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
/* /*
* Cook the colDef->raw_expr into an expression. * Cook the colDef->raw_expr into an expression.
* Note: Name is strictly for error message * Note: Name is strictly for error message
*/ */
expr = cookDefault(pstate, colDef->raw_expr, defaultExpr = cookDefault(pstate, colDef->raw_expr,
basetypeoid, basetypeoid,
stmt->typename->typmod, stmt->typename->typmod,
domainName); domainName);
/* /*
* Expression must be stored as a nodeToString result, * Expression must be stored as a nodeToString result,
* but we also require a valid textual representation * but we also require a valid textual representation
* (mainly to make life easier for pg_dump). * (mainly to make life easier for pg_dump).
*/ */
defaultValue = deparse_expression(expr, defaultValue = deparse_expression(defaultExpr,
deparse_context_for(domainName, deparse_context_for(domainName,
InvalidOid), InvalidOid),
false); false);
defaultValueBin = nodeToString(expr); defaultValueBin = nodeToString(defaultExpr);
break; break;
/* /*
* Find the NULL constraint. * Find the NULL constraint.
*/ */
case CONSTR_NOTNULL: case CONSTR_NOTNULL:
if (nullDefined) { if (nullDefined)
elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint"); elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
} else { typNotNull = true;
typNotNull = true; nullDefined = true;
nullDefined = true;
}
break; break;
case CONSTR_NULL: case CONSTR_NULL:
if (nullDefined) { if (nullDefined)
elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint"); elog(ERROR, "CREATE DOMAIN has conflicting NULL / NOT NULL constraint");
} else { typNotNull = false;
typNotNull = false; nullDefined = true;
nullDefined = true;
}
break; break;
case CONSTR_UNIQUE: case CONSTR_UNIQUE:
...@@ -544,28 +543,44 @@ DefineDomain(CreateDomainStmt *stmt) ...@@ -544,28 +543,44 @@ DefineDomain(CreateDomainStmt *stmt)
/* /*
* Have TypeCreate do all the real work. * Have TypeCreate do all the real work.
*/ */
TypeCreate(domainName, /* type name */ domainoid =
domainNamespace, /* namespace */ TypeCreate(domainName, /* type name */
InvalidOid, /* preassigned type oid (none here) */ domainNamespace, /* namespace */
InvalidOid, /* relation oid (n/a here) */ InvalidOid, /* preassigned type oid (none here) */
internalLength, /* internal size */ InvalidOid, /* relation oid (n/a here) */
externalLength, /* external size */ internalLength, /* internal size */
'd', /* type-type (domain type) */ externalLength, /* external size */
delimiter, /* array element delimiter */ 'd', /* type-type (domain type) */
inputProcedure, /* input procedure */ delimiter, /* array element delimiter */
outputProcedure, /* output procedure */ inputProcedure, /* input procedure */
receiveProcedure, /* receive procedure */ outputProcedure, /* output procedure */
sendProcedure, /* send procedure */ receiveProcedure, /* receive procedure */
basetypelem, /* element type ID */ sendProcedure, /* send procedure */
basetypeoid, /* base type ID */ basetypelem, /* element type ID */
defaultValue, /* default type value (text) */ basetypeoid, /* base type ID */
defaultValueBin, /* default type value (binary) */ defaultValue, /* default type value (text) */
byValue, /* passed by value */ defaultValueBin, /* default type value (binary) */
alignment, /* required alignment */ byValue, /* passed by value */
storage, /* TOAST strategy */ alignment, /* required alignment */
stmt->typename->typmod, /* typeMod value */ storage, /* TOAST strategy */
typNDims, /* Array dimensions for base type */ stmt->typename->typmod, /* typeMod value */
typNotNull); /* Type NOT NULL */ typNDims, /* Array dimensions for base type */
typNotNull); /* Type NOT NULL */
/*
* Add any dependencies needed for the default expression.
*/
if (defaultExpr)
{
ObjectAddress domobject;
domobject.classId = RelOid_pg_type;
domobject.objectId = domainoid;
domobject.objectSubId = 0;
recordDependencyOnExpr(&domobject, defaultExpr, NIL,
DEPENDENCY_NORMAL);
}
/* /*
* Now we can clean up. * Now we can clean up.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: view.c,v 1.66 2002/07/12 18:43:16 tgl Exp $ * $Id: view.c,v 1.67 2002/07/16 22:12:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -72,6 +72,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist) ...@@ -72,6 +72,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist)
def->raw_default = NULL; def->raw_default = NULL;
def->cooked_default = NULL; def->cooked_default = NULL;
def->constraints = NIL; def->constraints = NIL;
def->support = NULL;
attrList = lappend(attrList, def); attrList = lappend(attrList, def);
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.193 2002/07/12 18:43:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.194 2002/07/16 22:12:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1749,6 +1749,7 @@ _copyColumnDef(ColumnDef *from) ...@@ -1749,6 +1749,7 @@ _copyColumnDef(ColumnDef *from)
if (from->cooked_default) if (from->cooked_default)
newnode->cooked_default = pstrdup(from->cooked_default); newnode->cooked_default = pstrdup(from->cooked_default);
Node_Copy(from, newnode, constraints); Node_Copy(from, newnode, constraints);
Node_Copy(from, newnode, support);
return newnode; return newnode;
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.140 2002/07/12 18:43:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.141 2002/07/16 22:12:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1636,6 +1636,8 @@ _equalColumnDef(ColumnDef *a, ColumnDef *b) ...@@ -1636,6 +1636,8 @@ _equalColumnDef(ColumnDef *a, ColumnDef *b)
return false; return false;
if (!equal(a->constraints, b->constraints)) if (!equal(a->constraints, b->constraints))
return false; return false;
if (!equal(a->support, b->support))
return false;
return true; return true;
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.162 2002/07/12 18:43:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.163 2002/07/16 22:12:19 tgl Exp $
* *
* NOTES * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
...@@ -183,6 +183,8 @@ _outColumnDef(StringInfo str, ColumnDef *node) ...@@ -183,6 +183,8 @@ _outColumnDef(StringInfo str, ColumnDef *node)
_outToken(str, node->cooked_default); _outToken(str, node->cooked_default);
appendStringInfo(str, " :constraints "); appendStringInfo(str, " :constraints ");
_outNode(str, node->constraints); _outNode(str, node->constraints);
appendStringInfo(str, " :support ");
_outNode(str, node->support);
} }
static void static void
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.238 2002/07/12 18:43:17 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.239 2002/07/16 22:12:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -847,6 +847,12 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt, ...@@ -847,6 +847,12 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
cxt->blist = lappend(cxt->blist, seqstmt); cxt->blist = lappend(cxt->blist, seqstmt);
/*
* Mark the ColumnDef so that during execution, an appropriate
* dependency will be added from the sequence to the column.
*/
column->support = makeRangeVar(snamespace, sname);
/* /*
* Create appropriate constraints for SERIAL. We do this in full, * Create appropriate constraints for SERIAL. We do this in full,
* rather than shortcutting, so that we will detect any * rather than shortcutting, so that we will detect any
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.340 2002/07/14 23:38:13 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.341 2002/07/16 22:12:20 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -1852,10 +1852,11 @@ CreateAsElement: ...@@ -1852,10 +1852,11 @@ CreateAsElement:
ColumnDef *n = makeNode(ColumnDef); ColumnDef *n = makeNode(ColumnDef);
n->colname = $1; n->colname = $1;
n->typename = NULL; n->typename = NULL;
n->is_not_null = false;
n->raw_default = NULL; n->raw_default = NULL;
n->cooked_default = NULL; n->cooked_default = NULL;
n->is_not_null = FALSE; n->constraints = NIL;
n->constraints = NULL; n->support = NULL;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: dependency.h,v 1.2 2002/07/16 05:53:34 tgl Exp $ * $Id: dependency.h,v 1.3 2002/07/16 22:12:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -98,4 +98,6 @@ extern void recordMultipleDependencies(const ObjectAddress *depender, ...@@ -98,4 +98,6 @@ extern void recordMultipleDependencies(const ObjectAddress *depender,
int nreferenced, int nreferenced,
DependencyType behavior); DependencyType behavior);
extern void deleteDependencyRecordsFor(Oid classId, Oid objectId);
#endif /* DEPENDENCY_H */ #endif /* DEPENDENCY_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parsenodes.h,v 1.186 2002/07/14 23:38:13 tgl Exp $ * $Id: parsenodes.h,v 1.187 2002/07/16 22:12:20 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -269,6 +269,10 @@ typedef struct BooleanTest ...@@ -269,6 +269,10 @@ typedef struct BooleanTest
* parsetree produced by gram.y, but transformCreateStmt will remove * parsetree produced by gram.y, but transformCreateStmt will remove
* the item and set raw_default instead. CONSTR_DEFAULT items * the item and set raw_default instead. CONSTR_DEFAULT items
* should not appear in any subsequent processing. * should not appear in any subsequent processing.
*
* The "support" field, if not null, denotes a supporting relation that
* should be linked by an internal dependency to the column. Currently
* this is only used to link a SERIAL column's sequence to the column.
*/ */
typedef struct ColumnDef typedef struct ColumnDef
{ {
...@@ -280,6 +284,7 @@ typedef struct ColumnDef ...@@ -280,6 +284,7 @@ typedef struct ColumnDef
* tree) */ * tree) */
char *cooked_default; /* nodeToString representation */ char *cooked_default; /* nodeToString representation */
List *constraints; /* other constraints on column */ List *constraints; /* other constraints on column */
RangeVar *support; /* supporting relation, if any */
} 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