blob: bf6e9e27e0a50762eb70dbffee2ca650d06cf589 [file] [log] [blame]
-- ALTER TABLE ... RENAME on corrupted relations
SET allow_system_table_mods = true;
-- missing entry
CREATE TABLE cor (a int, b float);
INSERT INTO cor SELECT i, i+1 FROM generate_series(1,100)i;
DELETE FROM pg_attribute WHERE attname='a' AND attrelid='cor'::regclass;
INSERT INTO pg_attribute SELECT distinct on(attrelid, attnum) * FROM gp_dist_random('pg_attribute') WHERE attname='a' AND attrelid='cor'::regclass;
ALTER TABLE cor RENAME TO oldcor;
DROP TABLE oldcor;
-- typname is out of sync
CREATE TABLE cor (a int, b float, c text);
UPDATE pg_type SET typname='newcor' WHERE typrelid='cor'::regclass;
ALTER TABLE cor RENAME TO newcor2;
ALTER TABLE newcor2 RENAME TO cor;
DROP TABLE cor;
RESET allow_system_table_mods;
-- MPP-20466 Dis-allow duplicate constraint names for same table
create table dupconstr (
i int,
j int constraint dup_constraint CHECK (j > 10))
distributed by (i);
-- should fail because of duplicate constraint name
alter table dupconstr add constraint dup_constraint unique (i);
alter table dupconstr add constraint dup_constraint primary key (i);
-- cleanup
drop table dupconstr;
--
-- Alter datatype of column with constraint should raise meaningful error
-- See github issue: https://github.com/greenplum-db/gpdb/issues/10561
--
create table contype (i int4 primary key, j int check (j < 100));
alter table contype alter i type numeric; --error
insert into contype values (1, 1), (2, 2), (3, 3);
-- after insert data, alter primary key/unique column's type will go through a special check logic
alter table contype alter i type numeric; --error
alter table contype alter j type numeric;
-- cleanup
drop table contype;
--
-- Test ALTER COLUMN TYPE after dropped column with text datatype (see MPP-19146)
--
create domain mytype as text;
create temp table at_foo (f1 text, f2 mytype, f3 text);
insert into at_foo values('aa','bb','cc');
drop domain mytype cascade;
alter table at_foo alter f1 TYPE varchar(10);
drop table at_foo;
create domain mytype as int;
create temp table at_foo (f1 text, f2 mytype, f3 text);
insert into at_foo values('aa',0,'cc');
drop domain mytype cascade;
alter table at_foo alter f1 TYPE varchar(10);
-- Verify that INSERT, UPDATE and DELETE work after dropping a column and
-- adding a constraint. There was a bug on that in ORCA, once upon a time
-- (MPP-20207)
CREATE TABLE altable(a int, b text, c int);
ALTER TABLE altable DROP COLUMN b;
ALTER TABLE altable ADD CONSTRAINT c_check CHECK (c > 0);
INSERT INTO altable(a, c) VALUES(0, -10);
SELECT * FROM altable ORDER BY 1;
INSERT INTO altable(a, c) VALUES(0, 10);
SELECT * FROM altable ORDER BY 1;
DELETE FROM altable WHERE c = -10;
SELECT * FROM altable ORDER BY 1;
DELETE FROM altable WHERE c = 10;
SELECT * FROM altable ORDER BY 1;
DELETE FROM altable WHERE c = 10;
SELECT * FROM altable ORDER BY 1;
INSERT INTO altable(a, c) VALUES(0, 10);
SELECT * FROM altable ORDER BY 1;
UPDATE altable SET c = -10;
SELECT * FROM altable ORDER BY 1;
UPDATE altable SET c = 1;
SELECT * FROM altable ORDER BY 1;
-- Verify that changing the datatype of a funnily-named column works.
-- (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;
-- Test the new "fast default" mechanism from PostgreSQL v11. It's important
-- that each segment gets the same attmissingval.
CREATE TABLE gp_test_fast_def(i int);
INSERT INTO gp_test_fast_def (i) SELECT g FROM generate_series(1, 10) g;
ALTER TABLE gp_test_fast_def ADD COLUMN ts timestamp DEFAULT now();
ANALYZE gp_test_fast_def;
SELECT COUNT (DISTINCT ts) FROM gp_test_fast_def;
-- Create view with JOIN clause, drop column, check select to view not causing segfault
CREATE TABLE dropped_col_t1(i1 int, i2 int);
CREATE TABLE dropped_col_t2(i1 int, i2 int);
CREATE VIEW dropped_col_v AS SELECT dropped_col_t1.i1 FROM dropped_col_t1 JOIN dropped_col_t2 ON dropped_col_t1.i1=dropped_col_t2.i1;
ALTER TABLE dropped_col_t1 DROP COLUMN i2;
SELECT * FROM dropped_col_v;
-- alter indexed column to the same type shouldn't change the index' relfilenode on QD and QEs.
-- helper utilities to check compare relfilenodes
drop table if exists relfilenodecheck;
create table relfilenodecheck(segid int, relname text, relfilenodebefore int, relfilenodeafter int, casename text);
prepare capturerelfilenodebefore as
insert into relfilenodecheck select -1 segid, relname, pg_relation_filenode(relname::text) as relfilenode, null::int, $1 as casename from pg_class where relname like $2
union select gp_segment_id segid, relname, pg_relation_filenode(relname::text) as relfilenode, null::int, $1 as casename from gp_dist_random('pg_class')
where relname like $2 order by segid;
prepare checkrelfilenodediff as
select a.segid, b.casename, b.relname, (relfilenodebefore != a.relfilenode) rewritten
from
(
select -1 segid, relname, pg_relation_filenode(relname::text) as relfilenode
from pg_class
where relname like $2
union
select gp_segment_id segid, relname, pg_relation_filenode(relname::text) as relfilenode
from gp_dist_random('pg_class')
where relname like $2 order by segid
)a, relfilenodecheck b
where b.casename like $1 and b.relname like $2 and a.segid = b.segid;
create table attype_indexed(a int, b int);
create index attype_indexed_i on attype_indexed(b);
insert into attype_indexed select i,i from generate_series(1, 100)i;
-- alter to same type.
-- check relfilenode before AT
execute capturerelfilenodebefore('alter column type same', 'attype_indexed_i');
alter table attype_indexed alter column b type int;
-- relfilenode stay same as before
execute checkrelfilenodediff('alter column type same', 'attype_indexed_i');
-- insert works fine
insert into attype_indexed select i,i from generate_series(1, 100)i;
select count(*) from attype_indexed;
-- alter to different type, relfilenode should change
execute capturerelfilenodebefore('alter column diff type', 'attype_indexed_i');
alter table attype_indexed alter column b type text;
execute checkrelfilenodediff('alter column diff type', 'attype_indexed_i');
--insert works fine
insert into attype_indexed select i, 'abc'::text from generate_series(1, 100) i;
select count(*) from attype_indexed;
-- alter column with exclusion constraint
create table attype_indexed_constr(
c circle,
dkey inet,
exclude using gist (dkey inet_ops with =, c with &&)
);
-- not change
execute capturerelfilenodebefore('alter column diff type', 'attype_indexed_constr_dkey_c_excl');
alter table attype_indexed_constr alter column c type circle;
execute checkrelfilenodediff('alter column diff type', 'attype_indexed_constr_dkey_c_excl');
drop table relfilenodecheck;
-- Test that we are able to attach a newly created partition table when it has foreign key reference.
CREATE TABLE issue_14279_fk_reference (col2 text unique not null);
INSERT INTO issue_14279_fk_reference VALUES ('stuff');
CREATE TABLE issue_14279_taptest_table (
col1 BIGINT,
col2 TEXT NOT NULL DEFAULT 'stuff', FOREIGN KEY (col2) REFERENCES issue_14279_fk_reference(col2))
PARTITION BY RANGE (col1);
CREATE TABLE issue_14279_taptest_table_p3000000000 (
LIKE issue_14279_taptest_table
INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
ALTER TABLE issue_14279_taptest_table ATTACH PARTITION issue_14279_taptest_table_p3000000000 FOR VALUES FROM (3000000000) TO (3000000100);
BEGIN;
CREATE TABLE issue_14279_taptest_table_p3000000100 (
LIKE issue_14279_taptest_table
INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
ALTER TABLE issue_14279_taptest_table ATTACH PARTITION issue_14279_taptest_table_p3000000100 FOR VALUES FROM (3000000100) TO (3000000200);
END;
INSERT INTO issue_14279_taptest_table SELECT generate_series(3000000000, 3000000001);
INSERT INTO issue_14279_taptest_table SELECT generate_series(3000000100, 3000000101);
-- The parent table shouldn't have anything.
SELECT * FROM ONLY issue_14279_taptest_table;
-- The newly attached table should have 2 rows.
SELECT * FROM issue_14279_taptest_table_p3000000000;
-- The newly attached table should have 2 rows.
SELECT * FROM issue_14279_taptest_table_p3000000100;
DROP TABLE issue_14279_taptest_table;
DROP TABLE issue_14279_fk_reference;