Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbb3da43

Browse files
committed
Allow use of table rowtypes directly as column types of other tables.
Instead of prohibiting that, put code into ALTER TABLE to reject ALTERsthat would affect other tables' columns. Eventually we will probablywant to extend ALTER TABLE to actually do something useful here, butin the meantime it seems wrong to forbid the feature completely justbecause ALTER isn't fully baked.
1 parent19e3bdd commitbb3da43

File tree

2 files changed

+98
-16
lines changed

2 files changed

+98
-16
lines changed

‎src/backend/catalog/heap.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.268 2004/06/0604:52:55 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.269 2004/06/0620:30:07 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -416,10 +416,7 @@ CheckAttributeType(const char *attname, Oid atttypid)
416416
* Warn user, but don't fail, if column to be created has UNKNOWN type
417417
* (usually as a result of a 'retrieve into' - jolly)
418418
*
419-
* Refuse any attempt to create a pseudo-type column or one that uses a
420-
* non-standalone composite type. (We could support using table rowtypes
421-
* as attributes, if we were willing to make ALTER TABLE hugely more
422-
* complex, but for now let's limit the damage ...)
419+
* Refuse any attempt to create a pseudo-type column.
423420
*/
424421
if (atttypid==UNKNOWNOID)
425422
ereport(WARNING,
@@ -435,16 +432,6 @@ CheckAttributeType(const char *attname, Oid atttypid)
435432
errmsg("column \"%s\" has pseudo-type %s",
436433
attname,format_type_be(atttypid))));
437434
}
438-
elseif (att_typtype=='c')
439-
{
440-
Oidtyprelid=get_typ_typrelid(atttypid);
441-
442-
if (get_rel_relkind(typrelid)!=RELKIND_COMPOSITE_TYPE)
443-
ereport(ERROR,
444-
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
445-
errmsg("column \"%s\" has composite type %s",
446-
attname,format_type_be(atttypid))));
447-
}
448435
}
449436

450437
/* --------------------------------

‎src/backend/commands/tablecmds.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.111 2004/06/05 19:48:07 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.112 2004/06/06 20:30:07 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -194,6 +194,8 @@ static void ATSimpleRecursion(List **wqueue, Relation rel,
194194
AlterTableCmd*cmd,boolrecurse);
195195
staticvoidATOneLevelRecursion(List**wqueue,Relationrel,
196196
AlterTableCmd*cmd);
197+
staticvoidfind_composite_type_dependencies(OidtypeOid,
198+
constchar*origTblName);
197199
staticvoidATPrepAddColumn(List**wqueue,Relationrel,boolrecurse,
198200
AlterTableCmd*cmd);
199201
staticvoidATExecAddColumn(AlteredTableInfo*tab,Relationrel,
@@ -2281,6 +2283,18 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
22812283
else
22822284
newrel=NULL;
22832285

2286+
/*
2287+
* If we need to rewrite the table, the operation has to be propagated
2288+
* to tables that use this table's rowtype as a column type.
2289+
*
2290+
* (Eventually this will probably become true for scans as well, but
2291+
* at the moment a composite type does not enforce any constraints,
2292+
* so it's not necessary/appropriate to enforce them just during ALTER.)
2293+
*/
2294+
if (newrel)
2295+
find_composite_type_dependencies(oldrel->rd_rel->reltype,
2296+
RelationGetRelationName(oldrel));
2297+
22842298
/*
22852299
* Generate the constraint and default execution states
22862300
*/
@@ -2606,6 +2620,87 @@ ATOneLevelRecursion(List **wqueue, Relation rel,
26062620
}
26072621
}
26082622

2623+
2624+
/*
2625+
* find_composite_type_dependencies
2626+
*
2627+
* Check to see if a table's rowtype is being used as a column in some
2628+
* other table (possibly nested several levels deep in composite types!).
2629+
* Eventually, we'd like to propagate the check or rewrite operation
2630+
* into other such tables, but for now, just error out if we find any.
2631+
*
2632+
* We assume that functions and views depending on the type are not reasons
2633+
* to reject the ALTER. (How safe is this really?)
2634+
*/
2635+
staticvoid
2636+
find_composite_type_dependencies(OidtypeOid,constchar*origTblName)
2637+
{
2638+
RelationdepRel;
2639+
ScanKeyDatakey[2];
2640+
SysScanDescdepScan;
2641+
HeapTupledepTup;
2642+
2643+
/*
2644+
* We scan pg_depend to find those things that depend on the rowtype.
2645+
* (We assume we can ignore refobjsubid for a rowtype.)
2646+
*/
2647+
depRel=relation_openr(DependRelationName,AccessShareLock);
2648+
2649+
ScanKeyInit(&key[0],
2650+
Anum_pg_depend_refclassid,
2651+
BTEqualStrategyNumber,F_OIDEQ,
2652+
ObjectIdGetDatum(RelOid_pg_type));
2653+
ScanKeyInit(&key[1],
2654+
Anum_pg_depend_refobjid,
2655+
BTEqualStrategyNumber,F_OIDEQ,
2656+
ObjectIdGetDatum(typeOid));
2657+
2658+
depScan=systable_beginscan(depRel,DependReferenceIndex, true,
2659+
SnapshotNow,2,key);
2660+
2661+
while (HeapTupleIsValid(depTup=systable_getnext(depScan)))
2662+
{
2663+
Form_pg_dependpg_depend= (Form_pg_depend)GETSTRUCT(depTup);
2664+
Relationrel;
2665+
Form_pg_attributeatt;
2666+
2667+
/* Ignore dependees that aren't user columns of relations */
2668+
/* (we assume system columns are never of rowtypes) */
2669+
if (pg_depend->classid!=RelOid_pg_class||
2670+
pg_depend->objsubid <=0)
2671+
continue;
2672+
2673+
rel=relation_open(pg_depend->objid,AccessShareLock);
2674+
att=rel->rd_att->attrs[pg_depend->objsubid-1];
2675+
2676+
if (rel->rd_rel->relkind==RELKIND_RELATION)
2677+
{
2678+
ereport(ERROR,
2679+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2680+
errmsg("cannot alter table \"%s\" because column \"%s\".\"%s\" uses its rowtype",
2681+
origTblName,
2682+
RelationGetRelationName(rel),
2683+
NameStr(att->attname))));
2684+
}
2685+
elseif (OidIsValid(rel->rd_rel->reltype))
2686+
{
2687+
/*
2688+
* A view or composite type itself isn't a problem, but we must
2689+
* recursively check for indirect dependencies via its rowtype.
2690+
*/
2691+
find_composite_type_dependencies(rel->rd_rel->reltype,
2692+
origTblName);
2693+
}
2694+
2695+
relation_close(rel,AccessShareLock);
2696+
}
2697+
2698+
systable_endscan(depScan);
2699+
2700+
relation_close(depRel,AccessShareLock);
2701+
}
2702+
2703+
26092704
/*
26102705
* ALTER TABLE ADD COLUMN
26112706
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp