Add more checks against altering typed tables
- Prohibit altering column type - Prohibit changing inheritance - Move checks from Exec to Prep phases in ALTER TABLE code backpatched to 9.0
This commit is contained in:
parent
87e0b7422d
commit
0156840e4e
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.332 2010/07/06 19:18:56 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.333 2010/07/23 20:04:18 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -288,6 +288,7 @@ static void ATExecSetOptions(Relation rel, const char *colName,
|
||||||
Node *options, bool isReset);
|
Node *options, bool isReset);
|
||||||
static void ATExecSetStorage(Relation rel, const char *colName,
|
static void ATExecSetStorage(Relation rel, const char *colName,
|
||||||
Node *newValue);
|
Node *newValue);
|
||||||
|
static void ATPrepDropColumn(Relation rel, bool recurse, AlterTableCmd *cmd);
|
||||||
static void ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
|
static void ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
|
||||||
DropBehavior behavior,
|
DropBehavior behavior,
|
||||||
bool recurse, bool recursing,
|
bool recurse, bool recursing,
|
||||||
|
@ -327,7 +328,8 @@ static void ATExecEnableDisableTrigger(Relation rel, char *trigname,
|
||||||
char fires_when, bool skip_system);
|
char fires_when, bool skip_system);
|
||||||
static void ATExecEnableDisableRule(Relation rel, char *rulename,
|
static void ATExecEnableDisableRule(Relation rel, char *rulename,
|
||||||
char fires_when);
|
char fires_when);
|
||||||
static void ATExecAddInherit(Relation rel, RangeVar *parent);
|
static void ATPrepAddInherit(Relation child_rel);
|
||||||
|
static void ATExecAddInherit(Relation child_rel, RangeVar *parent);
|
||||||
static void ATExecDropInherit(Relation rel, RangeVar *parent);
|
static void ATExecDropInherit(Relation rel, RangeVar *parent);
|
||||||
static void copy_relation_data(SMgrRelation rel, SMgrRelation dst,
|
static void copy_relation_data(SMgrRelation rel, SMgrRelation dst,
|
||||||
ForkNumber forkNum, bool istemp);
|
ForkNumber forkNum, bool istemp);
|
||||||
|
@ -2499,10 +2501,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
|
||||||
break;
|
break;
|
||||||
case AT_DropColumn: /* DROP COLUMN */
|
case AT_DropColumn: /* DROP COLUMN */
|
||||||
ATSimplePermissions(rel, false);
|
ATSimplePermissions(rel, false);
|
||||||
|
ATPrepDropColumn(rel, recurse, cmd);
|
||||||
/* Recursion occurs during execution phase */
|
/* Recursion occurs during execution phase */
|
||||||
/* No command-specific prep needed except saving recurse flag */
|
|
||||||
if (recurse)
|
|
||||||
cmd->subtype = AT_DropColumnRecurse;
|
|
||||||
pass = AT_PASS_DROP;
|
pass = AT_PASS_DROP;
|
||||||
break;
|
break;
|
||||||
case AT_AddIndex: /* ADD INDEX */
|
case AT_AddIndex: /* ADD INDEX */
|
||||||
|
@ -2579,6 +2579,12 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
|
||||||
/* No command-specific prep needed */
|
/* No command-specific prep needed */
|
||||||
pass = AT_PASS_MISC;
|
pass = AT_PASS_MISC;
|
||||||
break;
|
break;
|
||||||
|
case AT_AddInherit: /* INHERIT */
|
||||||
|
ATSimplePermissions(rel, false);
|
||||||
|
/* This command never recurses */
|
||||||
|
ATPrepAddInherit(rel);
|
||||||
|
pass = AT_PASS_MISC;
|
||||||
|
break;
|
||||||
case AT_EnableTrig: /* ENABLE TRIGGER variants */
|
case AT_EnableTrig: /* ENABLE TRIGGER variants */
|
||||||
case AT_EnableAlwaysTrig:
|
case AT_EnableAlwaysTrig:
|
||||||
case AT_EnableReplicaTrig:
|
case AT_EnableReplicaTrig:
|
||||||
|
@ -2591,8 +2597,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
|
||||||
case AT_EnableAlwaysRule:
|
case AT_EnableAlwaysRule:
|
||||||
case AT_EnableReplicaRule:
|
case AT_EnableReplicaRule:
|
||||||
case AT_DisableRule:
|
case AT_DisableRule:
|
||||||
case AT_AddInherit: /* INHERIT / NO INHERIT */
|
case AT_DropInherit: /* NO INHERIT */
|
||||||
case AT_DropInherit:
|
|
||||||
ATSimplePermissions(rel, false);
|
ATSimplePermissions(rel, false);
|
||||||
/* These commands never recurse */
|
/* These commands never recurse */
|
||||||
/* No command-specific prep needed */
|
/* No command-specific prep needed */
|
||||||
|
@ -3568,6 +3573,11 @@ static void
|
||||||
ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
|
ATPrepAddColumn(List **wqueue, Relation rel, bool recurse,
|
||||||
AlterTableCmd *cmd)
|
AlterTableCmd *cmd)
|
||||||
{
|
{
|
||||||
|
if (rel->rd_rel->reloftype)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
|
errmsg("cannot add column to typed table")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recurse to add the column to child classes, if requested.
|
* Recurse to add the column to child classes, if requested.
|
||||||
*
|
*
|
||||||
|
@ -3616,11 +3626,6 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
|
||||||
Form_pg_type tform;
|
Form_pg_type tform;
|
||||||
Expr *defval;
|
Expr *defval;
|
||||||
|
|
||||||
if (rel->rd_rel->reloftype)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
|
||||||
errmsg("cannot add column to typed table")));
|
|
||||||
|
|
||||||
attrdesc = heap_open(AttributeRelationId, RowExclusiveLock);
|
attrdesc = heap_open(AttributeRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4325,6 +4330,19 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue)
|
||||||
* static pre-pass because it won't handle multiple inheritance situations
|
* static pre-pass because it won't handle multiple inheritance situations
|
||||||
* correctly.)
|
* correctly.)
|
||||||
*/
|
*/
|
||||||
|
static void
|
||||||
|
ATPrepDropColumn(Relation rel, bool recurse, AlterTableCmd *cmd)
|
||||||
|
{
|
||||||
|
if (rel->rd_rel->reloftype)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
|
errmsg("cannot drop column from typed table")));
|
||||||
|
|
||||||
|
/* No command-specific prep needed except saving recurse flag */
|
||||||
|
if (recurse)
|
||||||
|
cmd->subtype = AT_DropColumnRecurse;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
|
ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
|
||||||
DropBehavior behavior,
|
DropBehavior behavior,
|
||||||
|
@ -4337,11 +4355,6 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
|
||||||
List *children;
|
List *children;
|
||||||
ObjectAddress object;
|
ObjectAddress object;
|
||||||
|
|
||||||
if (rel->rd_rel->reloftype)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
|
||||||
errmsg("cannot drop column from typed table")));
|
|
||||||
|
|
||||||
/* At top level, permission check was done in ATPrepCmd, else do it */
|
/* At top level, permission check was done in ATPrepCmd, else do it */
|
||||||
if (recursing)
|
if (recursing)
|
||||||
ATSimplePermissions(rel, false);
|
ATSimplePermissions(rel, false);
|
||||||
|
@ -5788,6 +5801,11 @@ ATPrepAlterColumnType(List **wqueue,
|
||||||
NewColumnValue *newval;
|
NewColumnValue *newval;
|
||||||
ParseState *pstate = make_parsestate(NULL);
|
ParseState *pstate = make_parsestate(NULL);
|
||||||
|
|
||||||
|
if (rel->rd_rel->reloftype)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
|
errmsg("cannot alter column type of typed table")));
|
||||||
|
|
||||||
/* lookup the attribute so we can check inheritance status */
|
/* lookup the attribute so we can check inheritance status */
|
||||||
tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
|
tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
@ -7115,6 +7133,15 @@ ATExecEnableDisableRule(Relation rel, char *trigname,
|
||||||
* check constraints of the parent appear in the child and that they have the
|
* check constraints of the parent appear in the child and that they have the
|
||||||
* same data types and expressions.
|
* same data types and expressions.
|
||||||
*/
|
*/
|
||||||
|
static void
|
||||||
|
ATPrepAddInherit(Relation child_rel)
|
||||||
|
{
|
||||||
|
if (child_rel->rd_rel->reloftype)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
|
errmsg("cannot change inheritance of typed table")));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ATExecAddInherit(Relation child_rel, RangeVar *parent)
|
ATExecAddInherit(Relation child_rel, RangeVar *parent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,12 +25,18 @@ SELECT * FROM get_all_persons();
|
||||||
----+------
|
----+------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
|
-- certain ALTER TABLE operations on typed tables are not allowed
|
||||||
ALTER TABLE persons ADD COLUMN comment text;
|
ALTER TABLE persons ADD COLUMN comment text;
|
||||||
ERROR: cannot add column to typed table
|
ERROR: cannot add column to typed table
|
||||||
ALTER TABLE persons DROP COLUMN name;
|
ALTER TABLE persons DROP COLUMN name;
|
||||||
ERROR: cannot drop column from typed table
|
ERROR: cannot drop column from typed table
|
||||||
ALTER TABLE persons RENAME COLUMN id TO num;
|
ALTER TABLE persons RENAME COLUMN id TO num;
|
||||||
ERROR: cannot rename column of typed table
|
ERROR: cannot rename column of typed table
|
||||||
|
ALTER TABLE persons ALTER COLUMN name TYPE varchar;
|
||||||
|
ERROR: cannot alter column type of typed table
|
||||||
|
CREATE TABLE stuff (id int);
|
||||||
|
ALTER TABLE persons INHERIT stuff;
|
||||||
|
ERROR: cannot change inheritance of typed table
|
||||||
CREATE TABLE personsx OF person_type (myname WITH OPTIONS NOT NULL); -- error
|
CREATE TABLE personsx OF person_type (myname WITH OPTIONS NOT NULL); -- error
|
||||||
ERROR: column "myname" does not exist
|
ERROR: column "myname" does not exist
|
||||||
CREATE TABLE persons2 OF person_type (
|
CREATE TABLE persons2 OF person_type (
|
||||||
|
@ -83,3 +89,4 @@ DETAIL: drop cascades to table persons
|
||||||
drop cascades to function get_all_persons()
|
drop cascades to function get_all_persons()
|
||||||
drop cascades to table persons2
|
drop cascades to table persons2
|
||||||
drop cascades to table persons3
|
drop cascades to table persons3
|
||||||
|
DROP TABLE stuff;
|
||||||
|
|
|
@ -13,9 +13,13 @@ $$;
|
||||||
|
|
||||||
SELECT * FROM get_all_persons();
|
SELECT * FROM get_all_persons();
|
||||||
|
|
||||||
|
-- certain ALTER TABLE operations on typed tables are not allowed
|
||||||
ALTER TABLE persons ADD COLUMN comment text;
|
ALTER TABLE persons ADD COLUMN comment text;
|
||||||
ALTER TABLE persons DROP COLUMN name;
|
ALTER TABLE persons DROP COLUMN name;
|
||||||
ALTER TABLE persons RENAME COLUMN id TO num;
|
ALTER TABLE persons RENAME COLUMN id TO num;
|
||||||
|
ALTER TABLE persons ALTER COLUMN name TYPE varchar;
|
||||||
|
CREATE TABLE stuff (id int);
|
||||||
|
ALTER TABLE persons INHERIT stuff;
|
||||||
|
|
||||||
CREATE TABLE personsx OF person_type (myname WITH OPTIONS NOT NULL); -- error
|
CREATE TABLE personsx OF person_type (myname WITH OPTIONS NOT NULL); -- error
|
||||||
|
|
||||||
|
@ -40,3 +44,5 @@ CREATE TABLE persons4 OF person_type (
|
||||||
|
|
||||||
DROP TYPE person_type RESTRICT;
|
DROP TYPE person_type RESTRICT;
|
||||||
DROP TYPE person_type CASCADE;
|
DROP TYPE person_type CASCADE;
|
||||||
|
|
||||||
|
DROP TABLE stuff;
|
||||||
|
|
Loading…
Reference in New Issue