未验证 提交 d8a613b8 编写于 作者: Z ZhangJackey 提交者: GitHub

Parent partition and children partition table must have same columns

In the previous code, we can modify the parent partition's column
by ALTER TABLE ONLY, so the column of the parent partition
and children partition may be different.

In order to prohibit this situation, we check the DROP COLUMN/
ADD COLUMN/ALTER TYPE COLUMN statement to prohibit the
user only modify the column of parent partition or children partitions.

There was a discussion on gpdb-dev@:
https://groups.google.com/a/greenplum.org/forum/#!msg/gpdb-dev/0SzL_gSbqKo/d-2RpwKrFwAJ
上级 ae67ca0f
......@@ -4290,7 +4290,12 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
* recursing.
*/
ATExternalPartitionCheck(cmd->subtype, rel, recursing);
ATPartitionCheck(cmd->subtype, rel, false, recursing);
/*
* (!recurse) indicate that we can not only add column to root
* partition
*/
ATPartitionCheck(cmd->subtype, rel, !recurse /* rejectroot */, recursing);
/* Performs own recursion */
ATPrepAddColumn(wqueue, rel, recurse, recursing, cmd, lockmode);
/* Recursion occurs during execution phase */
......@@ -4376,7 +4381,12 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
ATPrepDropColumn(wqueue, rel, recurse, recursing, cmd, lockmode);
ATExternalPartitionCheck(cmd->subtype, rel, recursing);
ATPartitionCheck(cmd->subtype, rel, false, recursing);
/*
* (!recurse) indicate that we can not only drop column to root
* partition
*/
ATPartitionCheck(cmd->subtype, rel, !recurse /* rejectroot */, recursing);
/* Recursion occurs during execution phase */
pass = AT_PASS_DROP;
break;
......@@ -4470,7 +4480,12 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
ATSimplePermissions(rel,
ATT_TABLE | ATT_COMPOSITE_TYPE | ATT_FOREIGN_TABLE);
ATExternalPartitionCheck(cmd->subtype, rel, recursing);
ATPartitionCheck(cmd->subtype, rel, false, recursing);
/*
* (!recurse) indicate that we can not only alter type to root
* partition
*/
ATPartitionCheck(cmd->subtype, rel, !recurse /* rejectroot */, recursing);
/* Performs own recursion */
ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd, lockmode);
pass = AT_PASS_ALTER_TYPE;
......
......@@ -121,3 +121,138 @@ SELECT * FROM altable ORDER BY 1;
-- (There used to be a quoting bug in the internal query this issues.)
create table "foo'bar" (id int4, t text);
alter table "foo'bar" alter column t type integer using length(t);
--
-- ADD/DROP/ALTER COLUMN on root partition is approved.
--
-- Heap table
DROP TABLE IF EXISTS test_part_col;
NOTICE: table "test_part_col" does not exist, skipping
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
DISTRIBUTED BY(a)
PARTITION BY RANGE (b)
( START (1) END (2) EVERY (1),
DEFAULT PARTITION other_b);
NOTICE: CREATE TABLE will create partition "test_part_col_1_prt_other_b" for table "test_part_col"
NOTICE: CREATE TABLE will create partition "test_part_col_1_prt_2" for table "test_part_col"
ALTER TABLE ONLY test_part_col ADD COLUMN f int; --error
ERROR: can't add a column to "test_part_col"; it is a partitioned table or part thereof
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT; --error
ERROR: can't alter a column datatype of "test_part_col"; it is a partitioned table or part thereof
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f; --error
ERROR: can't drop a column from "test_part_col"; it is a partitioned table or part thereof
ALTER TABLE test_part_col DROP COLUMN f;
ALTER TABLE ONLY test_part_col_1_prt_other_b ADD COLUMN f int;
ERROR: can't add a column to "test_part_col_1_prt_other_b"; it is a partitioned table or part thereof
ALTER TABLE test_part_col_1_prt_other_b ADD COLUMN f int;
ERROR: can't add a column to "test_part_col_1_prt_other_b"; it is part of a partitioned table
HINT: You may be able to perform the operation on the partitioned table as a whole.
ALTER TABLE ONLY test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT; --error
ERROR: can't alter a column datatype of "test_part_col_1_prt_other_b"; it is a partitioned table or part thereof
ALTER TABLE test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT;
ERROR: can't alter a column datatype of "test_part_col_1_prt_other_b"; it is part of a partitioned table
HINT: You may be able to perform the operation on the partitioned table as a whole.
ALTER TABLE ONLY test_part_col_1_prt_other_b DROP COLUMN e; --error
ERROR: can't drop a column from "test_part_col_1_prt_other_b"; it is a partitioned table or part thereof
ALTER TABLE test_part_col_1_prt_other_b DROP COLUMN e;
ERROR: can't drop a column from "test_part_col_1_prt_other_b"; it is part of a partitioned table
HINT: You may be able to perform the operation on the partitioned table as a whole.
DROP TABLE test_part_col;
-- Non-partition heap table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int) DISTRIBUTED BY(a);
ALTER TABLE ONLY test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f;
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE test_part_col DROP COLUMN f;
DROP TABLE test_part_col;
-- AO table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
WITH (appendonly=true)
DISTRIBUTED BY(a)
PARTITION BY RANGE (b)
( START (1) END (2) EVERY (1),
DEFAULT PARTITION other_b);
NOTICE: CREATE TABLE will create partition "test_part_col_1_prt_other_b" for table "test_part_col"
NOTICE: CREATE TABLE will create partition "test_part_col_1_prt_2" for table "test_part_col"
ALTER TABLE ONLY test_part_col ADD COLUMN f int; --error
ERROR: can't add a column to "test_part_col"; it is a partitioned table or part thereof
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT; --error
ERROR: can't alter a column datatype of "test_part_col"; it is a partitioned table or part thereof
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f; --error
ERROR: can't drop a column from "test_part_col"; it is a partitioned table or part thereof
ALTER TABLE test_part_col DROP COLUMN f;
ALTER TABLE ONLY test_part_col_1_prt_other_b ADD COLUMN f int;
ERROR: can't add a column to "test_part_col_1_prt_other_b"; it is a partitioned table or part thereof
ALTER TABLE test_part_col_1_prt_other_b ADD COLUMN f int;
ERROR: can't add a column to "test_part_col_1_prt_other_b"; it is part of a partitioned table
HINT: You may be able to perform the operation on the partitioned table as a whole.
ALTER TABLE ONLY test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT; --error
ERROR: can't alter a column datatype of "test_part_col_1_prt_other_b"; it is a partitioned table or part thereof
ALTER TABLE test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT;
ERROR: can't alter a column datatype of "test_part_col_1_prt_other_b"; it is part of a partitioned table
HINT: You may be able to perform the operation on the partitioned table as a whole.
ALTER TABLE ONLY test_part_col_1_prt_other_b DROP COLUMN e; --error
ERROR: can't drop a column from "test_part_col_1_prt_other_b"; it is a partitioned table or part thereof
ALTER TABLE test_part_col_1_prt_other_b DROP COLUMN e;
ERROR: can't drop a column from "test_part_col_1_prt_other_b"; it is part of a partitioned table
HINT: You may be able to perform the operation on the partitioned table as a whole.
DROP TABLE test_part_col;
-- Non-partition AO table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
WITH (appendonly=true) DISTRIBUTED BY(a);
ALTER TABLE ONLY test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f;
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE test_part_col DROP COLUMN f;
DROP TABLE test_part_col;
-- AOCS table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
WITH (appendonly=true, orientation=column)
DISTRIBUTED BY(a)
PARTITION BY RANGE (b)
( START (1) END (2) EVERY (1),
DEFAULT PARTITION other_b);
NOTICE: CREATE TABLE will create partition "test_part_col_1_prt_other_b" for table "test_part_col"
NOTICE: CREATE TABLE will create partition "test_part_col_1_prt_2" for table "test_part_col"
ALTER TABLE ONLY test_part_col ADD COLUMN f int; --error
ERROR: can't add a column to "test_part_col"; it is a partitioned table or part thereof
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT; --error
ERROR: can't alter a column datatype of "test_part_col"; it is a partitioned table or part thereof
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f; --error
ERROR: can't drop a column from "test_part_col"; it is a partitioned table or part thereof
ALTER TABLE test_part_col DROP COLUMN f;
ALTER TABLE ONLY test_part_col_1_prt_other_b ADD COLUMN f int;
ERROR: can't add a column to "test_part_col_1_prt_other_b"; it is a partitioned table or part thereof
ALTER TABLE test_part_col_1_prt_other_b ADD COLUMN f int;
ERROR: can't add a column to "test_part_col_1_prt_other_b"; it is part of a partitioned table
HINT: You may be able to perform the operation on the partitioned table as a whole.
ALTER TABLE ONLY test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT; --error
ERROR: can't alter a column datatype of "test_part_col_1_prt_other_b"; it is a partitioned table or part thereof
ALTER TABLE test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT;
ERROR: can't alter a column datatype of "test_part_col_1_prt_other_b"; it is part of a partitioned table
HINT: You may be able to perform the operation on the partitioned table as a whole.
ALTER TABLE ONLY test_part_col_1_prt_other_b DROP COLUMN e; --error
ERROR: can't drop a column from "test_part_col_1_prt_other_b"; it is a partitioned table or part thereof
ALTER TABLE test_part_col_1_prt_other_b DROP COLUMN e;
ERROR: can't drop a column from "test_part_col_1_prt_other_b"; it is part of a partitioned table
HINT: You may be able to perform the operation on the partitioned table as a whole.
DROP TABLE test_part_col;
-- Non-partition AOCS table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
WITH (appendonly=true, orientation=column) DISTRIBUTED BY(a);
ALTER TABLE ONLY test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f;
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE test_part_col DROP COLUMN f;
DROP TABLE test_part_col;
......@@ -39,6 +39,7 @@ NOTICE: CREATE TABLE will create partition "part_1_prt_part_1" for table "part"
INSERT INTO part VALUES (1, 2, 3), (4, 5, 6);
ALTER TABLE part DROP COLUMN c;
ALTER TABLE ONLY part DROP COLUMN b; -- note the ONLY here!
ERROR: can't drop a column from "part"; it is a partitioned table or part thereof
-- DROP all the columns
CREATE TABLE no_cols_left (a int, b int, c int) DISTRIBUTED RANDOMLY;
INSERT INTO no_cols_left VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9);
......
......@@ -81,3 +81,131 @@ SELECT * FROM altable ORDER BY 1;
-- (There used to be a quoting bug in the internal query this issues.)
create table "foo'bar" (id int4, t text);
alter table "foo'bar" alter column t type integer using length(t);
--
-- ADD/DROP/ALTER COLUMN on root partition is approved.
--
-- Heap table
DROP TABLE IF EXISTS test_part_col;
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
DISTRIBUTED BY(a)
PARTITION BY RANGE (b)
( START (1) END (2) EVERY (1),
DEFAULT PARTITION other_b);
ALTER TABLE ONLY test_part_col ADD COLUMN f int; --error
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT; --error
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f; --error
ALTER TABLE test_part_col DROP COLUMN f;
ALTER TABLE ONLY test_part_col_1_prt_other_b ADD COLUMN f int;
ALTER TABLE test_part_col_1_prt_other_b ADD COLUMN f int;
ALTER TABLE ONLY test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT; --error
ALTER TABLE test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT;
ALTER TABLE ONLY test_part_col_1_prt_other_b DROP COLUMN e; --error
ALTER TABLE test_part_col_1_prt_other_b DROP COLUMN e;
DROP TABLE test_part_col;
-- Non-partition heap table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int) DISTRIBUTED BY(a);
ALTER TABLE ONLY test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f;
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE test_part_col DROP COLUMN f;
DROP TABLE test_part_col;
-- AO table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
WITH (appendonly=true)
DISTRIBUTED BY(a)
PARTITION BY RANGE (b)
( START (1) END (2) EVERY (1),
DEFAULT PARTITION other_b);
ALTER TABLE ONLY test_part_col ADD COLUMN f int; --error
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT; --error
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f; --error
ALTER TABLE test_part_col DROP COLUMN f;
ALTER TABLE ONLY test_part_col_1_prt_other_b ADD COLUMN f int;
ALTER TABLE test_part_col_1_prt_other_b ADD COLUMN f int;
ALTER TABLE ONLY test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT; --error
ALTER TABLE test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT;
ALTER TABLE ONLY test_part_col_1_prt_other_b DROP COLUMN e; --error
ALTER TABLE test_part_col_1_prt_other_b DROP COLUMN e;
DROP TABLE test_part_col;
-- Non-partition AO table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
WITH (appendonly=true) DISTRIBUTED BY(a);
ALTER TABLE ONLY test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f;
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE test_part_col DROP COLUMN f;
DROP TABLE test_part_col;
-- AOCS table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
WITH (appendonly=true, orientation=column)
DISTRIBUTED BY(a)
PARTITION BY RANGE (b)
( START (1) END (2) EVERY (1),
DEFAULT PARTITION other_b);
ALTER TABLE ONLY test_part_col ADD COLUMN f int; --error
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT; --error
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f; --error
ALTER TABLE test_part_col DROP COLUMN f;
ALTER TABLE ONLY test_part_col_1_prt_other_b ADD COLUMN f int;
ALTER TABLE test_part_col_1_prt_other_b ADD COLUMN f int;
ALTER TABLE ONLY test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT; --error
ALTER TABLE test_part_col_1_prt_other_b ALTER COLUMN e TYPE TEXT;
ALTER TABLE ONLY test_part_col_1_prt_other_b DROP COLUMN e; --error
ALTER TABLE test_part_col_1_prt_other_b DROP COLUMN e;
DROP TABLE test_part_col;
-- Non-partition AOCS table
CREATE TABLE test_part_col(a int, b int, c int, d int, e int)
WITH (appendonly=true, orientation=column) DISTRIBUTED BY(a);
ALTER TABLE ONLY test_part_col ADD COLUMN f int;
ALTER TABLE ONLY test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE ONLY test_part_col DROP COLUMN f;
ALTER TABLE test_part_col ADD COLUMN f int;
ALTER TABLE test_part_col ALTER COLUMN f TYPE TEXT;
ALTER TABLE test_part_col DROP COLUMN f;
DROP TABLE test_part_col;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册