blob: 6f8ba2cd5866bceefb13f5d6f5e76d469f1bd846 [file] [log] [blame]
set enable_partition_rules = false;
set gp_enable_hash_partitioned_tables = true;
-- missing subpartition by
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by hash (b)
(
partition aa (subpartition cc, subpartition dd),
partition bb (subpartition cc, subpartition dd)
);
-- missing subpartition spec
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by hash (b)
subpartition by hash (d)
(
partition aa ,
partition bb
);
-- subpart spec conflict
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by hash (b)
subpartition by hash (d) subpartition template (subpartition jjj)
(
partition aa (subpartition cc, subpartition dd),
partition bb (subpartition cc, subpartition dd)
);
-- missing subpartition by
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by hash (b)
subpartition by hash (d)
(
partition aa (subpartition cc, subpartition dd (subpartition iii)),
partition bb (subpartition cc, subpartition dd)
);
-- Test column lookup works
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by hash(doesnotexist)
partitions 3;
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by hash(b)
partitions 3
subpartition by list(alsodoesntexist)
subpartition template (
subpartition aa values(1)
);
-- should work
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by hash (b)
subpartition by hash (d)
(
partition aa (subpartition cc, subpartition dd),
partition bb (subpartition cc, subpartition dd)
);
drop table ggg cascade;
-- disable hash partitions
set gp_enable_hash_partitioned_tables = false;
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by hash (b)
subpartition by hash (d)
(
partition aa (subpartition cc, subpartition dd),
partition bb (subpartition cc, subpartition dd)
);
drop table ggg cascade;
set gp_enable_hash_partitioned_tables = true;
-- should work
create table ggg (a char(1), b char(2), d char(3), e int)
distributed by (a)
partition by hash (b)
subpartition by hash (d)
subpartition template (
subpartition cc,
subpartition dd
),
subpartition by hash (e)
subpartition template (
subpartition ee,
subpartition ff
)
(
partition aa,
partition bb
);
drop table ggg cascade;
-- should work
create table ggg (a char(1), b char(2), d char(3), e int)
distributed by (a)
partition by hash (b)
subpartition by hash (d),
subpartition by hash (e)
subpartition template (
subpartition ee,
subpartition ff
)
(
partition aa (subpartition cc, subpartition dd),
partition bb (subpartition cc, subpartition dd)
);
drop table ggg cascade;
-- doesn't work because cannot have nested declaration in template
create table ggg (a char(1), b char(2), d char(3), e int)
distributed by (a)
partition by hash (b)
subpartition by hash (d)
subpartition template (
subpartition cc (subpartition ee, subpartition ff),
subpartition dd (subpartition ee, subpartition ff)
),
subpartition by hash (e)
(
partition aa,
partition bb
);
drop table ggg cascade;
--ERROR: Missing boundary specification in partition 'aa' of type LIST
create table fff (a char(1), b char(2), d char(3)) distributed by
(a) partition by list (b) (partition aa );
-- ERROR: Invalid use of RANGE boundary specification in partition
-- number 1 of type LIST
create table fff (a char(1), b char(2), d char(3)) distributed by (a)
partition by list (b) (start ('a') );
-- should work
create table fff (a char(1), b char(2), d char(3)) distributed by (a)
partition by list (b) (partition aa values ('2'));
drop table fff cascade;
-- Invalid use of RANGE boundary specification in partition "cc" of
-- type HASH (at depth 2)
create table ggg (a char(1), b char(2), d char(3), e int) distributed by (a)
partition by hash (b) subpartition by hash (d),
subpartition by hash (e)
subpartition template ( subpartition ee, subpartition ff ) (
partition aa (subpartition cc, subpartition dd), partition bb
(subpartition cc start ('a') , subpartition dd) );
-- this is subtly wrong -- it defines 4 partitions
-- the problem is the comma before "end", which causes us to
-- generate 2 anonymous partitions.
-- This is an error:
-- ERROR: invalid use of mixed named and unnamed RANGE boundary specifications
create table ggg (a char(1), b int, d char(3))
distributed by (a)
partition by range (b)
(
partition aa start ('2007'), end ('2008'),
partition bb start ('2008'), end ('2009')
);
create table ggg (a char(1), b int)
distributed by (a)
partition by range(b)
(
partition aa start ('2007'), end ('2008')
);
drop table ggg cascade;
create table ggg (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition aa start (date '2007-01-01') end (date '2008-01-01'),
partition bb start (date '2008-01-01') end (date '2009-01-01')
);
drop table ggg cascade;
-- don't allow nonconstant expressions, even simple ones...
create table ggg (a char(1), b numeric, d numeric)
distributed by (a)
partition by range (b,d)
(
partition aa start (2007,1) end (2008,2+2),
partition bb start (2008,2) end (2009,3)
);
-- too many columns for RANGE partition
create table ggg (a char(1), b numeric, d numeric)
distributed by (a)
partition by range (b,d)
(
partition aa start (2007,1) end (2008,2),
partition bb start (2008,2) end (2009,3)
);
drop table ggg cascade;
-- demo starts here
-- nested subpartitions
create table ggg
(a char(1), b date,
d char(3), e numeric,
f numeric, g numeric,
h numeric)
distributed by (a)
partition by hash(b)
partitions 2
subpartition by hash(d)
subpartitions 2,
subpartition by hash(e) subpartitions 2,
subpartition by hash(f) subpartitions 2,
subpartition by hash(g) subpartitions 2,
subpartition by hash(h) subpartitions 2;
drop table ggg cascade;
-- named, inline subpartitions
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by hash (b)
subpartition by hash (d)
(
partition aa (subpartition cc, subpartition dd),
partition bb (subpartition cc, subpartition dd)
);
drop table ggg cascade;
-- subpartitions with templates
create table ggg (a char(1), b char(2), d char(3), e numeric)
distributed by (a)
partition by hash (b)
subpartition by hash (d)
subpartition template (
subpartition cc,
subpartition dd
),
subpartition by hash (e)
subpartition template (
subpartition ee,
subpartition ff
)
(
partition aa,
partition bb
);
drop table ggg cascade;
-- mixed inline subpartition declarations with templates
create table ggg (a char(1), b char(2), d char(3), e numeric)
distributed by (a)
partition by hash (b)
subpartition by hash (d) ,
subpartition by hash (e)
subpartition template (
subpartition ee,
subpartition ff
)
(
partition aa (subpartition cc, subpartition dd),
partition bb (subpartition cc, subpartition dd)
);
drop table ggg cascade;
-- basic list partition
create table ggg (a char(1), b char(2), d char(3))
distributed by (a)
partition by LIST (b)
(
partition aa values ('a', 'b', 'c', 'd'),
partition bb values ('e', 'f', 'g')
);
insert into ggg values ('x', 'a');
insert into ggg values ('x', 'b');
insert into ggg values ('x', 'c');
insert into ggg values ('x', 'd');
insert into ggg values ('x', 'e');
insert into ggg values ('x', 'f');
insert into ggg values ('x', 'g');
insert into ggg values ('x', 'a');
insert into ggg values ('x', 'b');
insert into ggg values ('x', 'c');
insert into ggg values ('x', 'd');
insert into ggg values ('x', 'e');
insert into ggg values ('x', 'f');
insert into ggg values ('x', 'g');
select * from ggg order by 1, 2;
-- ok
select * from ggg_1_prt_aa order by 1, 2;
select * from ggg_1_prt_bb order by 1, 2;
drop table ggg cascade;
-- documentation example - partition by list and range
CREATE TABLE rank (id int, rank int, year date, gender
char(1)) DISTRIBUTED BY (id, gender, year)
partition by list (gender)
subpartition by range (year)
subpartition template (
start (date '2001-01-01'),
start (date '2002-01-01'),
start (date '2003-01-01'),
start (date '2004-01-01'),
start (date '2005-01-01')
)
(
partition boys values ('M'),
partition girls values ('F')
);
insert into rank values (1, 1, date '2001-01-15', 'M');
insert into rank values (2, 1, date '2002-02-15', 'M');
insert into rank values (3, 1, date '2003-03-15', 'M');
insert into rank values (4, 1, date '2004-04-15', 'M');
insert into rank values (5, 1, date '2005-05-15', 'M');
insert into rank values (6, 1, date '2001-01-15', 'F');
insert into rank values (7, 1, date '2002-02-15', 'F');
insert into rank values (8, 1, date '2003-03-15', 'F');
insert into rank values (9, 1, date '2004-04-15', 'F');
insert into rank values (10, 1, date '2005-05-15', 'F');
select * from rank order by 1, 2, 3, 4;
select * from rank_1_prt_boys order by 1, 2, 3, 4;
select * from rank_1_prt_girls order by 1, 2, 3, 4;
select * from rank_1_prt_girls_2_prt_1 order by 1, 2, 3, 4;
select * from rank_1_prt_girls_2_prt_2 order by 1, 2, 3, 4;
drop table rank cascade;
-- range list hash combo
create table ggg (a char(1), b date, d char(3), e numeric)
distributed by (a)
partition by range (b)
subpartition by list(d),
subpartition by hash(e) subpartitions 3
(
partition aa
start (date '2007-01-01')
end (date '2008-01-01')
(subpartition dd values ('1', '2', '3'),
subpartition ee values ('4', '5', '6')),
partition bb
start (date '2008-01-01')
end (date '2009-01-01')
(subpartition dd values ('1', '2', '3'),
subpartition ee values ('4', '5', '6'))
);
drop table ggg cascade;
-- demo ends here
-- LIST validation
-- duplicate partition name
CREATE TABLE rank (id int, rank int, year date, gender
char(1)) DISTRIBUTED BY (id, gender, year)
partition by list (gender)
(
partition boys values ('M'),
partition girls values ('a'),
partition girls values ('b'),
partition girls values ('c'),
partition girls values ('d'),
partition girls values ('e'),
partition bob values ('M')
);
-- duplicate values
CREATE TABLE rank (id int, rank int, year date, gender
char(1)) DISTRIBUTED BY (id, gender, year)
partition by list (rank,gender)
(
values ((1, 'M')),
values ((2, 'M')),
values ((3, 'M')),
values ((1, 'F')),
partition ff values ((4, 'M')),
partition bb values ((1, 'M'))
);
-- RANGE validation
-- legal if end of aa not inclusive
create table ggg (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition aa start (date '2007-01-01') end (date '2008-01-01'),
partition bb start (date '2008-01-01') end (date '2009-01-01')
every (interval '10 days'));
drop table ggg cascade;
-- bad - legal if end of aa not inclusive
create table ggg (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition aa start (date '2007-01-01') end (date '2008-01-01') inclusive,
partition bb start (date '2008-01-01') end (date '2009-01-01')
every (interval '10 days'));
drop table ggg cascade;
-- legal because start of bb not inclusive
create table ggg (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition aa start (date '2007-01-01') end (date '2008-01-01') inclusive,
partition bb start (date '2008-01-01') exclusive end (date '2009-01-01')
every (interval '10 days'));
drop table ggg cascade;
-- legal if end of aa not inclusive
create table ggg (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition bb start (date '2008-01-01') end (date '2009-01-01'),
partition aa start (date '2007-01-01') end (date '2008-01-01')
);
drop table ggg cascade;
-- bad - legal if end of aa not inclusive
create table ggg (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition bb start (date '2008-01-01') end (date '2009-01-01'),
partition aa start (date '2007-01-01') end (date '2008-01-01') inclusive
);
drop table ggg cascade;
-- legal because start of bb not inclusive
create table ggg (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition bb start (date '2008-01-01') exclusive end (date '2009-01-01'),
partition aa start (date '2007-01-01') end (date '2008-01-01') inclusive
);
drop table ggg cascade;
-- validate aa - start greater than end
create table ggg (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition bb start (date '2008-01-01') end (date '2009-01-01'),
partition aa start (date '2007-01-01') end (date '2006-01-01')
);
drop table ggg cascade;
-- formerly we could not set end of first partition because next is before
-- but we can sort them now so this is legal.
create table ggg (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition bb start (date '2008-01-01') ,
partition aa start (date '2007-01-01')
);
drop table ggg cascade;
-- test cross type coercion
-- int -> char(N)
create table ggg (i int, a char(1))
distributed by (i)
partition by list(a)
(partition aa values(1, 2));
drop table ggg cascade;
-- int -> numeric
create table ggg (i int, n numeric(20, 2))
distributed by (i)
partition by list(n)
(partition aa values(1.22, 4.1));
drop table ggg cascade;
-- EVERY
-- the documentation example, rewritten with EVERY in a template
CREATE TABLE rank (id int,
rank int, year date, gender char(1))
DISTRIBUTED BY (id, gender, year)
partition by list (gender)
subpartition by range (year)
subpartition template (
start (date '2001-01-01')
end (date '2006-01-01') every (interval '1 year')) (
partition boys values ('M'),
partition girls values ('F')
);
insert into rank values (1, 1, date '2001-01-15', 'M');
insert into rank values (2, 1, date '2002-02-15', 'M');
insert into rank values (3, 1, date '2003-03-15', 'M');
insert into rank values (4, 1, date '2004-04-15', 'M');
insert into rank values (5, 1, date '2005-05-15', 'M');
insert into rank values (6, 1, date '2001-01-15', 'F');
insert into rank values (7, 1, date '2002-02-15', 'F');
insert into rank values (8, 1, date '2003-03-15', 'F');
insert into rank values (9, 1, date '2004-04-15', 'F');
insert into rank values (10, 1, date '2005-05-15', 'F');
select * from rank order by 1, 2, 3, 4;
select * from rank_1_prt_boys order by 1, 2, 3, 4;
select * from rank_1_prt_girls order by 1, 2, 3, 4;
select * from rank_1_prt_girls_2_prt_1 order by 1, 2, 3, 4;
select * from rank_1_prt_girls_2_prt_2 order by 1, 2, 3, 4;
drop table rank cascade;
-- integer ranges work too
create table ggg (id integer, a integer)
distributed by (id)
partition by range (a)
(start (1) end (10) every (1));
insert into ggg values (1, 1);
insert into ggg values (2, 2);
insert into ggg values (3, 3);
insert into ggg values (4, 4);
insert into ggg values (5, 5);
insert into ggg values (6, 6);
insert into ggg values (7, 7);
insert into ggg values (8, 8);
insert into ggg values (9, 9);
insert into ggg values (10, 10);
select * from ggg order by 1, 2;
select * from ggg_1_prt_1 order by 1, 2;
select * from ggg_1_prt_2 order by 1, 2;
select * from ggg_1_prt_3 order by 1, 2;
select * from ggg_1_prt_4 order by 1, 2;
drop table ggg cascade;
-- hash tests
create table ggg (a char(1), b varchar(2), d varchar(2))
distributed by (a)
partition by hash(b)
partitions 3
(partition a, partition b, partition c);
insert into ggg values (1,1,1);
insert into ggg values (2,2,1);
insert into ggg values (1,3,1);
insert into ggg values (2,2,3);
insert into ggg values (1,4,5);
insert into ggg values (2,2,4);
insert into ggg values (1,5,6);
insert into ggg values (2,7,3);
insert into ggg values (1,'a','b');
insert into ggg values (2,'c','c');
select * from ggg order by 1, 2, 3;
--select * from ggg_1_prt_a order by 1, 2, 3;
--select * from ggg_1_prt_b order by 1, 2, 3;
--select * from ggg_1_prt_c order by 1, 2, 3;
drop table ggg cascade;
-- use multiple cols
create table ggg (a char(1), b varchar(2), d varchar(2))
distributed by (a)
partition by hash(b,d)
partitions 3
(partition a, partition b, partition c);
insert into ggg values (1,1,1);
insert into ggg values (2,2,1);
insert into ggg values (1,3,1);
insert into ggg values (2,2,3);
insert into ggg values (1,4,5);
insert into ggg values (2,2,4);
insert into ggg values (1,5,6);
insert into ggg values (2,7,3);
insert into ggg values (1,'a','b');
insert into ggg values (2,'c','c');
select * from ggg order by 1, 2, 3;
--select * from ggg_1_prt_a order by 1, 2, 3;
--select * from ggg_1_prt_b order by 1, 2, 3;
--select * from ggg_1_prt_c order by 1, 2, 3;
drop table ggg cascade;
-- use multiple cols of different types and without a partition spec
create table ggg (a char(1), b varchar(2), d integer, e date)
distributed by (a)
partition by hash(b,d,e)
partitions 3;
insert into ggg values (1,1,1,date '2001-01-15');
insert into ggg values (2,2,1,date '2001-01-15');
insert into ggg values (1,3,1,date '2001-01-15');
insert into ggg values (2,2,3,date '2001-01-15');
insert into ggg values (1,4,5,date '2001-01-15');
insert into ggg values (2,2,4,date '2001-01-15');
insert into ggg values (1,5,6,date '2001-01-15');
insert into ggg values (2,7,3,date '2001-01-15');
insert into ggg values (1,'a',33,date '2001-01-15');
insert into ggg values (2,'c',44,date '2001-01-15');
select * from ggg order by 1, 2, 3, 4;
--select * from ggg_1_prt_1 order by 1, 2, 3, 4;
--select * from ggg_1_prt_2 order by 1, 2, 3, 4;
--select * from ggg_1_prt_3 order by 1, 2, 3, 4;
drop table ggg cascade;
-- append only tests
create table foz (i int, d date) with (appendonly = true) distributed by (i)
partition by range (d) (start (date '2001-01-01') end (date '2005-01-01')
every(interval '1 year'));
insert into foz select i, '2001-01-01'::date + ('1 day'::interval * i) from
generate_series(1, 1000) i;
select count(*) from foz;
select count(*) from foz_1_prt_1;
select min(d), max(d) from foz;
select min(d), max(d) from foz_1_prt_1;
select min(d), max(d) from foz_1_prt_2;
select min(d), max(d) from foz_1_prt_3;
select min(d), max(d) from foz_1_prt_4;
drop table foz cascade;
-- copy test
create table foz (i int, d date) distributed by (i)
partition by range (d) (start (date '2001-01-01') end (date '2005-01-01')
every(interval '1 year'));
COPY foz FROM stdin DELIMITER '|';
1|2001-01-2
2|2001-10-10
3|2002-10-30
4|2003-01-01
5|2004-05-05
\.
select * from foz_1_prt_1;
select * from foz_1_prt_2;
select * from foz_1_prt_3;
select * from foz_1_prt_4;
-- Check behaviour of key for which there is no partition
COPY foz FROM stdin DELIMITER '|';
6|2010-01-01
\.
drop table foz cascade;
-- Same test with append only
create table foz (i int, d date) with (appendonly = true) distributed by (i)
partition by range (d) (start (date '2001-01-01') end (date '2005-01-01')
every(interval '1 year'));
COPY foz FROM stdin DELIMITER '|';
1|2001-01-2
2|2001-10-10
3|2002-10-30
4|2003-01-01
5|2004-05-05
\.
select * from foz_1_prt_1;
select * from foz_1_prt_2;
select * from foz_1_prt_3;
select * from foz_1_prt_4;
-- Check behaviour of key for which there is no partition
COPY foz FROM stdin DELIMITER '|';
6|2010-01-01
\.
drop table foz cascade;
-- complain if create table as select (CTAS)
CREATE TABLE rank1 (id int,
rank int, year date, gender char(1));
create table rank2 as select * from rank1
DISTRIBUTED BY (id, gender, year)
partition by list (gender)
subpartition by range (year)
subpartition template (
start (date '2001-01-01')
end (date '2006-01-01') every (interval '1 year')) (
partition boys values ('M'),
partition girls values ('F')
);
-- like is ok
create table rank2 (like rank1)
DISTRIBUTED BY (id, gender, year)
partition by list (gender)
subpartition by range (year)
subpartition template (
start (date '2001-01-01')
end (date '2006-01-01') every (interval '1 year')) (
partition boys values ('M'),
partition girls values ('F')
);
drop table rank1 cascade;
drop table rank2 cascade;
-- alter table testing
create table hhh (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition aa start (date '2007-01-01') end (date '2008-01-01')
with (appendonly=true),
partition bb start (date '2008-01-01') end (date '2009-01-01')
with (appendonly=false)
);
-- already exists
alter table hhh add partition aa;
-- no partition spec
alter table hhh add partition cc;
-- overlaps
alter table hhh add partition cc start ('2008-01-01') end ('2010-01-01');
alter table hhh add partition cc end ('2008-01-01');
-- reversed (start > end)
alter table hhh add partition cc start ('2010-01-01') end ('2009-01-01');
-- works
--alter table hhh add partition cc start ('2009-01-01') end ('2010-01-01');
alter table hhh add partition cc end ('2010-01-01');
-- works - anonymous partition MPP-3350
alter table hhh add partition end ('2010-02-01');
-- MPP-3607 - ADD PARTITION with open intervals
create table no_end1 (aa int, bb int) partition by range (bb)
(partition foo start(3));
-- fail overlap
alter table no_end1 add partition baz end (4);
-- fail overlap (because prior partition has no end)
alter table no_end1 add partition baz start (5);
-- ok (terminates on foo start)
alter table no_end1 add partition baz start (2);
-- ok (because ends before baz start)
alter table no_end1 add partition baz2 end (1);
create table no_start1 (aa int, bb int) partition by range (bb)
(partition foo end(3));
-- fail overlap (because next partition has no start)
alter table no_start1 add partition baz start (2);
-- fail overlap (because next partition has no start)
alter table no_start1 add partition baz end (1);
-- ok (starts on foo end)
alter table no_start1 add partition baz end (4);
-- ok (because starts after baz end)
alter table no_start1 add partition baz2 start (5);
select tablename, partitionlevel, parentpartitiontablename,
partitionname, partitionrank, partitionboundary from pg_partitions
where tablename = 'no_start1' or tablename = 'no_end1'
order by tablename, partitionrank;
drop table no_end1;
drop table no_start1;
-- hash partitions cannot have default partitions
create table jjj (aa int, bb int)
partition by hash(bb)
(partition j1, partition j2);
alter table jjj add default partition;
drop table jjj cascade;
-- default partitions cannot have boundary specifications
create table jjj (aa int, bb date)
partition by range(bb)
(partition j1 end (date '2008-01-01'),
partition j2 end (date '2009-01-01'));
-- must have a name
alter table jjj add default partition;
alter table jjj add default partition for (rank(1));
-- cannot have boundary spec
alter table jjj add default partition j3 end (date '2010-01-01');
drop table jjj cascade;
-- only one default partition
create table jjj (aa int, bb date)
partition by range(bb)
(partition j1 end (date '2008-01-01'),
partition j2 end (date '2009-01-01'),
default partition j3);
alter table jjj add default partition j3 ;
alter table jjj add default partition j4 ;
-- cannot add if have default, must split
alter table jjj add partition j5 end (date '2010-01-01');
drop table jjj cascade;
alter table hhh alter partition cc set tablespace foo_p;
alter table hhh alter partition aa set tablespace foo_p;
alter table hhh coalesce partition cc;
alter table hhh coalesce partition aa;
alter table hhh drop partition cc;
alter table hhh drop partition cc cascade;
alter table hhh drop partition cc restrict;
alter table hhh drop partition if exists cc;
-- fail (mpp-3265)
alter table hhh drop partition for (rank(0));
alter table hhh drop partition for (rank(-55));
alter table hhh drop partition for ('2001-01-01');
create table hhh_r1 (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition aa start (date '2007-01-01') end (date '2008-01-01')
every (interval '1 month')
);
create table hhh_l1 (a char(1), b date, d char(3))
distributed by (a)
partition by list (b)
(
partition aa values ('2007-01-01'),
partition bb values ('2008-01-01'),
partition cc values ('2009-01-01')
);
-- must have name or value for list partition
alter table hhh_l1 drop partition;
alter table hhh_l1 drop partition aa;
alter table hhh_l1 drop partition for ('2008-01-01');
-- if not specified, drop first range partition...
alter table hhh_r1 drop partition for ('2007-04-01');
alter table hhh_r1 drop partition;
alter table hhh_r1 drop partition;
alter table hhh_r1 drop partition;
alter table hhh_r1 drop partition;
alter table hhh_r1 drop partition;
-- more add partition tests
-- start before first partition (fail because start equal end)
alter table hhh_r1 add partition zaa start ('2007-07-01');
-- start before first partition (ok)
alter table hhh_r1 add partition zaa start ('2007-06-01');
-- start > last (fail because start equal end)
alter table hhh_r1 add partition bb start ('2008-01-01') end ('2008-01-01') ;
-- start > last (ok)
alter table hhh_r1 add partition bb start ('2008-01-01')
end ('2008-02-01') inclusive;
-- start > last (fail because start == last end inclusive)
alter table hhh_r1 add partition cc start ('2008-02-01') end ('2008-03-01') ;
-- start > last (ok [and leave a gap])
alter table hhh_r1 add partition cc start ('2008-04-01') end ('2008-05-01') ;
-- overlap (fail)
alter table hhh_r1 add partition dd start ('2008-01-01') end ('2008-05-01') ;
-- new partition in "gap" (ok)
alter table hhh_r1 add partition dd start ('2008-03-01') end ('2008-04-01') ;
-- overlap all partitions (fail)
alter table hhh_r1 add partition ee start ('2006-01-01') end ('2009-01-01') ;
-- start before first partition (fail because end in "gap" [and overlaps])
alter table hhh_r1 add partition yaa start ('2007-05-01') end ('2007-07-01');
-- start before first partition (fail )
alter table hhh_r1 add partition yaa start ('2007-05-01')
end ('2007-10-01') inclusive;
-- start before first partition (fail because end overlaps)
alter table hhh_r1 add partition yaa start ('2007-05-01')
end ('2007-10-01') exclusive;
drop table hhh_r1 cascade;
drop table hhh_l1 cascade;
-- the documentation example, rewritten with EVERY in a template
-- and also with a default partition
CREATE TABLE rank (id int,
rank int, year date, gender char(1))
DISTRIBUTED BY (id, gender, year)
partition by list (gender)
subpartition by range (year)
subpartition template (
start (date '2001-01-01')
end (date '2006-01-01') every (interval '1 year')) (
partition boys values ('M'),
partition girls values ('F'),
default partition neuter
);
insert into rank values (1, 1, date '2001-01-15', 'M');
insert into rank values (2, 1, date '2002-02-15', 'M');
insert into rank values (3, 1, date '2003-03-15', 'M');
insert into rank values (4, 1, date '2004-04-15', 'M');
insert into rank values (5, 1, date '2005-05-15', 'M');
insert into rank values (6, 1, date '2001-01-15', 'F');
insert into rank values (7, 1, date '2002-02-15', 'F');
insert into rank values (8, 1, date '2003-03-15', 'F');
insert into rank values (9, 1, date '2004-04-15', 'F');
insert into rank values (10, 1, date '2005-05-15', 'F');
select * from rank ;
alter table rank DROP partition boys restrict;
select * from rank ;
-- MPP-3722: complain if for(value) matches the default partition
alter table rank truncate partition for('N');
alter table rank DROP partition for('N');
alter table rank DROP partition if exists for('N');
alter table rank DROP default partition if exists ;
-- can't drop the final partition - must drop the table
alter table rank DROP partition girls;
-- MPP-4011: make FOR(value) work
alter table rank alter partition for ('F') add default partition def1;
alter table rank alter partition for ('F')
truncate partition for ('2010-10-10');
alter table rank truncate partition for ('F');
drop table rank cascade;
alter table hhh exchange partition cc with table nosuchtable with validation;
alter table hhh exchange partition cc with table nosuchtable without validation;
alter table hhh exchange partition aa with table nosuchtable with validation;
alter table hhh exchange partition aa with table nosuchtable without validation;
alter table hhh merge partition cc, partition dd;
alter table hhh merge partition cc, partition dd into partition ee;
alter table hhh merge partition aa, partition dd into partition ee;
alter table hhh modify partition cc add values ('a');
alter table hhh modify partition cc drop values ('a');
alter table hhh modify partition aa add values ('a');
alter table hhh modify partition aa drop values ('a');
create table mmm_r1 (a char(1), b date, d char(3))
distributed by (a)
partition by range (b)
(
partition aa start (date '2007-01-01') end (date '2008-01-01')
every (interval '1 month')
);
create table mmm_l1 (a char(1), b char(1), d char(3))
distributed by (a)
partition by list (b)
(
partition aa values ('a', 'b', 'c'),
partition bb values ('d', 'e', 'f'),
partition cc values ('g', 'h', 'i')
);
alter table mmm_r1 drop partition for ('2007-03-01');
-- ok
alter table mmm_r1 add partition bb START ('2007-03-03') END ('2007-03-20');
-- fail
alter table mmm_r1 modify partition for (rank(-55)) start ('2007-03-02');
alter table mmm_r1 modify partition for ('2001-01-01') start ('2007-03-02');
alter table mmm_r1 modify partition bb start ('2006-03-02');
alter table mmm_r1 modify partition bb start ('2011-03-02');
alter table mmm_r1 modify partition bb end ('2006-03-02');
alter table mmm_r1 modify partition bb end ('2011-03-02');
alter table mmm_r1 modify partition bb add values ('2011-03-02');
alter table mmm_r1 modify partition bb drop values ('2011-03-02');
--ok
alter table mmm_r1 modify partition bb START ('2007-03-02') END ('2007-03-22');
alter table mmm_r1 modify partition bb START ('2007-03-01') END ('2007-03-31');
alter table mmm_r1 modify partition bb START ('2007-03-02') END ('2007-03-22');
-- with default
alter table mmm_r1 add default partition def1;
-- now fail
alter table mmm_r1 modify partition bb START ('2007-03-01') END ('2007-03-31');
-- still ok to reduce range
alter table mmm_r1 modify partition bb START ('2007-03-09') END ('2007-03-10');
-- fail
alter table mmm_l1 modify partition for (rank(1)) drop values ('k');
alter table mmm_l1 modify partition for ('j') drop values ('k');
alter table mmm_l1 modify partition for ('a') drop values ('k');
alter table mmm_l1 modify partition for ('a') drop values ('e');
alter table mmm_l1 modify partition for ('a') add values ('e');
alter table mmm_l1 modify partition for ('a') START ('2007-03-09') ;
--ok
alter table mmm_l1 modify partition for ('a') drop values ('b');
alter table mmm_l1 modify partition for ('a') add values ('z');
-- with default
alter table mmm_l1 add default partition def1;
-- ok
alter table mmm_l1 modify partition for ('a') drop values ('c');
-- now fail
alter table mmm_l1 modify partition for ('a') add values ('y');
-- XXX XXX: add some data
drop table mmm_r1 cascade;
drop table mmm_l1 cascade;
alter table hhh rename partition cc to aa;
alter table hhh rename partition aa to aa;
alter table hhh rename partition aa to "funky fresh";
alter table hhh rename partition "funky fresh" to aa;
-- use FOR PARTITION VALUE (with implicate date conversion)
alter table hhh rename partition for ('2007-01-01') to "funky fresh";
alter table hhh rename partition for ('2007-01-01') to aa;
alter table hhh set subpartition template ();
alter table hhh split partition cc at ('a');
alter table hhh split partition cc at ('a') into (partition gg, partition hh);
alter table hhh split partition aa at ('a');
alter table hhh truncate partition cc;
alter table hhh truncate partition aa;
insert into hhh values('a', date '2007-01-02', 'b');
insert into hhh values('a', date '2007-02-01', 'b');
insert into hhh values('a', date '2007-03-01', 'b');
insert into hhh values('a', date '2007-04-01', 'b');
insert into hhh values('a', date '2007-05-01', 'b');
insert into hhh values('a', date '2007-06-01', 'b');
insert into hhh values('a', date '2007-07-01', 'b');
insert into hhh values('a', date '2007-08-01', 'b');
insert into hhh values('a', date '2007-09-01', 'b');
insert into hhh values('a', date '2007-10-01', 'b');
insert into hhh values('a', date '2007-11-01', 'b');
insert into hhh values('a', date '2007-12-01', 'b');
insert into hhh values('a', date '2008-01-02', 'b');
insert into hhh values('a', date '2008-02-01', 'b');
insert into hhh values('a', date '2008-03-01', 'b');
insert into hhh values('a', date '2008-04-01', 'b');
insert into hhh values('a', date '2008-05-01', 'b');
insert into hhh values('a', date '2008-06-01', 'b');
insert into hhh values('a', date '2008-07-01', 'b');
insert into hhh values('a', date '2008-08-01', 'b');
insert into hhh values('a', date '2008-09-01', 'b');
insert into hhh values('a', date '2008-10-01', 'b');
insert into hhh values('a', date '2008-11-01', 'b');
insert into hhh values('a', date '2008-12-01', 'b');
select * from hhh;
alter table hhh truncate partition aa;
select * from hhh;
alter table hhh truncate partition bb;
select * from hhh;
insert into hhh values('a', date '2007-01-02', 'b');
insert into hhh values('a', date '2007-02-01', 'b');
insert into hhh values('a', date '2007-03-01', 'b');
insert into hhh values('a', date '2007-04-01', 'b');
insert into hhh values('a', date '2007-05-01', 'b');
insert into hhh values('a', date '2007-06-01', 'b');
insert into hhh values('a', date '2007-07-01', 'b');
insert into hhh values('a', date '2007-08-01', 'b');
insert into hhh values('a', date '2007-09-01', 'b');
insert into hhh values('a', date '2007-10-01', 'b');
insert into hhh values('a', date '2007-11-01', 'b');
insert into hhh values('a', date '2007-12-01', 'b');
insert into hhh values('a', date '2008-01-02', 'b');
insert into hhh values('a', date '2008-02-01', 'b');
insert into hhh values('a', date '2008-03-01', 'b');
insert into hhh values('a', date '2008-04-01', 'b');
insert into hhh values('a', date '2008-05-01', 'b');
insert into hhh values('a', date '2008-06-01', 'b');
insert into hhh values('a', date '2008-07-01', 'b');
insert into hhh values('a', date '2008-08-01', 'b');
insert into hhh values('a', date '2008-09-01', 'b');
insert into hhh values('a', date '2008-10-01', 'b');
insert into hhh values('a', date '2008-11-01', 'b');
insert into hhh values('a', date '2008-12-01', 'b');
select * from hhh;
-- truncate child partitions recursively
truncate table hhh;
select * from hhh;
drop table hhh cascade;
-- default partitions
-- hash partitions cannot have default partitions
create table jjj (aa int, bb int)
partition by hash(bb)
(partition j1, partition j2, default partition j3);
-- default partitions cannot have boundary specifications
create table jjj (aa int, bb date)
partition by range(bb)
(partition j1 end (date '2008-01-01'),
partition j2 end (date '2009-01-01'),
default partition j3 end (date '2010-01-01'));
-- more than one default partition
create table jjj (aa int, bb date)
partition by range(bb)
(partition j1 end (date '2008-01-01'),
partition j2 end (date '2009-01-01'),
default partition j3,
default partition j4);
-- check default
create table foz (i int, d date) distributed by (i)
partition by range (d)
(
default partition dsf,
partition foo start (date '2001-01-01') end (date '2005-01-01')
every(interval '1 year')
);
insert into foz values(1, '2003-04-01');
insert into foz values(2, '2010-04-01');
select * from foz;
select * from foz_1_prt_dsf;
drop table foz cascade;
-- check for out of order partition definitions. We should order these correctly
-- and determine the appropriate boundaries.
create table d (i int, j int) distributed by (i) partition by range(j)
( start (10), start(5), start(50) end(60));
insert into d values(1, 5);
insert into d values(1, 10);
insert into d values(1, 11);
insert into d values(1, 55);
insert into d values(1, 70);
select * from d;
select * from d_1_prt_1;
select * from d_1_prt_2;
select * from d_1_prt_3;
drop table d cascade;
-- check for NULL support
-- hash
create table d (i int, j int) partition by hash(j) partitions 4;
insert into d values(1, NULL);
insert into d values(NULL, NULL);
drop table d cascade;
-- list
create table d (i int, j int) partition by list(j)
(partition a values(1, 2, NULL),
partition b values(3, 4)
);
insert into d values(1, 1);
insert into d values(1, 2);
insert into d values(1, NULL);
insert into d values(1, 3);
insert into d values(1, 4);
select * from d_1_prt_a;
select * from d_1_prt_b;
drop table d cascade;
--range
-- Reject NULL values
create table d (i int, j int) partition by range(j)
(partition a start (1) end(10), partition b start(11) end(20));
insert into d values (1, 1);
insert into d values (1, 2);
insert into d values (1, NULL);
drop table d cascade;
-- allow NULLs into the default partition
create table d (i int, j int) partition by range(j)
(partition a start (1) end(10), partition b start(11) end(20),
default partition abc);
insert into d values (1, 1);
insert into d values (1, 2);
insert into d values (1, NULL);
select * from d_1_prt_abc;
drop table d cascade;
-- multicolumn list support
create table d (a int, b int, c int) distributed by (a)
partition by list(b, c)
(partition a values(('1', '2'), ('3', '4')),
partition b values(('100', '20')),
partition c values(('1000', '1001'), ('1001', '1002'), ('1003', '1004')));
insert into d values(1, 1, 2);
insert into d values(1, 3, 4);
insert into d values(1, 100, 20);
insert into d values(1, 100, 2000);
insert into d values(1, '1000', '1001'), (1, '1001', '1002'), (1, '1003', '1004');
insert into d values(1, 100, NULL);
select * from d_1_prt_a;
select * from d_1_prt_b;
select * from d_1_prt_c;
drop table d cascade;
-- test multi value range partitioning
create table b (i int, j date) distributed by (i)
partition by range (i, j)
(start(1, '2008-01-01') end (10, '2009-01-01'),
start(1, '2009-01-01') end(15, '2010-01-01'),
start(15, '2010-01-01') end (30, '2011-01-01'),
start(1, '2011-01-01') end (100, '2012-01-01')
);
-- should work
insert into b values(1, '2008-06-11');
insert into b values(11, '2009-08-24');
insert into b values(25, '2010-01-22');
insert into b values(90, '2011-05-04');
-- shouldn't work
insert into b values(1, '2019-01-01');
insert into b values(91, '2008-05-05');
select * from b_1_prt_1;
select * from b_1_prt_2;
select * from b_1_prt_3;
select * from b_1_prt_4;
drop table b;
-- try some different combinations
create table b (i int, n numeric(20, 2), t timestamp, s text)
distributed by (i)
partition by range(n, t, s)
(
start(2000.99, '2007-01-01 00:00:00', 'AAA')
end (4000.95, '2007-02-02 15:00:00', 'BBB'),
start(2000.99, '2007-01-01 00:00:00', 'BBB')
end (4000.95, '2007-02-02 16:00:00', 'CCC'),
start(4000.95, '2007-01-01 00:00:00', 'AAA')
end (7000.95, '2007-02-02 15:00:00', 'BBB')
);
-- should work
insert into b values(1, 2000.99, '2007-01-01 00:00:00', 'AAA');
insert into b values(2, 2000.99, '2007-01-01 00:00:00', 'BBB');
insert into b values(3, 4000.95, '2007-01-01 00:00:00', 'AAA');
insert into b values(6, 3000, '2007-02-02 15:30:00', 'BBC');
insert into b values(6, 3000, '2007-02-02 15:30:00', 'CC');
insert into b values(6, 3000, '2007-02-02 16:00:00'::timestamp -
'1 second'::interval, 'BBZZZZZZZZZZ');
-- should fail
insert into b values(6, 3000, '2007-02-02 15:30:00', 'CCCCCCC');
insert into b values(4, 5000, '2007-01-01 12:00:00', 'BCC');
insert into b values(5, 8000, '2007-01-01 12:00:00', 'ZZZ');
insert into b values(6, 3000, '2007-02-02 16:00:00', 'ABZZZZZZZZZZ');
insert into b values(6, 1000, '2007-02-02 16:00:00', 'ABZZZZZZZZZZ');
insert into b values(6, 3000, '2006-02-02 16:00:00', 'ABZZZZZZZZZZ');
insert into b values(6, 3000, '2007-02-02 00:00:00', 'A');
-- NULL tests
insert into b default values;
insert into b values(6, 3000, '2007-01-01 12:00:00', NULL);
drop table b;
-- check that we detect subpartitions partitioning a column that is already
-- a partitioning target
create table a (i int, b int)
distributed by (i)
partition by range (i)
subpartition by hash(b) subpartitions 3,
subpartition by hash(b) subpartitions 2
(start(1) end(100),
start(100) end(1000)
);
-- MPP-3988: allow same column in multiple partitioning keys at
-- different levels -- so this is legal again...
drop table if exists a;
-- Check multi level partition COPY
CREATE TABLE REGION (
R_REGIONKEY INTEGER not null,
R_NAME CHAR(25),
R_COMMENT VARCHAR(152)
)
distributed by (r_regionkey)
partition by hash (r_regionkey) partitions 1
subpartition by hash (r_name) subpartitions 3
,subpartition by hash (r_comment) subpartitions 2
(
partition p1(subpartition sp1,subpartition sp2,subpartition sp3)
);
create unique index region_pkey on region(r_regionkey);
copy region from stdin with delimiter '|';
0|AFRICA|lar deposits. blithely final packages cajole. regular waters are
1|AMERICA|hs use ironic, even requests. s
2|ASIA|ges. thinly even pinto beans ca
3|EUROPE|ly final courts cajole furiously final excuse
4|MIDDLE EAST|uickly special accounts cajole carefully blithely close
5|AUSTRALIA|sdf
6|ANTARCTICA|dsfdfg
\.
-- Test indexes
set enable_seqscan to off;
select * from region where r_regionkey = 1;
select * from region where r_regionkey = 2;
select * from region where r_regionkey = 3;
select * from region where r_regionkey = 4;
select * from region where r_regionkey = 5;
select * from region where r_regionkey = 6;
-- Test indexes with insert
-- start_matchsubs
--
-- # Note: insert is different partition depending on endianess
--
-- m/ERROR:.*duplicate key violates unique constraint.*region_1_prt_p1_2_prt_sp\d+_3_prt_1_pkey/
-- s/sp\d+/SPSOMETHING/
--
-- end_matchsubs
insert into region values(7, 'abc', 'def');
select * from region where r_regionkey = '7';
-- test duplicate key. We shouldn't really allow primary keys on partitioned
-- tables since we cannot enfoce them. But since this insert maps to a
-- single definitive partition, we can detect it.
insert into region values(7, 'abc', 'def');
drop table region;
-- exchange
-- 1) test all sanity checking
-- policies are different
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p (i int, j int) distributed by (j);
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
drop table foo_p;
drop table bar_p;
-- random policy vs. hash policy
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p (i int, j int) distributed randomly;
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
drop table foo_p;
drop table bar_p;
-- different number of columns
create table foo_p (i int, j int, k text) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p (i int, j int) distributed by (i);
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
drop table foo_p;
drop table bar_p;
-- different types
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p (i int, j int8) distributed by (i);
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
drop table foo_p;
drop table bar_p;
-- different column names
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p (i int, m int) distributed by (i);
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
drop table foo_p;
drop table bar_p;
-- different owner
create role part_role;
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p (i int, j int) distributed by (i);
set session authorization part_role;
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
-- back to super user
\c -
alter table bar_p owner to part_role;
set session authorization part_role;
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
\c -
-- owners should be the same, error out
alter table foo_p exchange partition for(rank(6)) with table bar_p;
drop table foo_p;
drop table bar_p;
drop role part_role;
-- with and without OIDs
-- MPP-8405: disallow OIDS on partitioned tables
create table foo_p (i int, j int) with (oids = true) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
-- but disallow exchange if different oid settings
create table foo_p (i int, j int) with (oids = false) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p (i int, j int) with (oids = true) distributed by (i);
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
drop table foo_p;
drop table bar_p;
-- non-partition table involved in inheritance
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table barparent(i int, j int) distributed by (i);
create table bar_p () inherits(barparent);
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
drop table foo_p;
drop table bar_p;
drop table barparent;
-- non-partition table involved in inheritance
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int) distributed by (i);
create table barchild () inherits(bar_p);
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
drop table foo_p;
drop table barchild;
drop table bar_p;
-- rules on non-partition table
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int) distributed by (i);
create table baz_p(i int, j int) distributed by (i);
create rule bar_baz as on insert to bar_p do instead insert into baz_p
values(NEW.i, NEW.j);
alter table foo_p exchange partition for(rank(2)) with table bar_p;
drop table foo_p, bar_p, baz_p;
-- Should fail: A constraint on bar_p isn't shared by all the parts.
-- Allowing this would make an inconsistent partitioned table. Note
-- that it is possible to have a constraint that prevents rows from
-- going into one or more parts. This isn't a conflict, though prior
-- versions would fail because "a constraint on bar_p conflicts with
-- partitioning rule".
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int check (j > 1000)) distributed by (i);
alter table foo_p exchange partition for(rank(2)) with table bar_p;
drop table foo_p, bar_p;
-- Should fail: A constraint on bar_p isn't shared by all the parts.
-- Allowing this would make an inconsistent partitioned table.
-- Prior versions allowed this, so parts could have differing constraints
-- as long as they avoided the partition columns.
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int check (i > 1000), j int) distributed by (i);
alter table foo_p exchange partition for(rank(2)) with table bar_p;
drop table foo_p, bar_p;
-- Shouldn't fail: check constraint matches partition rule.
-- Note this test is slightly different from prior versions to get
-- in line with constraint consistency requirement.
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int check (j >= 2 and j < 3 ))
distributed by (i);
insert into bar_p values(100000, 2);
alter table foo_p exchange partition for(rank(2)) with table bar_p;
insert into bar_p values(200000, 2);
select * from bar_p;
drop table foo_p, bar_p;
-- permissions
create role part_role;
create table foo_p (i int) partition by range(i)
(start(1) end(10) every(1));
create table bar_p (i int);
grant select on foo_p to part_role;
revoke all on bar_p from part_role;
select has_table_privilege('part_role', 'foo_p_1_prt_6'::regclass, 'select');
select has_table_privilege('part_role', 'bar_p'::regclass, 'select');
alter table foo_p exchange partition for(rank(6)) with table bar_p;
select has_table_privilege('part_role', 'foo_p_1_prt_6'::regclass, 'select');
select has_table_privilege('part_role', 'bar_p'::regclass, 'select');
drop table foo_p;
drop table bar_p;
drop role part_role;
-- validation
create table foo_p (i int) partition by range(i)
(start(1) end(10) every(1));
create table bar_p (i int);
insert into bar_p values(6);
insert into bar_p values(100);
-- should fail
alter table foo_p exchange partition for(rank(6)) with table bar_p;
alter table foo_p exchange partition for(rank(6)) with table bar_p without
validation;
select * from foo_p;
drop table foo_p, bar_p;
-- basic test
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int) distributed by (i);
insert into bar_p values(6);
alter table foo_p exchange partition for(rank(6)) with table bar_p;
select * from foo_p;
select * from bar_p;
-- test that we got the dependencies right
drop table bar_p;
select * from foo_p;
drop table foo_p;
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int) distributed by (i);
insert into bar_p values(6, 6);
alter table foo_p exchange partition for(rank(6)) with table bar_p;
-- Should fail. Prior releases didn't convey constraints out via exchange
-- but we do now, so the following tries to insert a value that can't go
-- in part 6.
insert into bar_p values(10, 10);
drop table foo_p;
select * from bar_p;
-- Should succeed. Conveyed constraint matches.
insert into bar_p values(6, 6);
select * from bar_p;
drop table bar_p;
-- AO exchange with heap
create table foo_p (i int, j int) with(appendonly = true) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int) distributed by (i);
insert into foo_p values(1, 1), (2, 1), (3, 1);
insert into bar_p values(6, 6);
alter table foo_p exchange partition for(rank(6)) with table bar_p;
select * from foo_p;
drop table bar_p;
drop table foo_p;
-- other way around
create table foo_p (i int, j int) with(appendonly = false) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int) with(appendonly = true) distributed by (i);
insert into foo_p values(1, 1), (2, 1), (3, 2);
insert into bar_p values(6, 6);
alter table foo_p exchange partition for(rank(6)) with table bar_p;
select * from foo_p;
drop table bar_p;
drop table foo_p;
-- exchange AO with AO
create table foo_p (i int, j int) with(appendonly = true) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int) with(appendonly = true) distributed by (i);
insert into foo_p values(1, 2), (2, 3), (3, 4);
insert into bar_p values(6, 6);
alter table foo_p exchange partition for(rank(6)) with table bar_p;
select * from foo_p;
drop table bar_p;
drop table foo_p;
-- exchange same table more than once
create table foo_p (i int, j int) distributed by (i)
partition by range(j)
(start(1) end(10) every(1));
create table bar_p(i int, j int) distributed by (i);
insert into bar_p values(6, 6);
alter table foo_p exchange partition for(rank(6)) with table bar_p;
select * from foo_p;
select * from bar_p;
alter table foo_p exchange partition for(rank(6)) with table bar_p;
select * from foo_p;
select * from bar_p;
alter table foo_p exchange partition for(rank(6)) with table bar_p;
select * from foo_p;
select * from bar_p;
drop table foo_p;
drop table bar_p;
-- XXX: not yet: VALIDATE parameter
-- Check for overflow of circular data types like time
-- Should fail
CREATE TABLE TIME_TBL_HOUR_2 (f1 time(2)) distributed by (f1)
partition by range (f1)
(
start (time '00:00') end (time '24:00') EVERY (INTERVAL '1 hour')
);
-- Should fail
CREATE TABLE TIME_TBL_HOUR_2 (f1 time(2)) distributed by (f1)
partition by range (f1)
(
start (time '00:00') end (time '23:59') EVERY (INTERVAL '1 hour')
);
-- Should work
CREATE TABLE TIME_TBL_HOUR_2 (f1 time(2)) distributed by (f1)
partition by range (f1)
(
start (time '00:00') end (time '23:00') EVERY (INTERVAL '1 hour')
);
drop table TIME_TBL_HOUR_2;
-- Check for every parameters that just don't make sense
create table hhh_r1 (a char(1), b date, d char(3))
distributed by (a) partition by range (b)
(
partition aa start (date '2007-01-01') end (date '2008-01-01')
every (interval '0 days')
);
create table foo_p (i int) distributed by(i)
partition by range(i)
(start (1) end (20) every(0));
-- Check for ambiguous EVERY parameters
-- should fail
create table foo_p (i int) distributed by (i)
partition by range(i)
(start (1) end (20) every (0.6));
-- should fail
create table foo_p (i int) distributed by (i)
partition by range(i)
(start (1) end (20) every (0.3));
-- should fail
create table foo_p (i int) distributed by (i)
partition by range(i)
(start (1) end (20) every (1.3));
-- should fail
create table foo_p (i int) distributed by (i)
partition by range(i)
(start (1) end (20) every (10.9));
-- should fail
create table foo_p (i int, j date) distributed by (i)
partition by range(j)
(start ('2007-01-01') end ('2008-01-01') every (interval '0.5 days'));
-- should fail
create table foo_p (i int, j date) distributed by (i)
partition by range(j)
(start ('2007-01-01') end ('2008-01-01') every (interval '0.5 days'));
-- should fail
create table foo_p (i int, j date) distributed by (i)
partition by range(j)
(start ('2007-01-01') end ('2008-01-01') every (interval '12 hours'));
-- should fail
create table foo_p (i int, j date) distributed by (i)
partition by range(j)
(start ('2007-01-01') end ('2008-01-01') every (interval '1.2 days'));
-- should work
create table foo_p (i int, j timestamp) distributed by (i)
partition by range(j)
(start ('2007-01-01') end ('2007-01-05') every (interval '1.2 days'));
drop table foo_p;
-- test inclusive/exclusive
CREATE TABLE supplier2(
S_SUPPKEY INTEGER,
S_NAME CHAR(25),
S_ADDRESS VARCHAR(40),
S_NATIONKEY INTEGER,
S_PHONECHAR char(15),
S_ACCTBAL decimal,
S_COMMENT VARCHAR(100)
)
partition by range (s_nationkey)
(
partition p1 start(0) ,
partition p2 start(12) end(13),
partition p3 end(20) inclusive,
partition p4 start(20) exclusive ,
partition p5 start(22) end(25)
);
-- Make sure they're correctly ordered
select parname, parruleord, pg_get_expr(parrangestart, parchildrelid, false),
parrangestartincl,
pg_get_expr(parrangeend, parchildrelid, false),parrangeendincl
from pg_partition_rule where
paroid in (select oid from pg_partition where parrelid = 'supplier2'::regclass)
order by parruleord;
insert into supplier2 (s_suppkey, s_nationkey) select i, i
from generate_series(1, 24) i;
select * from supplier2_1_prt_p1 order by S_NATIONKEY;
select * from supplier2_1_prt_p2 order by S_NATIONKEY;
select * from supplier2_1_prt_p3 order by S_NATIONKEY;
select * from supplier2_1_prt_p4 order by S_NATIONKEY;
select * from supplier2_1_prt_p5 order by S_NATIONKEY;
drop table supplier2;
-- mpp3238
create table foo_p (i int) partition by range (i)
(
partition p1 start('1') ,
partition p2 start('2639161') ,
partition p3 start('5957166') ,
partition p4 start('5981976') end('5994376') inclusive,
partition p5 end('6000001')
);
select parname, parruleord, pg_get_expr(parrangestart, parchildrelid, false) as
start, pg_get_expr(parrangeend, parchildrelid, false) as end,
pg_get_expr(parlistvalues, parchildrelid, false) as list from
pg_partition_rule
r, pg_partition p where r.paroid = p.oid and p.parlevel = 0 and
p.parrelid = 'foo_p'::regclass order by 1;
insert into foo_p values(5994400);
insert into foo_p values(1);
insert into foo_p values(6000002);
insert into foo_p values(5994376);
drop table foo_p;
create table foo_p (i int)
partition by range(i)
(partition p1 start(1) end(5),
partition p2 start(10),
partition p3 end(10) exclusive);
select parname, parruleord, pg_get_expr(parrangestart, parchildrelid, false) as
start, pg_get_expr(parrangeend, parchildrelid, false) as end,
pg_get_expr(parlistvalues, parchildrelid, false) as list from
pg_partition_rule
r, pg_partition p where r.paroid = p.oid and p.parlevel = 0 and
p.parrelid = 'foo_p'::regclass order by 1;
drop table foo_p;
create table foo_p (i int)
partition by range(i)
(partition p1 start(1) end(5),
partition p2 start(10) exclusive,
partition p3 end(10) inclusive);
select parname, parruleord, pg_get_expr(parrangestart, parchildrelid, false) as
start, parrangestartincl,
pg_get_expr(parrangeend, parchildrelid, false) as end,
parrangeendincl,
pg_get_expr(parlistvalues, parchildrelid, false) as list from
pg_partition_rule
r, pg_partition p where r.paroid = p.oid and p.parlevel = 0 and
p.parrelid = 'foo_p'::regclass order by 1;
insert into foo_p values(1), (5), (10);
drop table foo_p;
-- MPP-3264
-- mix AO with master HEAP and see if copy works
create table foo_p (i int)
partition by list(i)
(partition p1 values(1, 2, 3) with (appendonly = true),
partition p2 values(4)
);
copy foo_p from stdin;
1
2
3
4
\.
select * from foo_p;
select * from foo_p_1_prt_p1;
select * from foo_p_1_prt_p2;
drop table foo_p;
-- other way around
create table foo_p (i int) with(appendonly = true)
partition by list(i)
(partition p1 values(1, 2, 3) with (appendonly = false),
partition p2 values(4)
);
copy foo_p from stdin;
1
2
3
4
\.
select * from foo_p;
select * from foo_p_1_prt_p1;
select * from foo_p_1_prt_p2;
drop table foo_p;
-- MPP-3283
CREATE TABLE PARTSUPP (
PS_PARTKEY INTEGER,
PS_SUPPKEY INTEGER,
PS_AVAILQTY integer,
PS_SUPPLYCOST decimal,
PS_COMMENT VARCHAR(199)
)
partition by range (ps_suppkey)
subpartition by range (ps_partkey)
,subpartition by range (ps_supplycost) subpartition template (start('1')
end('1001') every(500))
(
partition p1 start('1') end('10001') every(5000)
(subpartition sp1 start('1') end('200001') every(66666)
)
);
insert into partsupp values(1,2,3325,771.64,', even theodolites. regular, final
theodolites eat after the carefully pending foxes. furiously regular deposits
sleep slyly. carefully bold realms above the ironic dependencies haggle
careful');
copy partsupp from stdin with delimiter '|';
1|2|3325|771.64|, even theodolites. regular, final theodolites eat after the
\.
drop table partsupp;
--MPP-3285
CREATE TABLE LINEITEM (
L_ORDERKEY INT8,
L_PARTKEY INTEGER,
L_SUPPKEY INTEGER,
L_LINENUMBER integer,
L_QUANTITY decimal,
L_EXTENDEDPRICE decimal,
L_DISCOUNT decimal,
L_TAX decimal,
L_RETURNFLAG CHAR(1),
L_LINESTATUS CHAR(1),
L_SHIPDATE date,
L_COMMITDATE date,
L_RECEIPTDATE date,
L_SHIPINSTRUCT CHAR(25),
L_SHIPMODE CHAR(10),
L_COMMENT VARCHAR(44)
)
partition by range (l_commitdate)
(
partition p1 start('1992-01-31') end('1998-11-01') every(interval '20 months')
);
copy lineitem from stdin with delimiter '|';
18182|5794|3295|4|9|15298.11|0.04|0.01|N|O|1995-07-04|1995-05-30|1995-08-03|DELIVER IN PERSON|RAIL|y special platelets
\.
select parname, parruleord, pg_get_expr(parrangestart, parchildrelid, false) as
start, parrangestartincl,
pg_get_expr(parrangeend, parchildrelid, false) as end,
parrangeendincl,
pg_get_expr(parlistvalues, parchildrelid, false) as list from
pg_partition_rule
r, pg_partition p where r.paroid = p.oid and p.parlevel = 0 and
p.parrelid = 'lineitem'::regclass order by 1;
drop table lineitem;
-- Make sure ADD creates dependencies
create table i (i int) partition by range(i) (start (1) end(3) every(1));
alter table i add partition foo2 start(40) end (50);
drop table i;
create table i (i int) partition by range(i) (start (1) end(3) every(1));
alter table i add partition foo2 start(40) end (50);
alter table i drop partition foo2;
drop table i;
-- dumpability of partition info
create table i5 (i int) partition by RANGE(i) (start(1) exclusive end(10)
inclusive);
select tablename, partitiontablename,
partitionboundary from pg_partitions where
tablename = 'i5';
select pg_get_partition_def('i5'::regclass, true);
drop table i5;
CREATE TABLE PARTSUPP (
PS_PARTKEY INTEGER,
PS_SUPPKEY INTEGER,
PS_AVAILQTY integer,
PS_SUPPLYCOST decimal,
PS_COMMENT VARCHAR(199)
)
partition by range (ps_suppkey)
subpartition by range (ps_partkey)
,subpartition by range (ps_supplycost) subpartition template (start('1')
end('1001') every(500))
(
partition p1 start('1') end('10001') every(5000)
(subpartition sp1 start('1') end('200001') every(66666)
)
);
select tablename, partitiontablename,
partitionboundary from pg_partitions where
tablename = 'partsupp';
select pg_get_partition_def('partsupp'::regclass, true);
drop table partsupp;
set gp_enable_hash_partitioned_tables = true;
create table i5 (i int, g text) partition by list(g)
subpartition by hash(i) subpartitions 3
(partition p1 values('foo', 'bar'), partition p2 values('foz')
);
select tablename, partitiontablename,
partitionboundary from pg_partitions where
tablename = 'i5';
select pg_get_partition_def('i5'::regclass, true);
drop table i5;
set gp_enable_hash_partitioned_tables = false;
-- ALTER TABLE ALTER PARTITION tests
CREATE TABLE rank2 (id int, rank int,
year date, gender char(1),
usstate char(2))
DISTRIBUTED BY (id, gender, year, usstate)
partition by list (gender)
subpartition by range (year)
subpartition template (
subpartition jan01 start (date '2001-01-01'),
subpartition jan02 start (date '2002-01-01'),
subpartition jan03 start (date '2003-01-01'),
subpartition jan04 start (date '2004-01-01'),
subpartition jan05 start (date '2005-01-01')
),
subpartition by list (usstate)
subpartition template (
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
)
(
partition boys values ('M'),
partition girls values ('F')
);
-- and without subpartition templates...
CREATE TABLE rank3 (id int, rank int,
year date, gender char(1),
usstate char(2))
DISTRIBUTED BY (id, gender, year, usstate)
partition by list (gender)
subpartition by range (year),
subpartition by list (usstate)
(
partition boys values ('M')
(
subpartition jan01 start (date '2001-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
),
subpartition jan02 start (date '2002-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
),
subpartition jan03 start (date '2003-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
),
subpartition jan04 start (date '2004-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
),
subpartition jan05 start (date '2005-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
)
)
,
partition girls values ('F')
(
subpartition jan01 start (date '2001-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
),
subpartition jan02 start (date '2002-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
),
subpartition jan03 start (date '2003-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
),
subpartition jan04 start (date '2004-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
),
subpartition jan05 start (date '2005-01-01')
(
subpartition mass values ('MA'),
subpartition cali values ('CA'),
subpartition ohio values ('OH')
)
)
);
-- ok
alter table rank2 truncate partition girls;
alter table rank2 alter partition girls truncate partition for (rank(1));
alter table rank2 alter partition girls alter partition
for (rank(1)) truncate partition mass;
-- don't NOTIFY of children if cascade
alter table rank2 truncate partition girls cascade;
-- fail - no rank 100
alter table rank2 alter partition girls truncate partition for (rank(100));
-- fail - no funky
alter table rank2 alter partition girls alter partition
for (rank(1)) truncate partition "funky";
-- fail - no funky (drop)
alter table rank2 alter partition girls alter partition
for (rank(1)) drop partition "funky";
-- fail - missing name
alter table rank2 alter partition girls alter partition
for (rank(1)) drop partition ;
-- ok
alter table rank2 alter partition girls drop partition
for (rank(1)) ;
-- ok , skipping
alter table rank2 alter partition girls drop partition if exists jan01;
-- ok until run out of partitions
alter table rank2 alter partition girls drop partition ;
alter table rank2 alter partition girls drop partition ;
alter table rank2 alter partition girls drop partition ;
alter table rank2 alter partition girls drop partition ;
alter table rank2 alter partition girls drop partition ;
-- ok, skipping
alter table rank2 alter partition girls drop partition if exists for (rank(5));
-- ok
alter table rank2 alter partition girls rename partition jan05
to "funky fresh";
alter table rank2 alter partition girls rename partition "funky fresh"
to jan05;
-- fail , not exist
alter table rank2 alter partition girls alter partition jan05 rename
partition jan01 to foo;
-- fail not exist
alter table rank2 alter partition girls alter partition jan05 alter
partition cali rename partition foo to bar;
-- fail not partitioned
alter table rank2 alter partition girls alter partition jan05 alter
partition cali alter partition foo drop partition bar;
-- ADD PARTITION, with and without templates
-- fails for rank2 (due to template), works for rank3
alter table rank2
add partition neuter values ('N')
(subpartition foo
start ('2001-01-01') end ('2002-01-01')
every (interval '1 month')
(subpartition bar values ('AZ')));
alter table rank3
add partition neuter values ('N')
(subpartition foo
start ('2001-01-01') end ('2002-01-01')
every (interval '1 month')
(subpartition bar values ('AZ')));
-- fail , no subpartition spec for rank3, works for rank2
alter table rank2 alter partition boys
add partition jan00 start ('2000-01-01') end ('2001-01-01');
alter table rank3 alter partition boys
add partition jan00 start ('2000-01-01') end ('2001-01-01');
-- work - create subpartition for rank3, fail for rank2
alter table rank2 alter partition boys
add partition jan99 start ('1999-01-01') end ('2000-01-01')
(subpartition ariz values ('AZ'));
alter table rank3 alter partition boys
add partition jan00 start ('2000-01-01') end ('2001-01-01')
(subpartition ariz values ('AZ'));
-- works for both -- adding leaf partition doesn't conflict with template
alter table rank2 alter partition boys
alter partition jan00
add partition haw values ('HI');
alter table rank3 alter partition boys
alter partition jan00
add partition haw values ('HI');
alter table rank2 drop partition neuter;
alter table rank3 drop partition neuter;
-- fail , no subpartition spec for rank3, work for rank2
alter table rank2
add default partition neuter ;
alter table rank3
add default partition neuter ;
alter table rank2
add default partition neuter
(subpartition foo
start ('2001-01-01') end ('2002-01-01')
every (interval '1 month')
(subpartition ariz values ('AZ')));
alter table rank3
add default partition neuter
(subpartition foo
start ('2001-01-01') end ('2002-01-01')
every (interval '1 month')
(subpartition ariz values ('AZ')));
-- fail
alter table rank2
alter default partition add default partition def1
(subpartition haw values ('HI'));
-- fail
alter table rank2
alter default partition alter default partition
add default partition def2;
-- work
alter table rank2
alter default partition add default partition def1;
alter table rank2
alter default partition alter default partition
add default partition def2;
alter table rank3
alter default partition add default partition def1
(subpartition haw values ('HI'));
alter table rank3
alter default partition alter default partition
add default partition def2;
drop table rank2 ;
drop table rank3 ;
-- **END** ALTER TABLE ALTER PARTITION tests
-- Test casting
create table f (i int) partition by range (i) (start(1::int) end(10::int));
drop table f;
create table f (i bigint) partition by range (i) (start(1::int8)
end(1152921504606846976::int8) every(576460752303423488));
drop table f;
create table f (n numeric(20, 2)) partition by range(n) (start(1::bigint)
end(10000::bigint));
drop table f;
create table f (n numeric(20, 2)) partition by range(n) (start(1::bigint)
end(10000::text));
drop table f;
--should fail. bool -> numeric makes no sense
create table f (n numeric(20, 2)) partition by range(n) (start(1::bigint)
end('f'::bool));
-- see that grant and revoke cascade to children
create role part_role;
create table granttest (i int, j int) partition by range(i)
subpartition by list(j) subpartition template (values(1, 2, 3))
(start(1) end(4) every(1));
select has_table_privilege('part_role', 'granttest'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_1'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_2'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_3'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_1_2_prt_1'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_2_2_prt_1'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_3_2_prt_1'::regclass,'select');
grant select on granttest to part_role;
select has_table_privilege('part_role', 'granttest'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_1'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_2'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_3'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_1_2_prt_1'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_2_2_prt_1'::regclass,'select');
select has_table_privilege('part_role', 'granttest_1_prt_3_2_prt_1'::regclass,'select');
grant insert on granttest to part_role;
select has_table_privilege('part_role', 'granttest'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_1'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_2'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_3'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_1_2_prt_1'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_2_2_prt_1'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_3_2_prt_1'::regclass,'insert');
revoke all on granttest from part_role;
select has_table_privilege('part_role', 'granttest'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_1'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_2'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_3'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_1_2_prt_1'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_2_2_prt_1'::regclass,'insert');
select has_table_privilege('part_role', 'granttest_1_prt_3_2_prt_1'::regclass,'insert');
drop table granttest;
drop role part_role;
-- deep inline + optional subpartition comma:
CREATE TABLE partsupp (
ps_partkey integer,
ps_suppkey integer,
ps_availqty integer,
ps_supplycost numeric,
ps_comment character varying(199)
) distributed by (ps_partkey) PARTITION BY RANGE(ps_suppkey)
SUBPARTITION BY RANGE(ps_partkey)
SUBPARTITION BY RANGE(ps_supplycost)
(
PARTITION p1_1 START (1) END (1666667) EVERY (1666666)
(
START (1) END (19304783)
(
START (1::numeric) END (501::numeric) EVERY (500),
START (501::numeric) END (1001::numeric) EVERY (500)
),
START (19304783) END (100000001)
(
START (1::numeric) END (501::numeric) EVERY (500),
START (501::numeric) END (1001::numeric) EVERY (500)
)
),
PARTITION p1_2 START (1666667) END (3333333) EVERY (1666666)
(
START (1) END (19304783)
(
START (1::numeric) END (501::numeric) EVERY (500),
START (501::numeric) END (1001::numeric) EVERY (500)
),
START (19304783) END (100000001)
(
START (1::numeric) END (501::numeric) EVERY (500),
START (501::numeric) END (1001::numeric) EVERY (500)
)
),
PARTITION p1_3 START (3333333) END (4999999) EVERY (1666666)
(
START (1) END (19304783)
(
START (1::numeric) END (501::numeric) EVERY (500),
START (501::numeric) END (1001::numeric) EVERY (500)
),
START (19304783) END (100000001)
(
START (1::numeric) END (501::numeric) EVERY (500),
START (501::numeric) END (1001::numeric) EVERY (500)
)
),
PARTITION p1_4 START (4999999) END (5000001) EVERY (1666666)
(
START (1) END (19304783)
(
START (1::numeric) END (501::numeric) EVERY (500),
START (501::numeric) END (1001::numeric) EVERY (500)
),
START (19304783) END (100000001)
(
START (1::numeric) END (501::numeric) EVERY (500),
START (501::numeric) END (1001::numeric) EVERY (500)
)
)
);
drop table partsupp;
-- Accept negative values trivially:
create table partition_g (i int) partition by range(i) (start((-1)) end(10));
drop table partition_g;
create table partition_g (i int) partition by range(i) (start(-1) end(10));
drop table partition_g;
CREATE TABLE orders (
o_orderkey bigint,
o_custkey integer,
o_orderstatus character(1),
o_totalprice numeric,
o_orderdate date,
o_orderpriority character(15),
o_clerk character(15),
o_shippriority integer,
o_comment character varying(79)
)
WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) PARTITION BY RANGE(o_orderdate)
SUBPARTITION BY RANGE(o_custkey)
SUBPARTITION BY RANGE(o_orderkey)
(
PARTITION p1_1 START ('1992-01-01'::date) END ('1993-06-01'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
),
SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
)
),
PARTITION p1_2 START ('1993-06-01'::date) END ('1994-11-01'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
),
SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
)
),
PARTITION p1_3 START ('1994-11-01'::date) END ('1996-04-01'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
),
SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
)
),
PARTITION p1_4 START ('1996-04-01'::date) END ('1997-09-01'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
),
SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
)
),
PARTITION p1_5 START ('1997-09-01'::date) END ('1998-08-03'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
),
SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
(
START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9),
START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9)
)
)
);
drop table orders;
-- grammar bug: MPP-3361
create table i2 (i int) partition by range(i) (start(-2::int) end(20));
drop table i2;
create table i2 (i int) partition by range(i) (start((-2)::int) end(20));
drop table i2;
create table i2 (i int) partition by range(i) (start(cast ((-2)::bigint as int))
end(20));
drop table i2;
CREATE TABLE partsupp (
ps_partkey integer,
ps_suppkey integer,
ps_availqty integer,
ps_supplycost numeric,
ps_comment character varying(199)
) PARTITION BY RANGE(ps_supplycost)
(
PARTITION newpart START ((-10000)::numeric) EXCLUSIVE END (1::numeric)
,
PARTITION p1 START (1::numeric) END (1001::numeric)
);
drop table partsupp;
-- MPP-3379
drop table if exists tmp_nation;
CREATE TABLE tmp_nation (N_NATIONKEY INTEGER, N_NAME CHAR(25), N_REGIONKEY INTEGER, N_COMMENT VARCHAR(152))
partition by range (n_nationkey)
(
partition p1 start('0') WITH (appendonly=true,checksum=true,blocksize=1998848,compresslevel=4),
partition p2 start('11') end('15') inclusive WITH (checksum=false,appendonly=true,blocksize=655360,compresslevel=4),
partition p3 start('15') exclusive end('19'), partition p4 start('19') WITH (compresslevel=8,appendonly=true,checksum=false,blocksize=884736),
partition p5 start('20')
);
delete from tmp_nation;
drop table tmp_nation;
-- SPLIT tests
-- basic sanity tests. All should pass.
create table k (i int) partition by range(i) (start(1) end(10) every(2),
default partition mydef);
insert into k select i from generate_series(1, 100) i;
alter table k split partition mydef at (20) into (partition mydef,
partition foo);
drop table k;
create table j (i int) partition by list(i) (partition a values(1, 2, 3, 4),
partition b values(5, 6, 7, 8));
insert into j select i from generate_series(1, 8) i;
alter table j split partition for(1) at (2, 3) into (partition fa, partition
fb);
select * from j_1_prt_fa;
select * from j_1_prt_fb;
alter table j split partition for(5) at (6);
select * from j;
-- should fail
alter table j split partition for (1) at (100);
drop table j;
create table k (i int) partition by range(i) (start(1) end(10) every(2),
default partition mydef);
-- should fail
alter table k split default partition start(30) end (300) into (partition mydef, partition mydef);
alter table k split partition for(3) at (20);
drop table k;
-- should work
create table k (i int) partition by range(i) (start(1) end(10) every(2),
default partition mydef);
insert into k select i from generate_series(1, 30) i;
alter table k split default partition start(15) end(20) into
(partition mydef, partition foo);
select * from k_1_prt_foo;
alter table k split default partition start(22) exclusive end(25) inclusive
into (partition bar, partition mydef);
select * from k_1_prt_bar;
alter table k split partition bar at (23) into (partition baz, partition foz);
select partitiontablename,partitionposition,partitionrangestart,
partitionrangeend from pg_partitions where tablename = 'k'
order by partitionposition;
drop table k;
-- Test errors for default handling
create table k (i int) partition by range(i) (start(1) end(2),
default partition mydef);
alter table k split partition mydef at (25) into (partition foo, partition
mydef);
drop table k;
create table k (i int) partition by list(i) (values(1), values(2),
default partition mydef);
alter table k split default partition start(10) end(20);
drop table k;
-- Check that we support int2
CREATE TABLE myINT2_TBL(q1 int2)
partition by range (q1)
(start (1) end (3) every (1));
insert into myint2_tbl values(1), (2);
drop table myint2_tbl;
-- check that we don't allow updates of tuples such that they would move
-- between partitions
create table v (i int, j int) partition by range(j) (start(1) end(5)
every(2));
insert into v values(1, 1) ;
-- should work
update v set j = 2;
-- should fail
update v set j = 3;
drop table v;
-- test AO seg totals
--
-- Note: ignore partition tablenames due to endianess issues
--
create or replace function ao_ptotal(relname text) returns float8 as $$
declare
aosegname text;
tupcount float8 := 0;
rc int := 0;
begin
execute 'select relname from pg_class where oid=(select segrelid from pg_class, pg_appendonly where relname=''' || relname || ''' and relid = pg_class.oid)' into aosegname;
if aosegname > 0 then
execute 'select tupcount from pg_aoseg.' || aosegname into tupcount;
end if;
return tupcount;
end; $$ language plpgsql volatile;
create table ao_p (i int) with (appendonly = true)
partition by range(i)
(start(1) end(10) every(1));
insert into ao_p values(1), (2), (3);
-- start_ignore
select partitiontablename, ao_ptotal(partitiontablename)
from pg_partitions where tablename = 'ao_p';
-- end_ignore
truncate ao_p;
-- start_ignore
select partitiontablename, ao_ptotal(partitiontablename)
from pg_partitions where tablename = 'ao_p';
-- end_ignore
copy ao_p from stdin;
4
5
6
\.
-- start_ignore
select partitiontablename, ao_ptotal(partitiontablename)
from pg_partitions where tablename = 'ao_p';
-- end_ignore
-- try SREH
copy ao_p from stdin log errors into ao_p_err segment reject limit 100;
6
7
10000
f
\.
-- start_ignore
select partitiontablename, ao_ptotal(partitiontablename)
from pg_partitions where tablename = 'ao_p';
-- end_ignore
drop table ao_p;
-- MPP-3591: make sure we get inclusive/exclusive right with every().
create table k (i int) partition by range(i)
(start(0) exclusive end(100) inclusive every(25));
select partitiontablename, partitionboundary from pg_partitions
where tablename = 'k' order by 1;
insert into k select i from generate_series(1, 100) i;
drop table k;
-- ADD and SPLIT must get inherit permissions of the partition they're
-- modifying
create role part_role;
create table a (a int, b int, c int) partition by range(a) subpartition by
range(b) subpartition template (subpartition h start(1) end(10))
subpartition by range(c)
subpartition template(subpartition i start(1) end(10))
(partition g start(1) end(2));
revoke all on a from public;
grant insert on a to part_role;
-- revoke it from one existing partition, to make sure we don't screw up
-- existing permissions
revoke all on a_1_prt_g_2_prt_h_3_prt_i from part_role;
alter table a add partition b start(40) end(50);
set session authorization part_role;
select has_table_privilege('part_role', 'a'::regclass,'insert');
select has_table_privilege('part_role', 'a_1_prt_b_2_prt_h'::regclass,'insert');
select has_table_privilege('part_role', 'a_1_prt_b_2_prt_h_3_prt_i'::regclass,'insert');
select has_table_privilege('part_role', 'a_1_prt_g_2_prt_h_3_prt_i'::regclass,
'insert');
insert into a values(45, 5, 5);
-- didn't grant select
select has_table_privilege('part_role', 'a'::regclass,'select');
select has_table_privilege('part_role', 'a_1_prt_b_2_prt_h'::regclass,'select');
select has_table_privilege('part_role', 'a_1_prt_b_2_prt_h_3_prt_i'::regclass,'select');
\c -
drop table a;
create table a (i date) partition by range(i)
(partition f start(date '2005-01-01') end (date '2009-01-01')
every(interval '2 years'));
revoke all on a from public;
grant insert on a to part_role;
alter table a split partition for(rank(1)) at (date '2006-01-01')
into (partition f, partition g);
alter table a add default partition mydef;
alter table a split default partition start(date '2010-01-01') end(date
'2011-01-01') into(partition mydef, partition other);
set session authorization part_role;
select has_table_privilege('part_role', 'a'::regclass,'insert');
select has_table_privilege('part_role', 'a_1_prt_f'::regclass,'insert');
select has_table_privilege('part_role', 'a_1_prt_mydef'::regclass,'insert');
select has_table_privilege('part_role', 'a_1_prt_other'::regclass,'insert');
insert into a values('2005-05-05');
insert into a values('2006-05-05');
insert into a values('2010-10-10');
\c -
drop table a;
drop role part_role;
-- Check that when we split a default, the INTO clause must named the default
create table k (i date) partition by range(i) (start('2008-01-01')
end('2009-01-01') every(interval '1 month'), default partition default_part);
alter table k split default partition start ('2009-01-01') end ('2009-02-01')
into (partition aa, partition nodate);
alter table k split default partition start ('2009-01-01') end ('2009-02-01')
into (partition aa, partition default_part);
-- check that it works without INTO
alter table k split default partition start ('2009-02-01') end ('2009-03-01');
drop table k;
-- List too
create table k (i int) partition by list(i) (partition a values(1, 2),
partition b values(3, 4), default partition mydef);
alter table k split partition mydef at (5) into (partition foo, partition bar);
alter table k split partition mydef at (5) into (partition foo, partition mydef);
alter table k split partition mydef at (10);
drop table k;
-- For LIST, make sure that we reject AT() clauses which match all parameters
create table j (i int) partition by list(i) (partition a values(1, 2, 3, 4),
partition b values(5, 6, 7, 8));
alter table j split partition for(1) at (1,2) into (partition fa, partition fb);
alter table j split partition for(1) at (1,2)
into (partition f1a, partition f1b); -- This has partition rules that overlaps
drop table j;
-- Check that we can split LIST partitions that have a default partition
create table j (i int) partition by list(i) (partition a values(1, 2, 3, 4),
partition b values(5, 6, 7, 8), default partition default_part);
alter table j split partition for(1) at (1,2) into (partition f1a, partition
f1b);
drop table j;
-- Make sure range can too
create table j (i int) partition by range(i) (partition a start(1) end(10),
default partition default_part);
alter table j split partition for(1) at (5) into (partition f1a, partition f1b);
drop table j;
-- MPP-3667 ADD PARTITION overlaps
create table mpp3621 (aa date, bb date) partition by range (bb)
(partition foo start('2008-01-01'));
-- these are ok
alter table mpp3621 add partition a1 start ('2007-01-01') end ('2007-02-01');
alter table mpp3621 add partition a2 start ('2007-02-01') end ('2007-03-01');
alter table mpp3621 add partition a3 start ('2007-03-01') end ('2007-04-01');
alter table mpp3621 add partition a4 start ('2007-09-01') end ('2007-10-01');
alter table mpp3621 add partition a5 start ('2007-08-01') end ('2007-09-01');
alter table mpp3621 add partition a6 start ('2007-04-01') end ('2007-05-01');
alter table mpp3621 add partition a7 start ('2007-05-01') end ('2007-06-01');
-- was error due to startSearchpoint != endSearchpoint
alter table mpp3621 add partition a8 start ('2007-07-01') end ('2007-08-01');
-- ok
alter table mpp3621 add partition a9 start ('2007-06-01') end ('2007-07-01');
drop table mpp3621;
-- Check for MPP-3679
create table list_test (a text, b text) partition by list (a) (partition foo
values ('foo'), partition bar values ('bar'), default partition baz);
alter table list_test split default partition at ('baz') into (partition bing,
default partition);
drop table list_test;
-- MPP-3816: cannot drop column which is the subject of partition config
create table list_test(a int, b int, c int) distributed by (a)
partition by list(b)
subpartition by list(c) subpartition template(subpartition c values(2))
(partition b values(1));
-- should fail
alter table list_test drop column b;
alter table list_test drop column c;
drop table list_test;
-- MPP-3678: allow exchange and split on tables with subpartitioning
CREATE TABLE rank (
id int,
rank int,
year int,
gender char(1),
count int )
DISTRIBUTED BY (id)
PARTITION BY LIST (gender)
SUBPARTITION BY RANGE (year)
SUBPARTITION TEMPLATE (
SUBPARTITION year1 START (2001),
SUBPARTITION year2 START (2002),
SUBPARTITION year3 START (2003),
SUBPARTITION year4 START (2004),
SUBPARTITION year5 START (2005),
SUBPARTITION year6 START (2006) END (2007) )
(PARTITION girls VALUES ('F'),
PARTITION boys VALUES ('M')
);
alter table rank alter partition girls add default partition gfuture;
alter table rank alter partition boys add default partition bfuture;
insert into rank values(1, 1, 2007, 'M', 1);
insert into rank values(2, 2, 2008, 'M', 3);
select * from rank;
alter table rank alter partition boys split default partition start ('2007')
end ('2008') into (partition bfuture, partition year7);
select * from rank_1_prt_boys_2_prt_bfuture;
select * from rank_1_prt_boys_2_prt_year7;
select * from rank;
--exchange test
create table r (like rank);
insert into rank values(3, 3, 2004, 'F', 100);
insert into r values(3, 3, 2004, 'F', 100000);
alter table rank alter partition girls exchange partition year4 with table r;
select * from rank_1_prt_girls_2_prt_year4;
select * from r;
alter table rank alter partition girls exchange partition year4 with table r;
select * from rank_1_prt_girls_2_prt_year4;
select * from r;
-- Split test
alter table rank alter partition girls split default partition start('2008')
end('2020') into (partition years, partition gfuture);
insert into rank values(4, 4, 2009, 'F', 100);
drop table rank;
drop table r;
-- MPP-4245: remove virtual subpartition templates when we drop the partitioned
-- table
create table bar_p (i int, j int) partition by range(i) subpartition by range(j)
subpartition template(start(1) end(10) every(1)) subpartition by range(i)
subpartition template(start(1) end(10) every(5)) (start(1) end(10));
alter table bar_p alter partition for ('5') alter partition for ('5')
drop partition for ('5');
insert into bar_p values(1, 1);
insert into bar_p values(5, 5);
drop table bar_p;
select parrelid::regclass, * from pg_partition;
select * from pg_partition_rule;
-- MPP-4172
-- should fail
create table ggg (a char(1), b int)
distributed by (b)
partition by range(a)
(
partition aa start ('2006') end ('2009'), partition bb start ('2007') end
('2008')
);
-- MPP-4892 SET SUBPARTITION TEMPLATE
create table mpp4892 (a char, b int, d char)
partition by range (b)
subpartition by list (d)
subpartition template (
subpartition sp1 values ('a'),
subpartition sp2 values ('b'))
(
start (1) end (10) every (1)
);
-- works
alter table mpp4892 add partition p1 end (11);
-- complain about existing template
alter table mpp4892 add partition p3 end (13) (subpartition sp3 values ('c'));
-- remove template
alter table mpp4892 set subpartition template ();
-- should work (because the template is gone)
alter table mpp4892 add partition p3 end (13) (subpartition sp3 values ('c'));
-- complain because the template is already gone
alter table mpp4892 set subpartition template ();
-- should work
alter table mpp4892 set subpartition template (subpartition sp3 values ('c'));
-- should work
alter table mpp4892 add partition p4 end (15);
drop table mpp4892;
-- make sure we do not allow overlapping range intervals
-- should fail
-- unordered elems
create table ttt (t int) partition by range(t) (
partition a start (1) end(10) inclusive,
partition c start(11) end(14),
partition b start(5) end(15)
);
-- should fail, this time it's ordered
create table ttt (t int) partition by range(t) (
partition a start (1) end(10) inclusive,
partition b start(5) end(15),
partition c start(11) end(14)
);
-- should fail
create table ttt (t date) partition by range(t) (
partition a start ('2005-01-01') end('2006-01-01') inclusive,
partition b start('2005-05-01') end('2005-06-11'),
partition c start('2006-01-01') exclusive end('2006-01-10')
);
-- should fail
create table ttt (t char) partition by range(t) (
partition a start('a') end('f'),
partition b start('e') end('g')
);
-- Test locking behaviour. When creating, dropping, querying or adding indexes
-- partitioned tables, we want to lock only the master, not the children.
-- start_ignore
create view locktest as
select coalesce(
case when relname like 'pg_toast%index' then 'toast index'
when relname like 'pg_toast%' then 'toast table'
else relname end, 'dropped table'),
mode,
locktype from
pg_locks l left outer join pg_class c on (l.relation = c.oid),
pg_database d where relation is not null and l.database = d.oid and
l.gp_segment_id = -1 and
d.datname = current_database() order by 1, 3, 2;
-- end_ignore
-- Partitioned table with toast table
begin;
-- creation
create table g (i int, t text) partition by range(i)
(start(1) end(10) every(1));
select * from locktest;
commit;
-- drop
begin;
drop table g;
select * from locktest;
commit;
-- AO table (ao segments, block directory won't exist after create)
begin;
-- creation
create table g (i int, t text, n numeric)
with (appendonly = true)
partition by list(i)
(values(1), values(2), values(3));
select * from locktest;
commit;
begin;
-- add a little data
insert into g values(1), (2), (3);
insert into g values(1), (2), (3);
insert into g values(1), (2), (3);
insert into g values(1), (2), (3);
insert into g values(1), (2), (3);
select * from locktest;
commit;
-- drop
begin;
drop table g;
select * from locktest;
commit;
-- Indexing
create table g (i int, t text) partition by range(i)
(start(1) end(10) every(1));
begin;
create index g_idx on g(i);
select * from locktest;
commit;
-- test select locking
begin;
select * from g where i = 1;
select * from locktest;
commit;
begin;
-- insert locking
insert into g values(3, 'f');
select * from locktest;
commit;
-- delete locking
begin;
delete from g where i = 4;
select * from locktest;
commit;
-- drop index
begin;
drop table g;
select * from locktest;
commit;
-- MPP-5159
-- Should fail -- missing partition spec and subpartition template follows the
-- partition declaration.
CREATE TABLE list_sales (trans_id int, date date, amount
decimal(9,2), region text)
DISTRIBUTED BY (trans_id)
PARTITION BY LIST (region)
SUBPARTITION TEMPLATE
( SUBPARTITION usa VALUES ('usa'),
SUBPARTITION asia VALUES ('asia'),
SUBPARTITION europe VALUES ('europe')
);
-- MPP-5185
-- Should work
CREATE TABLE rank (id int, rank int, year date, gender
char(1)) DISTRIBUTED BY (id, gender, year)
partition by list (gender)
subpartition by range (year)
subpartition template (
start (date '2001-01-01'),
start (date '2002-01-01'),
start (date '2003-01-01'),
start (date '2004-01-01'),
start (date '2005-01-01')
)
(
partition boys values ('M'),
partition girls values ('F')
);
alter table rank set subpartition template ();
-- nothing there
select * from pg_partition_templates;
alter table rank set subpartition template (default subpartition def2);
-- def2 is there
select * from pg_partition_templates;
alter table rank set subpartition template (default subpartition def2);
-- Should still be there
select * from pg_partition_templates;
drop table rank;
-- MPP-5397
-- should be able to add partition after dropped a col
create table mpp_5397 (a int, b int, c int)
distributed by (a)
partition by range (b)
(partition a1 start (0) end (5),
partition a2 end (10),
partition a3 end(15));
alter table mpp_5397 drop column c;
-- should work now
alter table mpp_5397 add partition z end (20);
drop table mpp_5397;
-- MPP-4987 -- make sure we can't damage a partitioning configuration
-- MPP-8405: disallow OIDS on partitioned tables
create table rank (i int, j int) with oids partition by range(j) (start(1) end(10)
every(1));
-- this works
create table rank (i int, j int) partition by range(j) (start(1) end(10)
every(1));
-- should all fail
alter table rank_1_prt_1 no inherit rank;
create table rank2(like rank);
alter table rank_1_prt_1 inherit rank2;
alter table rank_1_prt_1 alter column i type bigint;
alter table rank_1_prt_1 set without oids;
alter table rank_1_prt_1 drop constraint rank_1_prt_1_check;
alter table rank add partition ppo end (22) with (oids = true);
drop table rank, rank2;
-- MPP-5831, type cast in SPLIT
CREATE TABLE sg_cal_event_silvertail_hour (
caldt date NOT NULL,
calhr smallint NOT NULL,
ip character varying(128),
transactionid character varying(32),
transactiontime timestamp(2) without time zone
)
WITH (appendonly=true, compresslevel=5)
distributed by (ip) PARTITION BY RANGE(transactiontime)
(
PARTITION "P2009041607"
START ('2009-04-16 07:00:00'::timestamp without time zone)
END ('2009-04-16 08:00:00'::timestamp without time zone),
PARTITION "P2009041608"
START ('2009-04-16 08:00:00'::timestamp without time zone)
END ('2009-04-16 09:00:00'::timestamp without time zone),
DEFAULT PARTITION st_default
);
ALTER TABLE SG_CAL_EVENT_SILVERTAIL_HOUR SPLIT DEFAULT PARTITION
START ('2009-04-29 07:00:00'::timestamp) INCLUSIVE END ('2009-04-29
08:00:00'::timestamp) EXCLUSIVE INTO ( PARTITION P2009042907 ,
PARTITION st_default );
drop table sg_cal_event_silvertail_hour;
-- Make sure we inherit master's storage settings
create table foo_p (i int, j int, k text)
with (appendonly = true, compresslevel = 5)
partition by range(j) (start(1) end(10) every(1), default partition def);
insert into foo_p select i, i+1, repeat('fooo', 9000) from generate_series(1, 100) i;
alter table foo_p split default partition start (10) end(20)
into (partition p10_20, partition def);
select reloptions from pg_class where relname = 'foo_p_1_prt_p10_20';
select count(distinct k) from foo_p;
drop table foo_p;
create table foo_p (i int, j int, k text)
partition by range(j) (start(1) end(10) every(1), default partition def
with(appendonly = true));
insert into foo_p select i, i+1, repeat('fooo', 9000) from generate_series(1, 100) i;
alter table foo_p split default partition start (10) end(20)
into (partition p10_20, partition def);
select reloptions from pg_class where relname = 'foo_p_1_prt_p10_20';
select reloptions from pg_class where relname = 'foo_p_1_prt_def';
select count(distinct k) from foo_p;
drop table foo_p;
-- MPP-5878 - display correct partition boundary
create table mpp5878 (a int, b char, d char)
partition by list (b,d)
(
values (('a','b'),('c','d')),
values (('e','f'),('g','h'))
);
select partitionlistvalues from pg_partitions where tablename like 'mpp5878%';
select partitionboundary from pg_partitions where tablename like 'mpp5878%';
drop table mpp5878;
-- MPP-5941: work with many levels of templates
CREATE TABLE mpp5941 (a int, b date, c char,
d char(4), e varchar(20), f timestamp)
partition by range (b)
subpartition by list (a)
subpartition template (
subpartition l1 values (1,2,3,4,5),
subpartition l2 values (6,7,8,9,10) ),
subpartition by list (e)
subpartition template (
subpartition ll1 values ('Engineering'),
subpartition ll2 values ('QA') ),
subpartition by list (c)
subpartition template (
subpartition lll1 values ('M'),
subpartition lll2 values ('F') )
(
start (date '2007-01-01')
end (date '2010-01-01') every (interval '1 year')
);
-- just truncate for fun to see that everything is there
alter table mpp5941 alter partition for ('2008-01-01')
alter partition for (1) alter partition for ('QA')
truncate partition for ('M');
alter table mpp5941 alter partition for ('2008-01-01')
alter partition for (1) truncate partition for ('QA');
alter table mpp5941 alter partition for ('2008-01-01')
truncate partition for (1);
alter table mpp5941 truncate partition for ('2008-01-01') ;
truncate table mpp5941;
-- now look at the templates that we have
select tablename, partitionname, partitionlevel from pg_partition_templates
where tablename = 'mpp5941';
-- clear level 1
alter table mpp5941 set subpartition template ();
select tablename, partitionname, partitionlevel from pg_partition_templates
where tablename = 'mpp5941';
-- clear level 2
alter table mpp5941 alter partition for ('2008-01-01')
set subpartition template ();
select tablename, partitionname, partitionlevel from pg_partition_templates
where tablename = 'mpp5941';
-- clear level 3
alter table mpp5941 alter partition for ('2008-01-01')
alter partition for (1)
set subpartition template ();
select tablename, partitionname, partitionlevel from pg_partition_templates
where tablename = 'mpp5941';
-- no level 4 (error)
alter table mpp5941 alter partition for ('2008-01-01')
alter partition for (1) alter partition for ('QA')
set subpartition template ();
select tablename, partitionname, partitionlevel from pg_partition_templates
where tablename = 'mpp5941';
-- no level 5 (error)
alter table mpp5941 alter partition for ('2008-01-01')
alter partition for (1) alter partition for ('QA')
alter partition for ('M')
set subpartition template ();
select tablename, partitionname, partitionlevel from pg_partition_templates
where tablename = 'mpp5941';
-- set level 1 (error, because no templates for level 2, 3)
alter table mpp5941 set subpartition template (
subpartition l1 values (1,2,3,4,5),
subpartition l2 values (6,7,8,9,10) );
-- MPP-5992 - add deep templates correctly
-- Note: need to re-add the templates from deepest to shallowest,
-- because adding a template has a dependency on the existence of the
-- deeper template.
-- set level 3
alter table mpp5941 alter partition for ('2008-01-01')
alter partition for (1)
set subpartition template (
subpartition lll1 values ('M'),
subpartition lll2 values ('F') );
select tablename, partitionname, partitionlevel from pg_partition_templates
where tablename = 'mpp5941';
-- set level 2
alter table mpp5941 alter partition for ('2008-01-01')
set subpartition template (
subpartition ll1 values ('Engineering'),
subpartition ll2 values ('QA') );
select tablename, partitionname, partitionlevel from pg_partition_templates
where tablename = 'mpp5941';
-- set level 1
alter table mpp5941 set subpartition template (
subpartition l1 values (1,2,3,4,5),
subpartition l2 values (6,7,8,9,10) );
select tablename, partitionname, partitionlevel from pg_partition_templates
where tablename = 'mpp5941';
drop table mpp5941;
-- MPP-5984
CREATE TABLE partsupp ( ps_partkey integer,
ps_suppkey integer, ps_availqty integer,
ps_supplycost numeric, ps_comment character varying(199) )
PARTITION BY RANGE(ps_partkey)
(
partition nnull start (300) end (NULL)
);
CREATE TABLE partsupp ( ps_partkey integer,
ps_suppkey integer, ps_availqty integer,
ps_supplycost numeric, ps_comment character varying(199) )
PARTITION BY RANGE(ps_partkey)
(
partition nnull start (300) end (NULL::int)
);
CREATE TABLE partsupp ( ps_partkey integer,
ps_suppkey integer, ps_availqty integer,
ps_supplycost numeric, ps_comment character varying(199) )
PARTITION BY RANGE(ps_partkey)
(
partition p1 start(1) end(10),
partition p2 start(10) end(20),
default partition def
);
alter table partsupp split partition p2 at (NULL);
alter table partsupp split default partition start(null) end(200);
drop table partsupp;
CREATE TABLE partsupp ( ps_partkey integer,
ps_suppkey integer, ps_availqty integer,
ps_supplycost numeric, ps_comment character varying(199) )
PARTITION BY RANGE(ps_partkey)
(
partition nnull start (300) end (400)
);
alter table partsupp add partition foo start(500) end(NULL);
drop table partsupp;
--MPP-6240
CREATE TABLE supplier_hybrid_part(
S_SUPPKEY INTEGER,
S_NAME CHAR(25),
S_ADDRESS VARCHAR(40),
S_NATIONKEY INTEGER, S_PHONE CHAR(15),
S_ACCTBAL decimal,
S_COMMENT VARCHAR(101)
)
partition by range (s_suppkey)
subpartition by list (s_nationkey) subpartition template (
values('22','21','17'),
values('6','11','1','7','16','2') WITH (checksum=false,appendonly=true,blocksize=1171456, compresslevel=3),
values('18','20'),
values('9','23','13') WITH (checksum=true,appendonly=true,blocksize=1335296,compresslevel=7),
values('0','3','12','15','14','8','4','24','19','10','5')
)
(
partition p1 start('1') end('10001') every(10000)
);
select pg_get_partition_def('supplier_hybrid_part'::regclass, true);
drop table supplier_hybrid_part;
-- MPP-3544
-- Domain
create domain domainvarchar varchar(5);
create domain domainnumeric numeric(8,2);
create domain domainint4 int4;
create domain domaintext text;
-- Test tables using domains
-- list
create table basictest1
( testint4 domainint4
, testtext domaintext
, testvarchar domainvarchar
, testnumeric domainnumeric
)
partition by LIST(testvarchar)
(
partition aa values ('aaaaa'),
partition bb values ('bbbbb'),
partition cc values ('ccccc')
);
alter table basictest1 add partition dd values('ddddd');
insert into basictest1 values(1, 1, 'ddddd', 1);
insert into basictest1 values(1, 1, 'ccccc', 1);
insert into basictest1 values(1, 1, 'bbbbb', 1);
insert into basictest1 values(1, 1, 'aaaaa', 1);
drop table basictest1;
--range
create table basictest1 (testnumeric domainint4)
partition by range(testnumeric)
(start(1) end(10) every(5));
insert into basictest1 values(1);
insert into basictest1 values(2);
alter table basictest1 add partition ff start(10) end(20);
insert into basictest1 values(10);
drop table basictest1;
drop domain domainvarchar, domainnumeric, domainint4, domaintext;
-- Test index inheritance with partitions
create table ti (i int not null, j int)
distributed by (i)
partition by range (j)
(start(1) end(3) every(1));
create unique index ti_pkey on ti(i);
select * from pg_indexes where schemaname = 'public' and tablename like 'ti%';
create index ti_j_idx on ti using bitmap(j);
select * from pg_indexes where schemaname = 'public' and tablename like 'ti%';
alter table ti add partition p3 start(3) end(10);
select * from pg_indexes where schemaname = 'public' and tablename like 'ti%';
alter table ti split partition p3 at (7) into (partition pnew1, partition pnew2);
select * from pg_indexes where schemaname = 'public' and tablename like 'ti%';
drop table ti;
-- MPP-6611, make sure rename works with default partitions
create table it (i int, j int) partition by range(i)
subpartition by range(j) subpartition template(start(1) end(10) every(5))
(start(1) end(3) every(1));
alter table it rename to newit;
select schemaname, tablename from pg_tables where schemaname = 'public' and tablename like 'newit%';
alter table newit add default partition def;
select schemaname, tablename from pg_tables where schemaname = 'public' and tablename like 'newit%';
alter table newit rename to anotherit;
select schemaname, tablename from pg_tables where schemaname = 'public' and tablename like
'anotherit%';
drop table anotherit;
-- test table constraint inheritance
create table it (i int) distributed by (i) partition by range(i) (start(1) end(3) every(1));
select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%';
alter table it add primary key(i);
select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%';
drop table it;
-- MPP-6297: test special WITH(tablename=...) syntax for dump/restore
-- original table was:
-- PARTITION BY RANGE(l_commitdate)
-- (
-- PARTITION p1
-- START ('1992-01-31'::date) END ('1995-04-30'::date)
-- EVERY ('1 year 1 mon'::interval)
-- )
-- dump used to give a definition like this:
-- without the WITH(tablename=...), the vagaries of EVERY arithmetic
-- create >3 partitions
CREATE TABLE mpp6297 ( l_orderkey bigint,
l_commitdate date
)
distributed BY (l_orderkey) PARTITION BY RANGE(l_commitdate)
(
PARTITION p1_1 START ('1992-01-31'::date) END ('1993-02-28'::date)
EVERY ('1 year 1 mon'::interval)
,
PARTITION p1_2 START ('1993-02-28'::date) END ('1994-03-31'::date)
EVERY ('1 year 1 mon'::interval)
,
PARTITION p1_3 START ('1994-03-31'::date) END ('1995-04-30'::date)
EVERY ('1 year 1 mon'::interval)
);
-- should be a single partition def for p1 from 1/31 to 4/30, but
-- shows 4 partitions instead
select partitiontablename, partitionname,
partitionrangestart, partitionrangeend, partitioneveryclause
from pg_partitions
where tablename like 'mpp6297%' order by partitionrank;
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
drop table mpp6297;
-- when WITH(tablename=...) is specified, the EVERY is stored as an
-- attribute, but not expanded into additional partitions
CREATE TABLE mpp6297 ( l_orderkey bigint,
l_commitdate date
)
distributed BY (l_orderkey) PARTITION BY RANGE(l_commitdate)
(
PARTITION p1_1 START ('1992-01-31'::date) END ('1993-02-28'::date)
EVERY ('1 year 1 mon'::interval)
WITH (tablename='mpp6297_1_prt_p1_1'),
PARTITION p1_2 START ('1993-02-28'::date) END ('1994-03-31'::date)
EVERY ('1 year 1 mon'::interval)
WITH (tablename='mpp6297_1_prt_p1_2'),
PARTITION p1_3 START ('1994-03-31'::date) END ('1995-04-30'::date)
EVERY ('1 year 1 mon'::interval)
WITH (tablename='mpp6297_1_prt_p1_3')
);
-- should be a single partition def for p1 from 1/31 to 4/30, as intended
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
drop table mpp6297;
-- more with basic cases
create table mpp6297
(a int,
b int)
partition by range (b)
(
start (1) end (10) every (1),
end (11)
);
-- note that the partition from 10 to 11 is *not* part of every
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
alter table mpp6297 drop partition for (rank(3));
-- note that the every clause splits into two parts: 1-3 and 4-10
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
-- this isn't legal (but it would be nice)
alter table mpp6297 add partition start (3) end (4) every (1);
-- this is legal but it doesn't fix the EVERY clause
alter table mpp6297 add partition start (3) end (4) ;
-- note that the every clause is still splits into two parts: 1-3 and
-- 4-10, because the new partition from 3 to 4 doesn't have an EVERY
-- attribute
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
drop table mpp6297;
-- similarly, we can merge adjacent EVERY clauses if they match
create table mpp6297
(a int,
b int)
partition by range (b)
(
start (1) end (5) every (1),
start (5) end (10) every (1)
);
-- note that there is only a single every from 1-10
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
drop table mpp6297;
-- we cannot merge adjacent EVERY clauses if inclusivity/exclusivity is wrong
create table mpp6297
(a int,
b int)
partition by range (b)
(
start (1) end (5) every (1),
start (5) exclusive end (10) every (1)
);
-- two every clauses for this case
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
drop table mpp6297;
-- more fun with inclusivity/exclusivity (normal case)
create table mpp6297
(a int,
b int)
partition by range (b)
(
start (1) inclusive end (10) exclusive every (1)
);
-- note that inclusive and exclusive attributes aren't listed here (because
-- default behavior)
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
drop table mpp6297;
-- more fun with inclusivity/exclusivity (abnormal case)
create table mpp6297
(a int,
b int)
partition by range (b)
(
start (1) exclusive end (10) inclusive every (1)
);
-- note that inclusive and exclusive attributes are listed here
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
alter table mpp6297 drop partition for (rank(3));
-- note that the every clause splits into two parts: 1-3 and 4-10 (and
-- inclusive/exclusive is listed correctly)
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
drop table mpp6297;
-- we cannot merge adjacent EVERY clauses, even though the
-- inclusivity/exclusivity matches, because it is different from the
-- normal start inclusive/end exclusive
create table mpp6297
(a int,
b int)
partition by range (b)
(
start (1) end (5) inclusive every (1),
start (5) exclusive end (10) every (1)
);
-- two every clauses for this case
select
pg_get_partition_def(
(select oid from pg_class
where relname='mpp6297')::pg_catalog.oid, true);
drop table mpp6297;
-- MPP-6589: SPLITting an "open" ended partition (ie, no start or end)
CREATE TABLE mpp6589a
(
id bigint,
day_dt date
)
DISTRIBUTED BY (id)
PARTITION BY RANGE(day_dt)
(
PARTITION p20090312 END ('2009-03-12'::date)
);
select pg_get_partition_def('mpp6589a'::regclass,true);
-- should work
ALTER TABLE mpp6589a
SPLIT PARTITION p20090312 AT( '20090310' )
INTO( PARTITION p20090309, PARTITION p20090312_tmp);
select pg_get_partition_def('mpp6589a'::regclass,true);
drop table mpp6589a;
CREATE TABLE mpp6589i(a int, b int)
partition by range (b) (start (1) end (3));
select pg_get_partition_def('mpp6589i'::regclass,true);
-- should fail (overlap)
ALTER TABLE mpp6589i ADD PARTITION start (2);
-- should fail (overlap) (not a real overlap, but a "point" hole)
ALTER TABLE mpp6589i ADD PARTITION start (3) exclusive;
-- should work - make sure can add an open-ended final partition
ALTER TABLE mpp6589i ADD PARTITION start (3);
select pg_get_partition_def('mpp6589i'::regclass,true);
DROP TABLE mpp6589i;
-- test open-ended SPLIT
CREATE TABLE mpp6589b
(
id bigint,
day_dt date
)
DISTRIBUTED BY (id)
PARTITION BY RANGE(day_dt)
(
PARTITION p20090312 START ('2008-03-12'::date)
);
select pg_get_partition_def('mpp6589b'::regclass,true);
-- should work
ALTER TABLE mpp6589b
SPLIT PARTITION p20090312 AT( '20090310' )
INTO( PARTITION p20090309, PARTITION p20090312_tmp);
select pg_get_partition_def('mpp6589b'::regclass,true);
drop table mpp6589b;
-- MPP-7191, MPP-7193: partitioned tables - fully-qualify storage type
-- if not specified (and not a template)
CREATE TABLE mpp5992 (a int, b date, c char,
d char(4), e varchar(20), f timestamp)
WITH (orientation=column,appendonly=true)
partition by range (b)
subpartition by list (a)
subpartition template (
subpartition l1 values (1,2,3,4,5),
subpartition l2 values (6,7,8,9,10) ),
subpartition by list (e)
subpartition template (
subpartition ll1 values ('Engineering'),
subpartition ll2 values ('QA') ),
subpartition by list (c)
subpartition template (
subpartition lll1 values ('M'),
subpartition lll2 values ('F') )
(
start (date '2007-01-01')
end (date '2010-01-01') every (interval '1 year')
);
-- Delete subpartition template
alter table mpp5992 alter partition for ('2008-01-01')
set subpartition template ();
alter table mpp5992 alter partition for ('2008-01-01')
alter partition for (1)
set subpartition template ();
alter table mpp5992 set subpartition template ();
-- Add subpartition template
alter table mpp5992 alter partition for ('2008-01-01')
alter partition for (1)
set subpartition template ( subpartition lll1 values ('M'),
subpartition lll2 values ('F'));
alter table mpp5992 alter partition for ('2008-01-01')
set subpartition template (
subpartition ll1 values ('Engineering'),
subpartition ll2 values ('QA')
);
alter table mpp5992
set subpartition template (subpartition l1 values (1,2,3,4,5),
subpartition l2 values (6,7,8,9,10) );
alter table mpp5992
set subpartition template (subpartition l1 values (1,2,3),
subpartition l2 values (4,5,6), subpartition l3 values (7,8,9,10));
select * from pg_partition_templates where tablename='mpp5992';
-- Now we can add a new partition
alter table mpp5992
add partition foo1
start (date '2011-01-01')
end (date '2012-01-01'); -- should inherit from parent storage option
alter table mpp5992
add partition foo2
start (date '2012-01-01')
end (date '2013-01-01') WITH (orientation=column,appendonly=true);
alter table mpp5992
add partition foo3
start (date '2013-01-01') end (date '2014-01-01') WITH (appendonly=true);
select pg_get_partition_def('mpp5992'::regclass,true, true);
drop table mpp5992;
-- MPP-10223: split subpartitions
CREATE TABLE MPP10223pk
(
rnc VARCHAR(100),
wbts VARCHAR(100),
axc VARCHAR(100),
vptt VARCHAR(100),
vcct VARCHAR(100),
agg_level CHAR(5),
period_start_time TIMESTAMP WITH TIME ZONE,
load_time TIMESTAMP WITH TIME ZONE DEFAULT now(),
interval INTEGER,
totcellsegress double precision,
totcellsingress double precision,
CONSTRAINT "axc_vcct1_atmvcct_pk_test2"
PRIMARY KEY (rnc,wbts,axc,vptt,vcct,agg_level,period_start_time)
)
DISTRIBUTED BY (rnc,wbts,axc,vptt,vcct)
PARTITION BY LIST (AGG_LEVEL)
SUBPARTITION BY RANGE (PERIOD_START_TIME)
(
PARTITION min15part VALUES ('15min')
(
SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE,
SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE
END (date '2999-12-31') EXCLUSIVE
),
PARTITION hourpart VALUES ('hour')
(
SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE,
SUBPARTITION P20100623 START (date '2010-06-23') INCLUSIVE,
SUBPARTITION P20100624 START (date '2010-06-24') INCLUSIVE,
SUBPARTITION P20100625 START (date '2010-06-25') INCLUSIVE,
SUBPARTITION P20100626 START (date '2010-06-26') INCLUSIVE,
SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE,
SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE
END (date '2999-12-31') EXCLUSIVE
),
PARTITION daypart VALUES ('day')
(
SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE,
SUBPARTITION P20100623 START (date '2010-06-23') INCLUSIVE,
SUBPARTITION P20100624 START (date '2010-06-24') INCLUSIVE,
SUBPARTITION P20100625 START (date '2010-06-25') INCLUSIVE,
SUBPARTITION P20100626 START (date '2010-06-26') INCLUSIVE,
SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE,
SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE
END (date '2999-12-31') EXCLUSIVE
)
);
-- MPP-10421: works -- can re-use name for non-DEFAULT partitions, and
-- primary key problems fixed
ALTER TABLE MPP10223pk
ALTER PARTITION min15part
SPLIT PARTITION P_FUTURE AT ('2010-06-25')
INTO (PARTITION P20010101, PARTITION P_FUTURE);
drop table mpp10223pk;
-- rebuild the table without a primary key
CREATE TABLE MPP10223
(
rnc VARCHAR(100),
wbts VARCHAR(100),
axc VARCHAR(100),
vptt VARCHAR(100),
vcct VARCHAR(100),
agg_level CHAR(5),
period_start_time TIMESTAMP WITH TIME ZONE,
load_time TIMESTAMP WITH TIME ZONE DEFAULT now(),
interval INTEGER,
totcellsegress double precision,
totcellsingress double precision
)
DISTRIBUTED BY (rnc,wbts,axc,vptt,vcct)
PARTITION BY LIST (AGG_LEVEL)
SUBPARTITION BY RANGE (PERIOD_START_TIME)
(
PARTITION min15part VALUES ('15min')
(
SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE,
SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE
END (date '2999-12-31') EXCLUSIVE
),
PARTITION hourpart VALUES ('hour')
(
SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE,
SUBPARTITION P20100623 START (date '2010-06-23') INCLUSIVE,
SUBPARTITION P20100624 START (date '2010-06-24') INCLUSIVE,
SUBPARTITION P20100625 START (date '2010-06-25') INCLUSIVE,
SUBPARTITION P20100626 START (date '2010-06-26') INCLUSIVE,
SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE,
SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE
END (date '2999-12-31') EXCLUSIVE
),
PARTITION daypart VALUES ('day')
(
SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE,
SUBPARTITION P20100623 START (date '2010-06-23') INCLUSIVE,
SUBPARTITION P20100624 START (date '2010-06-24') INCLUSIVE,
SUBPARTITION P20100625 START (date '2010-06-25') INCLUSIVE,
SUBPARTITION P20100626 START (date '2010-06-26') INCLUSIVE,
SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE,
SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE
END (date '2999-12-31') EXCLUSIVE
)
);
-- this works
ALTER TABLE MPP10223
ALTER PARTITION min15part
SPLIT PARTITION P_FUTURE AT ('2010-06-25')
INTO (PARTITION P20010101, PARTITION P_FUTURE2);
select pg_get_partition_def('mpp10223'::regclass,true);
drop table mpp10223;
-- simpler version
create table mpp10223b (a int, b int , d int)
partition by range (b)
subpartition by range (d)
(partition p1 start (1) end (10)
(subpartition sp2 start (20) end (30)));
-- MPP-10421: allow re-use sp2 for non-DEFAULT partition
alter table mpp10223b alter partition p1
split partition for (rank(1) ) at (25)
into (partition sp2, partition sp3);
select pg_get_partition_def('mpp10223b'::regclass,true);
drop table mpp10223b;
-- MPP-10480: dump templates (but don't use "foo")
create table MPP10480 (a int, b int, d int)
partition by range (b)
subpartition by range(d)
subpartition template (start (1) end (10) every (1))
(start (20) end (30) every (1));
select pg_get_partition_template_def('MPP10480'::regclass, true, true);
drop table MPP10480;
-- MPP-10421: fix SPLIT of partitions with PRIMARY KEY constraint/indexes
CREATE TABLE mpp10321a
(
rnc VARCHAR(100),
wbts VARCHAR(100),
axc VARCHAR(100),
vptt VARCHAR(100),
vcct VARCHAR(100),
agg_level CHAR(5),
period_start_time TIMESTAMP WITH TIME ZONE,
load_time TIMESTAMP WITH TIME ZONE DEFAULT now(),
interval INTEGER,
totcellsegress double precision,
totcellsingress double precision,
CONSTRAINT "mpp10321a_pk"
PRIMARY KEY (rnc,wbts,axc,vptt,vcct,agg_level,period_start_time)
)
DISTRIBUTED BY (rnc,wbts,axc,vptt,vcct)
PARTITION BY LIST (AGG_LEVEL)
SUBPARTITION BY RANGE (PERIOD_START_TIME)
(
PARTITION min15part VALUES ('15min')
(
SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE,
SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE
END (date '2999-12-31') EXCLUSIVE
),
PARTITION hourpart VALUES ('hour')
(
SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE,
SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE
END (date '2999-12-31') EXCLUSIVE
)
);
ALTER TABLE mpp10321a
ALTER PARTITION min15part
SPLIT PARTITION P_FUTURE AT ('2010-06-25')
INTO (PARTITION P20010101, PARTITION P_FUTURE);
DROP TABLE mpp10321a;
-- test for default partition with boundary spec
create table bhagp_range (a int, b int)
distributed by (a)
partition by range (b)
(
default partition x
start (0) inclusive
end (2) exclusive
every (1)
);
create table bhagp_list (a int, b int)
distributed by (a)
partition by list (b)
(
default partition x
values (1,2)
);
-- more coverage tests
-- bad partition by type
create table cov1 (a int, b int)
distributed by (a)
partition by (b)
(
start (1) end (10) every (1)
);
-- bad partition by type
create table cov1 (a int, b int)
distributed by (a)
partition by funky (b)
(
start (1) end (10) every (1)
);
drop table cov1;
create table cov1 (a int, b int)
distributed by (a)
partition by range (b)
(
start (1) end (10) every (1)
);
-- syntax error
alter table cov1 drop partition for (funky(1));
-- no rank for default
alter table cov1 drop default partition for (rank(1));
-- no default
alter table cov1 drop default partition;
-- cannot add except by name
alter table cov1 add partition for (rank(1));
-- bad template
alter table cov1 set subpartition template (values (1,2) (values (2,3)));
-- create and drop default partition in one statement!
alter table cov1 add default partition def1, drop default partition;
drop table cov1;
set gp_enable_hash_partitioned_tables = true;
-- not hash
create table cov1 (a int, b int)
distributed by (a)
partition by range (b)
partitions 3
(
start (1) end (10) every (1)
);
-- not hash
create table cov1 (a int, b int, d int)
distributed by (a)
partition by range (b)
subpartition by range (d)
subpartitions 3
(
start (1) end (10) every (1)
);
set gp_enable_hash_partitioned_tables = false;
-- not hash
create table cov1 (a int, b int)
distributed by (a)
partition by range (b)
partitions 3
(
start (1) end (10) every (1)
);
-- not hash
create table cov1 (a int, b int, d int)
distributed by (a)
partition by range (b)
subpartition by range (d)
subpartitions 3
(
start (1) end (10) every (1)
);
-- legal?!?!
create table cov1 (a int, b int)
distributed by (a)
partition by range (b)
(
start () end(2)
);
-- no start, just end!
select * from pg_partitions where tablename = 'cov1';
drop table cov1;
-- every 5 (1) now disallowed...
create table cov1 (a int, b int)
distributed by (a)
partition by range (b)
(
start (1) end(20) every 5 (1)
);
drop table if exists cov1;
create table cov1 (a int, b int)
distributed by (a)
partition by list (b)
(
partition p1 values (1,2,3,4,5,6,7,8)
);
-- bad split
alter table cov1 split partition p1 at (5,50);
-- good split
alter table cov1 split partition p1 at (5,6,7)
into (partition p1, partition p2);
select partitionboundary from pg_partitions where tablename = 'cov1';
drop table cov1;
-- MPP-11120
-- ADD PARTITION didn't explicitly specify the distribution policy in the
-- CreateStmt distributedBy field and as such we followed the behaviour encoded
-- in transformDistributedBy(). Unfortunately, it chooses to set the
-- distribution policy to that of the primary key if the distribution policy
-- is not explicitly set.
create table test_table (
a int,
b int,
c int,
primary key (a,b,c)
)
distributed by (a)
partition by range (b)
(
default partition default_partition,
partition p1 start (1) end (2)
);
insert into test_table values(1,2,3);
select * from test_table; -- expected: (1,2,3)
delete from test_table where a=1 and b=2 and c=3; -- this should delete the row in test_table
select * from test_table; -- expected, no rows
insert into test_table values(1,2,3); -- reinsert data
-- all partitions should have same distribution policy
select relname, attrnums as distribution_attributes from
gp_distribution_policy p, pg_class c
where p.localoid = c.oid and relname like 'test_table%' order by p.localoid;
alter table test_table split default partition
start (3)
end (4)
into (partition p2, partition default_partition);
select relname, attrnums as distribution_attributes from
gp_distribution_policy p, pg_class c where p.localoid = c.oid and
relname like 'test_table%' order by p.localoid;
delete from test_table where a=1 and b=2 and c=3; -- this should delete the row in test_table
select * from test_table; -- expected, no rows! But we see the row. Wrong results!
alter table test_table drop partition default_partition;
alter table test_table add partition foo start(10) end(20);
select relname, attrnums as distribution_attributes from
gp_distribution_policy p, pg_class c where p.localoid = c.oid and
relname like 'test_table%' order by p.localoid;
drop table test_table;
-- MPP-6979: EXCHANGE partitions - fix namespaces if they differ
-- new schema
create schema mpp6979dummy;
create table mpp6979part(a int, b int)
partition by range(b)
(
start (1) end (10) every (1)
);
-- append-only table in new schema
create table mpp6979dummy.mpp6979tab(like mpp6979part) with (appendonly=true);
-- check that table and all parts in public schema
select schemaname, tablename, partitionschemaname, partitiontablename
from pg_partitions
where tablename like ('mpp6979%');
-- note that we have heap partitions in public, and ao table in mpp6979dummy
select nspname, relname, relstorage from pg_class pc, pg_namespace ns
where
pc.relnamespace=ns.oid and relname like ('mpp6979%');
-- exchange the partition with the ao table.
-- Now we have an ao partition and mpp6979tab is heap!
alter table mpp6979part exchange partition for (rank(1))
with table mpp6979dummy.mpp6979tab;
-- after the exchange, all partitions are still in public
select schemaname, tablename, partitionschemaname, partitiontablename
from pg_partitions
where tablename like ('mpp6979%');
-- the rank 1 partition is ao, but still in public, and
-- table mpp6979tab is now heap, but still in mpp6979dummy
select nspname, relname, relstorage from pg_class pc, pg_namespace ns
where
pc.relnamespace=ns.oid and relname like ('mpp6979%');
drop table mpp6979part;
drop table mpp6979dummy.mpp6979tab;
drop schema mpp6979dummy;
-- MPP-7898:
drop table if exists r cascade; --ignore
drop table if exists s cascade; --ignore
create table s
(a int, b text)
distributed by (a);
insert into s values
(1, 'one');
-- Try to create a table that mixes inheritance and partitioning.
-- Correct behavior: ERROR
create table r
( c int, d int)
inherits (s)
partition by range(d)
(
start (0)
end (2)
every (1)
);
-- If (incorrectly) the previous statement works, the next one is
-- likely to fail with in unexpected internal error. This is residual
-- issue MPP-7898.
insert into r values
(0, 'from r', 0, 0);
drop table if exists s cascade; --ignore
drop table if exists r cascade; --ignore
create table r
( a int, b text, c int, d int )
distributed by (a)
partition by range(d)
(
start (0)
end (2)
every (1)
);
insert into r values
(0, 'from r', 0, 0);
create table s
( a int, b text, c int, d int )
distributed by (a);
insert into s values
(1, 'from s', 555, 555);
create table t
( )
inherits (s)
distributed by (a);
insert into t values
(0, 'from t', 666, 666);
-- Try to exchange in the child and parent.
-- Correct behavior: ERROR in both cases.
alter table r exchange partition for (1) with table t;
alter table r exchange partition for (1) with table s;
drop table t cascade; --ignore
drop table s cascade; --ignore
drop table r cascade; --ignore
-- MPP-7898 end.
-- ( MPP-13750
CREATE TABLE s (id int, date date, amt decimal(10,2), units int)
DISTRIBUTED BY (id)
PARTITION BY RANGE (date)
( START (date '2008-01-01') INCLUSIVE
END (date '2008-01-02') EXCLUSIVE
EVERY (INTERVAL '1 day') );
create index s_i on s(amt)
where (id > 1)
;
create index s_j on s(units)
where (id <= 1)
;
create index s_i_expr on s(log(units));
alter table s add partition s_test
start(date '2008-01-03') end (date '2008-01-05');
alter table s split partition for (date '2008-01-03') at (date '2008-01-04')
into (partition s_test, partition s_test2);
select
relname,
(select count(distinct content) - 1
from gp_segment_configuration) - count(*) as missing,
count(distinct relid) oid_count
from (
select gp_execution_segment(), oid, relname
from gp_dist_random('pg_class')
) seg_class(segid, relid, relname)
where relname ~ '^s_'
group by relname;
drop table s cascade;
-- MPP-13750 )
-- MPP-13806 start
drop table if exists mpp13806;
CREATE TABLE mpp13806 (id int, date date, amt decimal(10,2))
DISTRIBUTED BY (id)
PARTITION BY RANGE (date)
( START (date '2008-01-01') INCLUSIVE
END (date '2008-01-05') EXCLUSIVE
EVERY (INTERVAL '1 day') );
-- Adding unbound partition right before the start used to fail
alter table mpp13806 add partition test end (date '2008-01-01') exclusive;
drop table if exists mpp13806;
CREATE TABLE mpp13806 (id int, date date, amt decimal(10,2))
DISTRIBUTED BY (id)
PARTITION BY RANGE (date)
( START (date '2008-01-01') EXCLUSIVE
END (date '2008-01-05') EXCLUSIVE
EVERY (INTERVAL '1 day') );
-- For good measure, test the opposite case
alter table mpp13806 add partition test end (date '2008-01-01') inclusive;
drop table mpp13806;
-- MPP-13806 end
-- MPP-14471 start
-- No unenforceable PK/UK constraints! (UNIQUE INDEXes still allowed; tested above)
drop table if exists tc cascade;
drop table if exists cc cascade;
drop table if exists at cascade;
create table tc
(a int, b int, c int, primary key(a) )
distributed by (a)
partition by range (b)
(
default partition d,
start (0) inclusive end(100) inclusive every (50)
);
create table cc
(a int primary key, b int, c int)
distributed by (a)
partition by range (b)
(
default partition d,
start (0) inclusive end(100) inclusive every (50)
);
create table at
(a int, b int, c int)
distributed by (a)
partition by range (b)
(
default partition d,
start (0) inclusive end(100) inclusive every (50)
);
alter table at
add primary key (a);
-- MPP-14471 end
-- MPP-17606 (using table "at" from above)
alter table at
alter column b
type numeric;
-- MPP-17606 end
-- MPP-17707 start
create table mpp17707
( d int, p int ,x text)
with (appendonly = true)
distributed by (d)
partition by range (p)
(start (0) end (3) every (2));
-- Create a expression index on the partitioned table
create index idx_abc on mpp17707(upper(x));
-- split partition 1 of table
alter table mpp17707 split partition for (0) at (1)
into (partition x1, partition x2);
-- MPP-17707 end
-- MPP-17814 start
drop table if exists plst2 cascade;
-- positive; bug was that it failed whereas it should succeed
create table plst2
(
a integer not null,
b integer not null,
c integer
)
distributed by (b)
partition by list (a,c)
(
partition p1 values ( (1, 2), (3, 4) ),
partition p2 values ( (5, 6) ),
partition p3 values ( (2, 1) )
);
drop table if exists plst2 cascade;
--negative; test legitimate failure
create table plst2
(
a integer not null,
b integer not null,
c integer
)
distributed by (b)
partition by list (a,c)
(
partition p1 values ( (1, 2), (3, 4) ),
partition p2 values ( (5, 6) ),
partition p3 values ( (1, 2) )
);
-- postive; make sure inner part duplicates are accepted and quietly removed.
drop table if exists plst2;
create table plst2
( a int, b int)
distributed by (a)
partition by list (a, b)
(
partition p0 values ((1,2), (3,4)),
partition p1 values ((4,3), (2,1)),
partition p2 values ((4,4),(5,5),(4,4),(5,5),(4,4),(5,5)),
partition p3 values ((4,5),(5,6))
);
-- positive; make sure legitimate alters work.
alter table plst2 add partition p4 values ((5,4),(6,5));
alter table plst2 add partition p5 values ((7,8),(7,8));
select conrelid::regclass, consrc
from pg_constraint
where conrelid in (
select parchildrelid::regclass
from pg_partition_rule
where paroid in (
select oid
from pg_partition
where parrelid = 'plst2'::regclass
)
);
-- negative; make sure conflicting alters fail.
alter table plst2 add partition p6 values ((7,8),(2,1));
drop table if exists plst2;
-- MPP-17814 end
-- MPP-18441
create table s_heap (i1 int, t1 text, t2 text, i2 int, i3 int, n1 numeric, b1 bool)
partition by list (t1)
(partition abc values('abc0', 'abc1', 'abc2'));
insert into s_heap (t1, i1, i2, i3, n1, b1) select 'abc0', 1, 1, 1, 2.3, true
from generate_series(1, 5);
alter table s_heap drop column t2;
alter table s_heap drop column i3;
-- create co table for exchange
create table s_heap_ex_abc (i1 int, t1 text, f1 float, i2 int, n1 numeric, b1 bool)
WITH (appendonly=true, orientation=column, compresstype=quicklz);
alter table s_heap_ex_abc drop column f1;
insert into s_heap_ex_abc select 1, 'abc1', 2, 2, true from generate_series(1, 5);
-- exchange partition
alter table s_heap exchange partition abc with table s_heap_ex_abc;
alter table s_heap exchange partition abc with table s_heap_ex_abc;
drop table s_heap, s_heap_ex_abc;
-- MPP-18441 end
-- MPP-18443
create table s_heap (i1 int, t1 text, i2 int , i3 int, n1 numeric,b1 bool)
partition by list (t1)
(partition def values('def0', 'def1', 'def2', 'def3', 'def4', 'def5', 'def6', 'def7', 'def8', 'def9'));
insert into s_heap(t1, i1, i2, i3, n1, b1)
select 'def0', 1, 1, 1, 2.3 , true from generate_series(1, 5);
alter table s_heap drop column i3;
create index s_heap_index on s_heap (i2);
alter table s_heap split partition def
at ('def0', 'def1', 'def2', 'def3', 'def4') into (partition def5, partition def0);
select * from s_heap_1_prt_def0;
drop table s_heap;
-- MPP-18443 end
-- MPP-18445
create table s_heap_ao ( i1 int, t1 text, i2 int , i3 int, n1 numeric,b1 bool)
partition by list (t1)
(partition def values('def0', 'def1', 'def2', 'def3', 'def4', 'def5', 'def6', 'def7', 'def8', 'def9')
with (appendonly=true, orientation=row));
insert into s_heap_ao(t1, i1, i2, i3, n1, b1)
select 'def4', 1, 1, 1, 2.3, true from generate_series(1, 2);
insert into s_heap_ao(t1, i1, i2, i3, n1, b1)
select 'def5', 1, 1, 1, 2.3, true from generate_series(1, 2);
alter table s_heap_ao drop column i3;
create index s_heap_ao_index on s_heap_ao (i2);
alter table s_heap_ao split partition def
at ('def0', 'def1', 'def2', 'def3', 'def4') into (partition def5, partition def0);
select * from s_heap_ao_1_prt_def0;
drop table s_heap_ao;
-- MPP-18445 end
-- MPP-18456
create table s_heap_co (i1 int, t1 text, i2 int, i3 int, n1 numeric, b1 bool)
partition by list (t1)
(partition def values('def0', 'def1', 'def2', 'def3', 'def4', 'def5', 'def6', 'def7', 'def8', 'def9')
with (appendonly=true, orientation=column));
insert into s_heap_co(t1, i1, i2, i3, n1, b1)
select 'def4', 1,1, 1, 2.3, true from generate_series(1, 2);
insert into s_heap_co(t1, i1, i2, i3, n1, b1)
select 'def5', 1,1, 1, 2.3, true from generate_series(1, 2);
alter table s_heap_co drop column i3;
create index s_heap_co_index on s_heap_co (i2);
alter table s_heap_co split partition def
at ('def0', 'def1', 'def2', 'def3', 'def4') into (partition def5, partition def0);
select * from s_heap_co_1_prt_def0;
drop table s_heap_co;
-- MPP-18456 end
-- MPP-18457, MPP-18415
CREATE TABLE non_ws_phone_leads (
lead_key integer NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
source_system_lead_id character varying(60) NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_event_type_key smallint NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_site_key integer NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_date_key integer NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_time_key integer NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_phone_number_key integer NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
duration_second smallint NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_program_key smallint NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_call_status_key integer NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_phone_department_set_key smallint NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_phone_channel_set_key smallint NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_phone_provider_key smallint NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768),
dim_phone_ad_set_key smallint NOT NULL ENCODING (compresstype=quicklz,compresslevel=1,blocksize=32768)
)
WITH (appendonly=true, compresstype=quicklz, orientation=column) DISTRIBUTED BY (dim_site_key ,dim_date_key) PARTITION BY RANGE(dim_date_key)
(
PARTITION p_max START (2451545) END (9999999) WITH (tablename='non_ws_phone_leads_1_prt_p_max', orientation=column, appendonly=true )
COLUMN lead_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN source_system_lead_id ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_event_type_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_site_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_date_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_time_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_phone_number_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN duration_second ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_program_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_call_status_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_phone_department_set_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_phone_channel_set_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_phone_provider_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
COLUMN dim_phone_ad_set_key ENCODING (compresstype=quicklz, compresslevel=1, blocksize=32768)
);
INSERT INTO non_ws_phone_leads VALUES (63962490, 'CA6qOEyxOmNJUQC7', 5058, 999901, 2455441, 40435, 999904, 207, 79, 2, 9901, 9901, 1, 9901);
CREATE TABLE dim_phone_numbers (
dim_phone_number_key integer NOT NULL,
media_tracker_description character varying(40) NOT NULL,
formatted_phone_number character varying(20) NOT NULL,
source_system_phone_number_id character varying(100) NOT NULL,
last_modified_date timestamp without time zone NOT NULL
) DISTRIBUTED BY (dim_phone_number_key);
ALTER TABLE ONLY dim_phone_numbers
ADD CONSTRAINT dim_phone_numbers_pk1 PRIMARY KEY (dim_phone_number_key);
INSERT INTO dim_phone_numbers VALUES (999902, 'test', '800-123-4568', '8001234568', '2012-09-25 13:34:35.037637');
INSERT INTO dim_phone_numbers VALUES (999904, 'test', '(800) 123-4570', '8001234570', '2012-09-25 13:34:35.148104');
INSERT INTO dim_phone_numbers VALUES (999903, 'test', '(800) 123-4569', '8001234569', '2012-09-25 13:34:35.093523');
INSERT INTO dim_phone_numbers VALUES (999901, 'test', '(800)123-4567', '8001234567', '2012-09-25 13:34:34.781042');
INSERT INTO dim_phone_numbers SELECT gs.*, dim_phone_numbers.media_tracker_description, dim_phone_numbers.formatted_phone_number, dim_phone_numbers.source_system_phone_number_id, dim_phone_numbers.last_modified_date FROM dim_phone_numbers, generate_series(1,100000) gs WHERE dim_phone_numbers.dim_phone_number_key = 999901;
ANALYZE dim_phone_numbers;
-- Table NON_WS_PHONE_LEADS has two distribution keys
-- Equality condition with constant on one distribution key
-- Redistribute over Append
SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY
FROM NON_WS_PHONE_LEADS PL
LEFT outer JOIN DIM_PHONE_NUMBERS DPN
ON PL.DIM_PHONE_NUMBER_KEY = DPN.DIM_PHONE_NUMBER_KEY
WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7'
AND PL.DIM_DATE_KEY = 2455441;
-- Table NON_WS_PHONE_LEADS has two distribution keys
-- Equality conditions with constants on all distribution keys
-- Redistribute over Append
SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY
FROM NON_WS_PHONE_LEADS PL
LEFT outer JOIN DIM_PHONE_NUMBERS DPN
ON PL.DIM_PHONE_NUMBER_KEY = DPN.DIM_PHONE_NUMBER_KEY
WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7'
AND PL.DIM_DATE_KEY = 2455441
AND PL.dim_site_key = 999901;
-- Table NON_WS_PHONE_LEADS has two distribution keys
-- Broadcast over Append
SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY
FROM NON_WS_PHONE_LEADS PL
JOIN DIM_PHONE_NUMBERS DPN
ON PL.DIM_PHONE_NUMBER_KEY = DPN.DIM_PHONE_NUMBER_KEY
WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7'
AND PL.DIM_DATE_KEY = 2455441
AND PL.dim_site_key = 999901;
-- Join condition uses functions
-- Broadcast over Append
SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY
FROM NON_WS_PHONE_LEADS PL
JOIN DIM_PHONE_NUMBERS DPN
ON PL.DIM_PHONE_NUMBER_KEY + 1 = DPN.DIM_PHONE_NUMBER_KEY + 1
WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7'
AND PL.DIM_DATE_KEY = 2455441
AND PL.dim_site_key = 999901;
-- Equality condition with constant on one distribution key
-- Redistribute over Append
-- Accessing a varchar in the SELECT clause should cause a SIGSEGV
SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY, source_system_lead_id
FROM NON_WS_PHONE_LEADS PL
LEFT outer JOIN DIM_PHONE_NUMBERS DPN
ON PL.DIM_PHONE_NUMBER_KEY = DPN.DIM_PHONE_NUMBER_KEY
WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7'
AND PL.DIM_DATE_KEY = 2455441;
DROP TABLE non_ws_phone_leads;
DROP TABLE dim_phone_numbers;
-- Equality condition with a constant expression on one distribution key
drop table if exists foo_p;
drop table if exists bar;
create table foo_p( a int, b int, k int, t text, p int) distributed by (a,b) partition by range(p) ( start(0) end(10) every (2), default partition other);
create table bar( a int, b int, k int, t text, p int) distributed by (a);
insert into foo_p select i, i % 10, i , i || 'SOME NUMBER SOME NUMBER', i % 10 from generate_series(1, 1000) i;
insert into bar select i % 7, i % 6, i % 9, i || 'SOME NUMBER', i % 4 from generate_series(1, 100) i;
insert into bar select i % 7, i % 6, i % 9, i || 'SOME NUMBER', i % 4 from generate_series(1, 10000) i;
insert into bar select i % 7, i % 6, i % 9, i || 'SOME NUMBER', i % 4 from generate_series(1, 10000) i;
analyze foo_p;
analyze bar;
set optimizer_segments = 3;
set optimizer_nestloop_factor = 1.0;
explain select foo_p.b, foo_p.t from foo_p left outer join bar on foo_p.a = bar.k where foo_p.t is not null and foo_p.a = (array[1])[1];
reset optimizer_segments;
drop table if exists foo_p;
drop table if exists bar;
-- MPP-18457, MPP-18415 end
-- MPP-18359
drop view if exists redundantly_named_part cascade;
create view redundantly_named_part(tableid, partid, partname) as
with
dups(paroid, partname) as
(
select paroid, parname
from pg_partition_rule
where parname is not null
group by paroid, parname
having count(*) > 1
),
parts(tableid, partid, paroid, partname) as
(
select p.parrelid, r.parchildrelid, r.paroid, r.parname
from pg_partition p, pg_partition_rule r
where not p.paristemplate and
p.oid = r.paroid
)
select p.tableid::regclass, p.partid::regclass, p.partname
from parts p, dups d
where
p.paroid = d.paroid and
p.partname = d.partname;
drop table if exists pnx;
create table pnx
(x int , y text)
distributed randomly
partition by list (y)
(
partition a values ('x1', 'x2'),
partition c values ('x3', 'x4')
);
insert into pnx values
(1,'x1'),
(2,'x2'),
(3,'x3'),
(4,'x4');
select tableoid::regclass, *
from pnx;
alter table pnx
split partition a at ('x1')
into (partition b, partition c);
select *
from redundantly_named_part;
select tableoid::regclass, *
from pnx;
select tableoid::regclass, *
from pnx
where y = 'x1';
select tableoid::regclass, *
from pnx
where x = 1;
drop table if exists pxn;
create table pxn
(x int , y text)
distributed randomly
partition by list (y)
(
partition a values ('x1', 'x2'),
partition c values ('x3', 'x4')
);
insert into pxn values
(1,'x1'),
(2,'x2'),
(3,'x3'),
(4,'x4');
select tableoid::regclass, *
from pxn;
alter table pxn
split partition a at ('x1')
into (partition c, partition b);
select *
from redundantly_named_part;
select tableoid::regclass, *
from pxn;
select tableoid::regclass, *
from pxn
where y = 'x2';
select tableoid::regclass, *
from pxn
where x = 2;
drop table if exists pxn;
create table pxn
(x int , y int)
distributed randomly
partition by range (y)
(
partition a start (0) end (10),
partition c start (11) end (20)
);
insert into pxn values
(4,4),
(9,9),
(14,14),
(19,19);
select tableoid::regclass, *
from pxn;
alter table pxn
split partition a at (5)
into (partition b, partition c);
select *
from redundantly_named_part;
select tableoid::regclass, *
from pxn;
select tableoid::regclass, *
from pxn
where y = 4;
select tableoid::regclass, *
from pxn
where x = 4;
drop table if exists pxn;
create table pxn
(x int , y int)
distributed randomly
partition by range (y)
(
partition a start (0) end (10),
partition c start (11) end (20)
);
insert into pxn values
(4,4),
(9,9),
(14,14),
(19,19);
select tableoid::regclass, *
from pxn;
alter table pxn
split partition a at (5)
into (partition c, partition b);
select *
from redundantly_named_part;
select tableoid::regclass, *
from pxn;
select tableoid::regclass, *
from pxn
where y = 9;
select tableoid::regclass, *
from pxn
where x = 9;
-- MPP-18359 end
-- MPP-19105
-- Base partitions with trailing dropped columns
drop table if exists t;
create table t (
a int,
b int,
c char,
d varchar(50)
) distributed by (c)
partition by range (a)
(
partition p1 start(1) end(5),
partition p2 start(5)
);
-- Drop column
alter table t drop column d;
-- Alter table split partition
alter table t split partition for(1) at (2) into (partition p11, partition p22);
insert into t values(1,2,'a');
select * from t;
-- END MPP-19105
reset optimizer_nestloop_factor;
-- Test split default partition while per tuple memory context is reset
-- Origin GPDB PR: https://github.com/greenplum-db/gpdb/pull/866
drop table if exists test_split_part cascade;
CREATE TABLE test_split_part ( log_id int NOT NULL, f_array int[] NOT NULL)
DISTRIBUTED BY (log_id)
PARTITION BY RANGE(log_id)
(
START (1::int) END (100::int) EVERY (5),
PARTITION "old" START (101::int) END (201::int),
DEFAULT PARTITION other_log_ids
);
insert into test_split_part (log_id , f_array) select id, '{10}' from generate_series(1,1000) id;
ALTER TABLE test_split_part SPLIT DEFAULT PARTITION START (201) INCLUSIVE END (301) EXCLUSIVE INTO (PARTITION "new", DEFAULT PARTITION);