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

Commiteb51af7

Browse files
committed
Prevent a rowtype from being included in itself.
Eventually we might be able to allow that, but it's not clear how manyplaces need to be fixed to prevent infinite recursion when there's a director indirect inclusion of a rowtype in itself. One such place isCheckAttributeType(), which will recurse to stack overflow in cases such asthose exhibited in bug #5950 from Alex Perepelica. If we were sure it wasthe only such place, we could easily modify the code added by this patch tostop the recursion without a complaint ... but it probably isn't the onlysuch place. Hence, throw error until such time as someone is excitedenough about this type of usage to put work into making it safe.Back-patch as far as 8.3. 8.2 doesn't have the recursive call inCheckAttributeType in the first place, so I see no need to add code therein the absence of clear evidence of a problem elsewhere.
1 parent5c22c0e commiteb51af7

File tree

6 files changed

+76
-10
lines changed

6 files changed

+76
-10
lines changed

‎src/backend/catalog/heap.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
431431
CheckAttributeType(NameStr(tupdesc->attrs[i]->attname),
432432
tupdesc->attrs[i]->atttypid,
433433
tupdesc->attrs[i]->attcollation,
434+
NIL,/* assume we're creating a new rowtype */
434435
allow_system_table_mods);
435436
}
436437
}
@@ -439,15 +440,25 @@ CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
439440
*CheckAttributeType
440441
*
441442
*Verify that the proposed datatype of an attribute is legal.
442-
*This is needed because there are types (and pseudo-types)
443+
*This is neededmainlybecause there are types (and pseudo-types)
443444
*in the catalogs that we do not support as elements of real tuples.
445+
*We also check some other properties required of a table column.
446+
*
447+
* If the attribute is being proposed for addition to an existing table or
448+
* composite type, pass a one-element list of the rowtype OID as
449+
* containing_rowtypes. When checking a to-be-created rowtype, it's
450+
* sufficient to pass NIL, because there could not be any recursive reference
451+
* to a not-yet-existing rowtype.
444452
* --------------------------------
445453
*/
446454
void
447-
CheckAttributeType(constchar*attname,Oidatttypid,Oidattcollation,
455+
CheckAttributeType(constchar*attname,
456+
Oidatttypid,Oidattcollation,
457+
List*containing_rowtypes,
448458
boolallow_system_table_mods)
449459
{
450460
charatt_typtype=get_typtype(atttypid);
461+
Oidatt_typelem;
451462

452463
if (atttypid==UNKNOWNOID)
453464
{
@@ -485,6 +496,20 @@ CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation,
485496
TupleDesctupdesc;
486497
inti;
487498

499+
/*
500+
* Check for self-containment. Eventually we might be able to allow
501+
* this (just return without complaint, if so) but it's not clear how
502+
* many other places would require anti-recursion defenses before it
503+
* would be safe to allow tables to contain their own rowtype.
504+
*/
505+
if (list_member_oid(containing_rowtypes,atttypid))
506+
ereport(ERROR,
507+
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
508+
errmsg("composite type %s cannot be made a member of itself",
509+
format_type_be(atttypid))));
510+
511+
containing_rowtypes=lcons_oid(atttypid,containing_rowtypes);
512+
488513
relation=relation_open(get_typ_typrelid(atttypid),AccessShareLock);
489514

490515
tupdesc=RelationGetDescr(relation);
@@ -495,19 +520,31 @@ CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation,
495520

496521
if (attr->attisdropped)
497522
continue;
498-
CheckAttributeType(NameStr(attr->attname),attr->atttypid,attr->attcollation,
523+
CheckAttributeType(NameStr(attr->attname),
524+
attr->atttypid,attr->attcollation,
525+
containing_rowtypes,
499526
allow_system_table_mods);
500527
}
501528

502529
relation_close(relation,AccessShareLock);
530+
531+
containing_rowtypes=list_delete_first(containing_rowtypes);
532+
}
533+
elseif (OidIsValid((att_typelem=get_element_type(atttypid))))
534+
{
535+
/*
536+
* Must recurse into array types, too, in case they are composite.
537+
*/
538+
CheckAttributeType(attname,att_typelem,attcollation,
539+
containing_rowtypes,
540+
allow_system_table_mods);
503541
}
504542

505543
/*
506544
* This might not be strictly invalid per SQL standard, but it is
507-
* pretty useless, and it cannot be dumped, so we must disallow
508-
* it.
545+
* pretty useless, and it cannot be dumped, so we must disallow it.
509546
*/
510-
if (type_is_collatable(atttypid)&&!OidIsValid(attcollation))
547+
if (!OidIsValid(attcollation)&&type_is_collatable(atttypid))
511548
ereport(ERROR,
512549
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
513550
errmsg("no collation was derived for column \"%s\" with collatable type %s",

‎src/backend/catalog/index.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,9 @@ ConstructTupleDescriptor(Relation heapRelation,
403403
* whether a table column is of a safe type (which is why we
404404
* needn't check for the non-expression case).
405405
*/
406-
CheckAttributeType(NameStr(to->attname),to->atttypid,to->attcollation, false);
406+
CheckAttributeType(NameStr(to->attname),
407+
to->atttypid,to->attcollation,
408+
NIL, false);
407409
}
408410

409411
/*

‎src/backend/commands/tablecmds.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4221,7 +4221,9 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
42214221
collOid=GetColumnDefCollation(NULL,colDef,typeOid);
42224222

42234223
/* make sure datatype is legal for a column */
4224-
CheckAttributeType(colDef->colname,typeOid,collOid, false);
4224+
CheckAttributeType(colDef->colname,typeOid,collOid,
4225+
list_make1_oid(rel->rd_rel->reltype),
4226+
false);
42254227

42264228
/* construct new attribute's pg_attribute entry */
42274229
attribute.attrelid=myrelid;
@@ -6536,7 +6538,9 @@ ATPrepAlterColumnType(List **wqueue,
65366538
targetcollid=GetColumnDefCollation(NULL,def,targettype);
65376539

65386540
/* make sure datatype is legal for a column */
6539-
CheckAttributeType(colName,targettype,targetcollid, false);
6541+
CheckAttributeType(colName,targettype,targetcollid,
6542+
list_make1_oid(rel->rd_rel->reltype),
6543+
false);
65406544

65416545
if (tab->relkind==RELKIND_RELATION)
65426546
{

‎src/include/catalog/heap.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ extern Form_pg_attribute SystemAttributeByName(const char *attname,
117117
externvoidCheckAttributeNamesTypes(TupleDesctupdesc,charrelkind,
118118
boolallow_system_table_mods);
119119

120-
externvoidCheckAttributeType(constchar*attname,Oidatttypid,Oidattcollation,
120+
externvoidCheckAttributeType(constchar*attname,
121+
Oidatttypid,Oidattcollation,
122+
List*containing_rowtypes,
121123
boolallow_system_table_mods);
122124

123125
#endif/* HEAP_H */

‎src/test/regress/expected/alter_table.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,6 +1493,18 @@ create table tab1 (a int, b text);
14931493
create table tab2 (x int, y tab1);
14941494
alter table tab1 alter column b type varchar; -- fails
14951495
ERROR: cannot alter table "tab1" because column "tab2"."y" uses its rowtype
1496+
-- disallow recursive containment of row types
1497+
create temp table recur1 (f1 int);
1498+
alter table recur1 add column f2 recur1; -- fails
1499+
ERROR: composite type recur1 cannot be made a member of itself
1500+
alter table recur1 add column f2 recur1[]; -- fails
1501+
ERROR: composite type recur1 cannot be made a member of itself
1502+
create temp table recur2 (f1 int, f2 recur1);
1503+
alter table recur1 add column f2 recur2; -- fails
1504+
ERROR: composite type recur1 cannot be made a member of itself
1505+
alter table recur1 add column f2 int;
1506+
alter table recur1 alter column f2 type recur2; -- fails
1507+
ERROR: composite type recur1 cannot be made a member of itself
14961508
--
14971509
-- lock levels
14981510
--

‎src/test/regress/sql/alter_table.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,15 @@ create table tab1 (a int, b text);
11121112
createtabletab2 (xint, y tab1);
11131113
altertable tab1 alter column b typevarchar;-- fails
11141114

1115+
-- disallow recursive containment of row types
1116+
create temp table recur1 (f1int);
1117+
altertable recur1 add column f2 recur1;-- fails
1118+
altertable recur1 add column f2 recur1[];-- fails
1119+
create temp table recur2 (f1int, f2 recur1);
1120+
altertable recur1 add column f2 recur2;-- fails
1121+
altertable recur1 add column f2int;
1122+
altertable recur1 alter column f2 type recur2;-- fails
1123+
11151124
--
11161125
-- lock levels
11171126
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp