mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Ensure that typmod decoration on a datatype name is validated in all cases,
even in code paths where we don't pay any subsequent attention to the typmod value. This seems needed in view of the fact that 8.3's generalized typmod support will accept a lot of bogus syntax, such as "timestamp(foo)" or "record(int, 42)" --- if we allow such things to pass without comment, users will get confused. Per a recent example from Greg Stark. To implement this in a way that's not very vulnerable to future bugs-of-omission, refactor the API of parse_type.c's TypeName lookup routines so that typmod validation is folded into the base lookup operation. Callers can still choose not to receive the encoded typmod, but we'll check the decoration anyway if it's present.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.234 2007/10/12 18:55:12 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.235 2007/11/11 19:22:48 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -899,8 +899,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
|
||||
(errmsg("merging multiple inherited definitions of column \"%s\"",
|
||||
attributeName)));
|
||||
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
|
||||
defTypeId = typenameTypeId(NULL, def->typename);
|
||||
deftypmod = typenameTypeMod(NULL, def->typename, defTypeId);
|
||||
defTypeId = typenameTypeId(NULL, def->typename, &deftypmod);
|
||||
if (defTypeId != attribute->atttypid ||
|
||||
deftypmod != attribute->atttypmod)
|
||||
ereport(ERROR,
|
||||
@ -1044,10 +1043,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
|
||||
(errmsg("merging column \"%s\" with inherited definition",
|
||||
attributeName)));
|
||||
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
|
||||
defTypeId = typenameTypeId(NULL, def->typename);
|
||||
deftypmod = typenameTypeMod(NULL, def->typename, defTypeId);
|
||||
newTypeId = typenameTypeId(NULL, newdef->typename);
|
||||
newtypmod = typenameTypeMod(NULL, newdef->typename, newTypeId);
|
||||
defTypeId = typenameTypeId(NULL, def->typename, &deftypmod);
|
||||
newTypeId = typenameTypeId(NULL, newdef->typename, &newtypmod);
|
||||
if (defTypeId != newTypeId || deftypmod != newtypmod)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
@ -3018,8 +3015,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
|
||||
int32 ctypmod;
|
||||
|
||||
/* Okay if child matches by type */
|
||||
ctypeId = typenameTypeId(NULL, colDef->typename);
|
||||
ctypmod = typenameTypeMod(NULL, colDef->typename, ctypeId);
|
||||
ctypeId = typenameTypeId(NULL, colDef->typename, &ctypmod);
|
||||
if (ctypeId != childatt->atttypid ||
|
||||
ctypmod != childatt->atttypmod)
|
||||
ereport(ERROR,
|
||||
@ -3074,10 +3070,9 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
|
||||
MaxHeapAttributeNumber)));
|
||||
i = minattnum + 1;
|
||||
|
||||
typeTuple = typenameType(NULL, colDef->typename);
|
||||
typeTuple = typenameType(NULL, colDef->typename, &typmod);
|
||||
tform = (Form_pg_type) GETSTRUCT(typeTuple);
|
||||
typeOid = HeapTupleGetOid(typeTuple);
|
||||
typmod = typenameTypeMod(NULL, colDef->typename, typeOid);
|
||||
|
||||
/* make sure datatype is legal for a column */
|
||||
CheckAttributeType(colDef->colname, typeOid);
|
||||
@ -4777,8 +4772,7 @@ ATPrepAlterColumnType(List **wqueue,
|
||||
colName)));
|
||||
|
||||
/* Look up the target type */
|
||||
targettype = typenameTypeId(NULL, typename);
|
||||
targettypmod = typenameTypeMod(NULL, typename, targettype);
|
||||
targettype = typenameTypeId(NULL, typename, &targettypmod);
|
||||
|
||||
/* make sure datatype is legal for a column */
|
||||
CheckAttributeType(colName, targettype);
|
||||
@ -4905,10 +4899,9 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
|
||||
colName)));
|
||||
|
||||
/* Look up the target type (should not fail, since prep found it) */
|
||||
typeTuple = typenameType(NULL, typename);
|
||||
typeTuple = typenameType(NULL, typename, &targettypmod);
|
||||
tform = (Form_pg_type) GETSTRUCT(typeTuple);
|
||||
targettype = HeapTupleGetOid(typeTuple);
|
||||
targettypmod = typenameTypeMod(NULL, typename, targettype);
|
||||
|
||||
/*
|
||||
* If there is a default expression for the column, get it and ensure we
|
||||
|
Reference in New Issue
Block a user