blob: 670ecfe653ce59ff540fad0a484c394fbec90ec9 [file] [log] [blame]
set optimizer_print_missing_stats = off;
--
-- This test case covers ALTER functionality for AOCS relations.
--
--
-- Switching on these gucs may be helpful in the event of failures.
--
-- set Debug_appendonly_print_storage_headers=true;
-- set Debug_appendonly_print_datumstream=true;
--
drop schema if exists aocs_addcol cascade;
NOTICE: schema "aocs_addcol" does not exist, skipping
create schema aocs_addcol;
set search_path=aocs_addcol,public;
create table addcol1 (a int) with (appendonly=true, orientation = column)
distributed by (a);
-- create three varblocks
insert into addcol1 select i from generate_series(-10,5)i;
insert into addcol1 select i from generate_series(6,15)i;
insert into addcol1 select i from generate_series(21,30)i;
select count(*) from addcol1;
count
-------
36
(1 row)
-- basic scenario with small content vablocks in new as well as existing column.
alter table addcol1
add column b varchar default 'I am in a small content varblock';
-- verification on master catalog
-- Moreover, gp_toolkit schema is not populated in regression database
-- select segno,column_num,physical_segno,tupcount,modcount,state
-- from gp_toolkit.__gp_aocsseg(aocs_oid('addcol1')) order by segno,column_num;
-- select after alter
select b from addcol1 where a < 8 and a > 2;
b
----------------------------------
I am in a small content varblock
I am in a small content varblock
I am in a small content varblock
I am in a small content varblock
I am in a small content varblock
(5 rows)
-- update and delete post alter should work
update addcol1 set b = 'new value' where a < 10 and a > 0;
select * from addcol1 where a < 8 and a > 3;
a | b
---+-----------
5 | new value
7 | new value
4 | new value
6 | new value
(4 rows)
delete from addcol1 where a > 25 or a < -5;
select count(*) from addcol1;
count
-------
26
(1 row)
-- vacuum creates a new appendonly segment, leaving the original
-- segment active with eof=0.
vacuum addcol1;
-- alter table with one empty and one non-empty appendonly segment.
alter table addcol1 add column c float default 1.2;
select * from addcol1 where a < 8 and a > 3;
a | b | c
---+-----------+-----
5 | new value | 1.2
7 | new value | 1.2
4 | new value | 1.2
6 | new value | 1.2
(4 rows)
-- insert should result in two appendonly segments, each having eof > 0.
insert into addcol1
select i, i::text, i*22/7::float
from generate_series(31,40)i;
-- alter table with more than one non-empty appendonly segments.
alter table addcol1 add column d int default 20;
select a,c,d from addcol1 where a > 9 and a < 15 order by a;
a | c | d
----+-----+----
10 | 1.2 | 20
11 | 1.2 | 20
12 | 1.2 | 20
13 | 1.2 | 20
14 | 1.2 | 20
(5 rows)
-- try inserting after alter
insert into addcol1 select i, 'abc', 22*i/7, -i from generate_series(1,10)i;
-- add columns with compression (dense and bulk dense content varblocks)
alter table addcol1
add column e float default to_char((22/7::float), '9.99999999999999')::float encoding (compresstype=RLE_TYPE),
add column f int default 20 encoding (compresstype=zlib);
select * from addcol1 where a < 2 and a > -4 order by a,c;
a | b | c | d | e | f
----+----------------------------------+-----+----+------------------+----
-3 | I am in a small content varblock | 1.2 | 20 | 3.14285714285714 | 20
-2 | I am in a small content varblock | 1.2 | 20 | 3.14285714285714 | 20
-1 | I am in a small content varblock | 1.2 | 20 | 3.14285714285714 | 20
0 | I am in a small content varblock | 1.2 | 20 | 3.14285714285714 | 20
1 | new value | 1.2 | 20 | 3.14285714285714 | 20
1 | abc | 3 | -1 | 3.14285714285714 | 20
(6 rows)
select a,f from addcol1 where a > 20 and a < 25 order by a,c;
a | f
----+----
21 | 20
22 | 20
23 | 20
24 | 20
(4 rows)
-- add column with existing compressed column (dense content)
create table addcol2 (a int encoding (compresstype=zlib))
with (appendonly=true, orientation=column)
distributed by (a);
insert into addcol2 select i/17 from generate_series(-10000,10000)i;
insert into addcol2 select i from generate_series(10001, 50000)i;
alter table addcol2 add column b varchar
default 'hope I end up on a magnetic disk some day'
encoding (compresstype=RLE_TYPE, blocksize=8192);
-- select after add column
select * from addcol2 where a > 9995 and a < 10006 order by a;
a | b
-------+-------------------------------------------
10001 | hope I end up on a magnetic disk some day
10002 | hope I end up on a magnetic disk some day
10003 | hope I end up on a magnetic disk some day
10004 | hope I end up on a magnetic disk some day
10005 | hope I end up on a magnetic disk some day
(5 rows)
-- add column with existing RLE compressed column (bulk dense content)
create table addcol3 (a int encoding (compresstype=RLE_TYPE, compresslevel=2))
with (appendonly=true, orientation=column)
distributed by (a);
insert into addcol3 select 10 from generate_series(1, 30000);
insert into addcol3 select -10 from generate_series(1, 20000);
insert into addcol3 select
case when i < 100000 then 1
when i >= 100000 and i < 500000 then 2
when i >=500000 and i < 1000000 then 3
end
from generate_series(-1000,999999)i;
alter table addcol3 add column b float
default 22/7::float encoding (compresstype=RLE_TYPE, compresslevel=2);
-- add column with null default
alter table addcol3 add column c varchar default null;
select count(b) from addcol3;
count
---------
1051000
(1 row)
select count(c) from addcol3;
count
-------
0
(1 row)
-- verification on master catalog
-- select segno,column_num,physical_segno,tupcount,modcount,state
-- from gp_toolkit.__gp_aocsseg(aocs_oid('addcol3')) order by segno,column_num;
-- insert after add column with null default
insert into addcol3 select i, 22*i/7, 'a non-null value'
from generate_series(1,100)i;
select count(*) from addcol3;
count
---------
1051100
(1 row)
-- verification on master catalog
-- select segno,column_num,physical_segno,tupcount,modcount,state
-- from gp_toolkit.__gp_aocsseg(aocs_oid('addcol3')) order by segno,column_num;
-- start with a new table, with two varblocks
create table addcol4 (a int, b float)
with (appendonly=true, orientation=column)
distributed by (a);
insert into addcol4 select i, 31/i from generate_series(1, 20)i;
insert into addcol4 select -i, 37/i from generate_series(1, 20)i;
select count(*) from addcol4;
count
-------
40
(1 row)
-- multiple alter subcommands (add column, drop column)
alter table addcol4
add column c varchar default null encoding (compresstype=zlib),
drop column b,
add column d date default date('2014-05-01')
encoding (compresstype=RLE_TYPE, compresslevel=2);
select * from addcol4 where a > 5 and a < 10 order by a;
a | c | d
---+---+------------
6 | | 05-01-2014
7 | | 05-01-2014
8 | | 05-01-2014
9 | | 05-01-2014
(4 rows)
-- verification on master catalog
-- select segno, column_num, physical_segno, tupcount, modcount, state
-- from gp_toolkit.__gp_aocsseg(aocs_oid('addcol4')) order by segno,column_num;
-- TODO: multiple subcommands (add column, add constraint, alter type)
-- block directory
create index i4a on addcol4 (a);
alter table addcol4
add column e varchar default 'wow' encoding (compresstype=zlib);
-- enforce index scan so that block directory is used
set enable_seqscan=off;
-- index scan after adding new column
select * from addcol4 where a > 5 and a < 10 order by a;
a | c | d | e
---+---+------------+-----
6 | | 05-01-2014 | wow
7 | | 05-01-2014 | wow
8 | | 05-01-2014 | wow
9 | | 05-01-2014 | wow
(4 rows)
create table addcol5 (a int, b float)
with (appendonly=true, orientation=column)
distributed by (a);
create index i5a on addcol5(a);
insert into addcol5
select i, 22*i/7 from generate_series(-10,10)i;
insert into addcol5
select i, 22*i/7 from generate_series(11,20)i;
insert into addcol5
select i, 22*i/7 from generate_series(21,30)i;
alter table addcol5 add column c int default 1;
-- insert after adding new column
insert into addcol5
select i, 22*i/7, 311/i from generate_series(31,35)i;
-- index scan after adding new column
set enable_seqscan=off;
select * from addcol5 where a > 25 order by a,b;
a | b | c
----+-----+----
26 | 81 | 1
27 | 84 | 1
28 | 88 | 1
29 | 91 | 1
30 | 94 | 1
31 | 97 | 10
32 | 100 | 9
33 | 103 | 9
34 | 106 | 9
35 | 110 | 8
(10 rows)
-- firstRowNum of the first block starts with a value greater than 1
-- (first insert was aborted).
create table addcol6 (a int, b int)
with (appendonly=true, orientation=column) distributed by (a);
begin;
insert into addcol6 select i,i from generate_series(1,10)i;
-- abort the first insert, still should advance gp_fastsequence for this
-- relation.
SELECT objmod, last_sequence, gp_segment_id from gp_dist_random('gp_fastsequence') WHERE objid
IN (SELECT segrelid FROM pg_appendonly WHERE relid IN (SELECT oid FROM pg_class
WHERE relname='addcol6'));
objmod | last_sequence | gp_segment_id
--------+---------------+---------------
0 | 0 | 1
1 | 100 | 1
0 | 0 | 2
1 | 100 | 2
0 | 0 | 0
1 | 100 | 0
(6 rows)
abort;
-- check gp_fastsequence remains advanced.
SELECT objmod, last_sequence, gp_segment_id from gp_dist_random('gp_fastsequence') WHERE objid
IN (SELECT segrelid FROM pg_appendonly WHERE relid IN (SELECT oid FROM pg_class
WHERE relname='addcol6'));
objmod | last_sequence | gp_segment_id
--------+---------------+---------------
0 | 0 | 1
1 | 100 | 1
0 | 0 | 2
1 | 100 | 2
0 | 0 | 0
1 | 100 | 0
(6 rows)
insert into addcol6 select i,i/2 from generate_series(1,20)i;
alter table addcol6 add column c float default 1.2;
select a,c from addcol6 where b > 5 order by a;
a | c
----+-----
12 | 1.2
13 | 1.2
14 | 1.2
15 | 1.2
16 | 1.2
17 | 1.2
18 | 1.2
19 | 1.2
20 | 1.2
(9 rows)
-- Lets validate after alter gp_fastsequence reflects correctly.
SELECT objmod, last_sequence, gp_segment_id from gp_dist_random('gp_fastsequence') WHERE objid
IN (SELECT segrelid FROM pg_appendonly WHERE relid IN (SELECT oid FROM pg_class
WHERE relname='addcol6'));
objmod | last_sequence | gp_segment_id
--------+---------------+---------------
0 | 0 | 0
1 | 200 | 0
0 | 0 | 1
1 | 200 | 1
0 | 0 | 2
1 | 200 | 2
(6 rows)
-- add column with default value as sequence
alter table addcol6 add column d serial;
-- select, insert, update after 'add column'
select c,d from addcol6 where d > 15 order by d;
c | d
-----+----
1.2 | 16
1.2 | 17
1.2 | 18
1.2 | 19
1.2 | 20
(5 rows)
insert into addcol6 select i, i, 71/i from generate_series(21,30)i;
select count(*) from addcol6;
count
-------
30
(1 row)
update addcol6 set b = 0, c = 0 where d > 15;
select count(*) from addcol6 where b = 0 and c = 0;
count
-------
15
(1 row)
-- partitioned table tests
create table addcol7 (
timest character varying(6),
user_id numeric(16,0) not null,
tag1 smallint,
tag2 varchar(2))
with (appendonly=true, orientation=column, compresslevel=5, oids=false)
distributed by (user_id)
partition by list(timest) (
partition part201202 values('201202')
with (appendonly=true, orientation=column, compresslevel=5),
partition part201203 values('201203')
with (appendonly=true, orientation=column, compresslevel=5));
insert into addcol7 select '201202', 100*i, i, 'a'
from generate_series(1,10)i;
insert into addcol7 select '201203', 101*i, i, 'b'
from generate_series(11,20)i;
alter table addcol7 add column new1 float default 1.2;
-- select, insert post alter
select * from addcol7 where tag1 > 7 and tag1 < 13 order by tag1;
timest | user_id | tag1 | tag2 | new1
--------+---------+------+------+------
201202 | 800 | 8 | a | 1.2
201202 | 900 | 9 | a | 1.2
201202 | 1000 | 10 | a | 1.2
201203 | 1111 | 11 | b | 1.2
201203 | 1212 | 12 | b | 1.2
(5 rows)
insert into addcol7 select '201202', 100*i, i, i::text, 22*i/7
from generate_series(21,30)i;
insert into addcol7 select '201203', 101*i, i, (i+2)::text, 22*i/7
from generate_series(31,40)i;
-- add new partition and a new column in the same alter table command
alter table addcol7
add partition part201204 values('201204')
with (appendonly=true, compresslevel=5),
add column new2 varchar default 'abc';
-- insert, select, update, delete and vacuum post alter
insert into addcol7 values
('201202', 101, 1, 'p1', 3/5::float, 'newcol2'),
('201202', 102, 2, 'p1', 1/6::float, 'newcol2'),
('201202', 103, 3, 'p1', 22/7::float, 'newcol2'),
('201203', 201, 4, 'p2', 1/3::float, 'newcol2'),
('201203', 202, 5, 'p2', null, null),
('201203', 203, 6, 'p2', null, null),
('201204', 301, 7, 'p3', 22/7::float, 'newcol2'),
('201204', 302, 8, 'p3', null, null),
('201204', 303, 9, 'p3', null, null);
select * from addcol7 where tag2 like 'p%' order by user_id;
timest | user_id | tag1 | tag2 | new1 | new2
--------+---------+------+------+---------------------+---------
201202 | 101 | 1 | p1 | 0.6 | newcol2
201202 | 102 | 2 | p1 | 0.16666666666666666 | newcol2
201202 | 103 | 3 | p1 | 3.142857142857143 | newcol2
201203 | 201 | 4 | p2 | 0.3333333333333333 | newcol2
201203 | 202 | 5 | p2 | |
201203 | 203 | 6 | p2 | |
201204 | 301 | 7 | p3 | 3.142857142857143 | newcol2
201204 | 302 | 8 | p3 | |
201204 | 303 | 9 | p3 | |
(9 rows)
update addcol7 set new1 = 0, tag1 = -1 where tag2 like 'p%';
delete from addcol7 where new2 is null;
vacuum addcol7;
select * from addcol7 where tag2 like 'p%' order by user_id;
timest | user_id | tag1 | tag2 | new1 | new2
--------+---------+------+------+------+---------
201202 | 101 | -1 | p1 | 0 | newcol2
201202 | 102 | -1 | p1 | 0 | newcol2
201202 | 103 | -1 | p1 | 0 | newcol2
201203 | 201 | -1 | p2 | 0 | newcol2
201204 | 301 | -1 | p3 | 0 | newcol2
(5 rows)
create table addcol8 (a int, b varchar(10), c int, d int)
with (appendonly=true, orientation=column) distributed by (a);
insert into addcol8 select i, 'abc'||i, i, i from generate_series(1,10)i;
alter table addcol8
alter column b type varchar(20),
add column e float default 1,
drop column c;
select * from addcol8 order by a;
a | b | d | e
----+-------+----+---
1 | abc1 | 1 | 1
2 | abc2 | 2 | 1
3 | abc3 | 3 | 1
4 | abc4 | 4 | 1
5 | abc5 | 5 | 1
6 | abc6 | 6 | 1
7 | abc7 | 7 | 1
8 | abc8 | 8 | 1
9 | abc9 | 9 | 1
10 | abc10 | 10 | 1
(10 rows)
\d addcol8
Table "aocs_addcol.addcol8"
Column | Type | Collation | Nullable | Default
--------+-----------------------+-----------+----------+---------
a | integer | | |
b | character varying(20) | | |
d | integer | | |
e | double precision | | | 1
Checksum: t
Distributed by: (a)
-- try renaming table and see if stuff still works
alter table addcol1 rename to addcol1_renamed;
alter table addcol1_renamed add column new_column int default 10;
alter table addcol1_renamed alter column new_column set not null;
alter table addcol1_renamed add column new_column2 int not null; -- should fail
ERROR: column "new_column2" of relation "addcol1_renamed" contains null values (seg0 127.0.1.1:7002 pid=2286449)
select count(*) from addcol1_renamed;
count
-------
46
(1 row)
alter table addcol1_renamed drop column new_column;
alter table addcol1_renamed rename to addcol1;
-- try renaming columns and see if stuff still works
alter table addcol1 rename column f to f_renamed;
alter table addcol1 alter column f_renamed set default 10;
select pg_get_expr(adbin, adrelid) from pg_attrdef pdef, pg_attribute pattr
where pdef.adrelid='addcol1'::regclass and pdef.adrelid=pattr.attrelid and pdef.adnum=pattr.attnum and pattr.attname='f_renamed';
pg_get_expr
-------------
10
(1 row)
insert into addcol1 values (999);
select a, f_renamed from addcol1 where a = 999;
a | f_renamed
-----+-----------
999 | 10
(1 row)
-- try dropping and adding back the column
alter table addcol1 drop column f_renamed;
select attname from pg_attribute where attrelid='addcol1'::regclass and attname='f_renamed';
attname
---------
(0 rows)
alter table addcol1 add column f_renamed int default 20;
select a, f_renamed from addcol1 where a = 999;
a | f_renamed
-----+-----------
999 | 20
(1 row)
-- try altering statistics of a column
alter table addcol1 alter column f_renamed set statistics 10000;
select attstattarget from pg_attribute where attrelid = 'aocs_addcol.addcol1'::regclass and attname = 'f_renamed';
attstattarget
---------------
10000
(1 row)
set client_min_messages to error;
alter table addcol1 alter column f_renamed set statistics 10001; -- should limit to 10000 and give warning
set client_min_messages to notice;
select attstattarget from pg_attribute where attrelid = 'aocs_addcol.addcol1'::regclass and attname = 'f_renamed';
attstattarget
---------------
10000
(1 row)
-- test alter distribution policy
alter table addcol1 set distributed randomly;
alter table addcol1 set distributed by (a);
alter table addcol1 add constraint tcheck check (a is not null);
-- test changing the storage type of a column
alter table addcol1 alter column f_renamed type varchar(7);
alter table addcol1 alter column f_renamed set storage plain;
select attname, attstorage from pg_attribute where attrelid='addcol1'::regclass and attname='f_renamed';
attname | attstorage
-----------+------------
f_renamed | p
(1 row)
alter table addcol1 alter column f_renamed set storage main;
select attname, attstorage from pg_attribute where attrelid='addcol1'::regclass and attname='f_renamed';
attname | attstorage
-----------+------------
f_renamed | m
(1 row)
alter table addcol1 alter column f_renamed set storage external;
select attname, attstorage from pg_attribute where attrelid='addcol1'::regclass and attname='f_renamed';
attname | attstorage
-----------+------------
f_renamed | e
(1 row)
alter table addcol1 alter column f_renamed set storage extended;
select attname, attstorage from pg_attribute where attrelid='addcol1'::regclass and attname='f_renamed';
attname | attstorage
-----------+------------
f_renamed | x
(1 row)
-- test some aocs partition table altering
create table alter_aocs_part_table (a int, b int) with (appendonly=true, orientation=column) distributed by (a)
partition by range(b) (start (1) end (5) exclusive every (1), default partition foo);
insert into alter_aocs_part_table values (generate_series(1,10), generate_series(1,10));
alter table alter_aocs_part_table drop partition for (1);
alter table alter_aocs_part_table split default partition start(6) inclusive end(7) exclusive;
alter table alter_aocs_part_table split default partition start(6) inclusive end(8) exclusive;
ERROR: partition "alter_aocs_part_table_1_prt_11" would overlap partition "alter_aocs_part_table_1_prt_1"
alter table alter_aocs_part_table split default partition start(7) inclusive end(8) exclusive;
\d+ alter_aocs_part_table
Partitioned table "aocs_addcol.alter_aocs_part_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Compression Type | Compression Level | Block Size | Description
--------+---------+-----------+----------+---------+---------+--------------+------------------+-------------------+------------+-------------
a | integer | | | | plain | | none | 0 | 32768 |
b | integer | | | | plain | | none | 0 | 32768 |
Partition key: RANGE (b)
Partitions: alter_aocs_part_table_1_prt_1 FOR VALUES FROM (6) TO (7),
alter_aocs_part_table_1_prt_11 FOR VALUES FROM (7) TO (8),
alter_aocs_part_table_1_prt_3 FOR VALUES FROM (2) TO (3),
alter_aocs_part_table_1_prt_4 FOR VALUES FROM (3) TO (4),
alter_aocs_part_table_1_prt_5 FOR VALUES FROM (4) TO (5),
alter_aocs_part_table_1_prt_foo DEFAULT
Distributed by: (a)
create table alter_aocs_ao_table (a int, b int) with (appendonly=true) distributed by (a);
insert into alter_aocs_ao_table values (2,2);
alter table alter_aocs_part_table exchange partition for (2) with table alter_aocs_ao_table;
create table alter_aocs_heap_table (a int, b int) distributed by (a);
insert into alter_aocs_heap_table values (3,3);
alter table alter_aocs_part_table exchange partition for (3) with table alter_aocs_heap_table;
-- Test truncating and exchanging partition and then rolling back
begin work;
create table alter_aocs_ptable_exchange (a int, b int) with (appendonly=true, orientation=column) distributed by (a);
insert into alter_aocs_ptable_exchange values (3,3), (3,3), (3,3);
alter table alter_aocs_part_table truncate partition for (3);
select count(*) from alter_aocs_part_table;
count
-------
8
(1 row)
alter table alter_aocs_part_table exchange partition for (3) with table alter_aocs_ptable_exchange;
select count(*) from alter_aocs_part_table;
count
-------
11
(1 row)
rollback work;
select count(*) from alter_aocs_part_table;
count
-------
9
(1 row)
-- Test AO hybrid partitioning scheme (range and list) w/ subpartitions
create table aocs_multi_level_part_table (date date, region text, region1 text, amount decimal(10,2))
with (appendonly=true, orientation=column, compresstype=zlib, compresslevel=1)
partition by range(date) subpartition by list(region) (
partition part1 start(date '2008-01-01') end(date '2009-01-01')
(subpartition usa values ('usa'), subpartition asia values ('asia'), default subpartition def),
partition part2 start(date '2009-01-01') end(date '2010-01-01')
(subpartition usa values ('usa'), subpartition asia values ('asia')));
-- insert some data
insert into aocs_multi_level_part_table values ('2008-02-02', 'usa', 'Texas', 10.05), ('2008-03-03', 'asia', 'China', 1.01);
insert into aocs_multi_level_part_table values ('2009-02-02', 'usa', 'Utah', 10.05), ('2009-03-03', 'asia', 'Japan', 1.01);
-- add a partition that is not a default partition
alter table aocs_multi_level_part_table add partition part3 start(date '2010-01-01') end(date '2012-01-01')
with (appendonly=true, orientation=column)
(subpartition usa values ('usa'), subpartition asia values ('asia'), default subpartition def);
-- Add default partition (defaults to heap storage unless set with AO)
alter table aocs_multi_level_part_table add default partition yearYYYY (default subpartition def);
SELECT am.amname FROM pg_class c LEFT JOIN pg_am am ON (c.relam = am.oid)
WHERE c.relname = 'aocs_multi_level_part_table_1_prt_yearyyyy_2_prt_def';
amname
-----------
ao_column
(1 row)
alter table aocs_multi_level_part_table drop partition yearYYYY;
alter table aocs_multi_level_part_table add default partition yearYYYY with (appendonly=true, orientation=column) (default subpartition def);
SELECT am.amname FROM pg_class c LEFT JOIN pg_am am ON (c.relam = am.oid)
WHERE c.relname = 'aocs_multi_level_part_table_1_prt_yearyyyy_2_prt_def';
amname
-----------
ao_column
(1 row)
-- index on atts 1, 4
create index ao_mlp_idx on aocs_multi_level_part_table(date, amount);
select indexname from pg_indexes where tablename='aocs_multi_level_part_table';
indexname
------------
ao_mlp_idx
(1 row)
alter index ao_mlp_idx rename to ao_mlp_idx_renamed;
select indexname from pg_indexes where tablename='aocs_multi_level_part_table';
indexname
--------------------
ao_mlp_idx_renamed
(1 row)
-- truncate partitions until table is empty
select * from aocs_multi_level_part_table;
date | region | region1 | amount
------------+--------+---------+--------
02-02-2008 | usa | Texas | 10.05
02-02-2009 | usa | Utah | 10.05
03-03-2008 | asia | China | 1.01
03-03-2009 | asia | Japan | 1.01
(4 rows)
truncate aocs_multi_level_part_table_1_prt_part1_2_prt_asia;
select * from aocs_multi_level_part_table;
date | region | region1 | amount
------------+--------+---------+--------
02-02-2008 | usa | Texas | 10.05
02-02-2009 | usa | Utah | 10.05
03-03-2009 | asia | Japan | 1.01
(3 rows)
alter table aocs_multi_level_part_table truncate partition for ('02-02-2008');
select * from aocs_multi_level_part_table;
date | region | region1 | amount
------------+--------+---------+--------
02-02-2009 | usa | Utah | 10.05
03-03-2009 | asia | Japan | 1.01
(2 rows)
alter table aocs_multi_level_part_table alter partition part2 truncate partition usa;
select * from aocs_multi_level_part_table;
date | region | region1 | amount
------------+--------+---------+--------
03-03-2009 | asia | Japan | 1.01
(1 row)
alter table aocs_multi_level_part_table truncate partition part2;
select * from aocs_multi_level_part_table;
date | region | region1 | amount
------+--------+---------+--------
(0 rows)
-- drop column in the partition table
select count(*) from pg_attribute where attrelid='aocs_multi_level_part_table'::regclass and attname = 'region1';
count
-------
1
(1 row)
alter table aocs_multi_level_part_table drop column region1;
select count(*) from pg_attribute where attrelid='aocs_multi_level_part_table'::regclass and attname = 'region1';
count
-------
0
(1 row)
-- splitting top partition of a multi-level partition should not work
alter table aocs_multi_level_part_table split partition part3 at (date '2011-01-01') into (partition part3, partition part4);
ERROR: cannot SPLIT PARTITION for relation "aocs_multi_level_part_table" -- partition has children
HINT: Try splitting the child partitions.
-- Test case: alter table add column with FirstRowNumber > 1
create table aocs_first_row_number (a int, b int) with (appendonly=true, orientation=column);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
create index i_aocs_first_row_number on aocs_first_row_number using btree(b);
-- abort an insert transaction to generate a first row number > 1
begin;
insert into aocs_first_row_number select i,i from generate_series(1,100)i;
abort;
insert into aocs_first_row_number select i,i from generate_series(101, 200)i;
alter table aocs_first_row_number add column c int default -1;
-- At this point, block directory entry for column c starts from first row number = 1,
-- which is not the same as first row number for columns a and b.
-- correct result using base table
set enable_seqscan=on;
set enable_indexscan=off;
select c from aocs_first_row_number where b = 10;
c
---
(0 rows)
set enable_seqscan=off;
set enable_indexscan=on;
-- Used to have wrong result using index: this select returns 1 tuple when no tuples should be returned.
-- expect: same result as scanning the base table
select c from aocs_first_row_number where b = 10;
c
---
(0 rows)
reset enable_seqscan;
reset enable_indexscan;
-- cleanup so as not to affect other installcheck tests
-- (e.g. column_compression).
set client_min_messages='WARNING';
drop schema aocs_addcol cascade;
-- Test case: alter column on a table after reorganize
-- For an AOCS table with columns using rle_type compression, the
-- implementation of 'reorganize' at 62d66c063fd did not set compression type
-- for dropped columns. This led to an error 'Bad datum stream Dense block
-- version'.
create table aocs_with_compress(a smallint, b smallint, c smallint) with (appendonly=true, orientation=column, compresstype=rle_type);
insert into aocs_with_compress values (1, 1, 1), (2, 2, 2);
alter table aocs_with_compress drop column b;
alter table aocs_with_compress set with (reorganize=true);
-- The following operation must not fail
alter table aocs_with_compress alter column c type integer;
-- test case: alter AOCS table add column, the preference of the storage setting is: the encoding clause > table setting > gp_default_storage_options
CREATE TABLE aocs_alter_add_col(a int) WITH (appendonly=true, orientation=column, compresstype=rle_type, compresslevel=4, blocksize=65536);
SET gp_default_storage_options ='compresstype=zlib, compresslevel=2';
-- use statement encoding
ALTER TABLE aocs_alter_add_col ADD COLUMN b int ENCODING(compresstype=zlib, compresslevel=3, blocksize=16384);
-- use table setting
ALTER TABLE aocs_alter_add_col ADD COLUMN c int;
RESET gp_default_storage_options;
-- use table setting
ALTER TABLE aocs_alter_add_col ADD COLUMN d int;
\d+ aocs_alter_add_col
Table "public.aocs_alter_add_col"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Compression Type | Compression Level | Block Size | Description
--------+---------+-----------+----------+---------+---------+--------------+------------------+-------------------+------------+-------------
a | integer | | | | plain | | rle_type | 4 | 65536 |
b | integer | | | | plain | | zlib | 3 | 16384 |
c | integer | | | | plain | | rle_type | 4 | 65536 |
d | integer | | | | plain | | rle_type | 4 | 65536 |
Checksum: t
Distributed by: (a)
Options: compresstype=rle_type, compresslevel=4, blocksize=65536
DROP TABLE aocs_alter_add_col;
CREATE TABLE aocs_alter_add_col_no_compress(a int) WITH (appendonly=true, orientation=column);
SET gp_default_storage_options ='compresstype=zlib, compresslevel=2, blocksize=8192';
-- use statement encoding
ALTER TABLE aocs_alter_add_col_no_compress ADD COLUMN b int ENCODING(compresstype=rle_type, compresslevel=3, blocksize=16384);
-- use gp_default_storage_options
ALTER TABLE aocs_alter_add_col_no_compress ADD COLUMN c int;
RESET gp_default_storage_options;
-- use default value
ALTER TABLE aocs_alter_add_col_no_compress ADD COLUMN d int;
\d+ aocs_alter_add_col_no_compress
Table "public.aocs_alter_add_col_no_compress"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Compression Type | Compression Level | Block Size | Description
--------+---------+-----------+----------+---------+---------+--------------+------------------+-------------------+------------+-------------
a | integer | | | | plain | | none | 0 | 32768 |
b | integer | | | | plain | | rle_type | 3 | 16384 |
c | integer | | | | plain | | zlib | 2 | 32768 |
d | integer | | | | plain | | none | 0 | 32768 |
Checksum: t
Distributed by: (a)
DROP TABLE aocs_alter_add_col_no_compress;
-- test case: ensure reorganize keep default compresstype, compresslevel and blocksize table options
CREATE TABLE aocs_alter_add_col_reorganize(a int) WITH (appendonly=true, orientation=column, compresstype=rle_type, compresslevel=4, blocksize=65536);
ALTER TABLE aocs_alter_add_col_reorganize SET WITH (reorganize=true);
SET gp_default_storage_options ='compresstype=zlib, compresslevel=2';
-- use statement encoding
ALTER TABLE aocs_alter_add_col_reorganize ADD COLUMN b int ENCODING(compresstype=zlib, compresslevel=3, blocksize=16384);
-- use table setting
ALTER TABLE aocs_alter_add_col_reorganize ADD COLUMN c int;
RESET gp_default_storage_options;
-- use table setting
ALTER TABLE aocs_alter_add_col_reorganize ADD COLUMN d int;
\d+ aocs_alter_add_col_reorganize
Table "public.aocs_alter_add_col_reorganize"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Compression Type | Compression Level | Block Size | Description
--------+---------+-----------+----------+---------+---------+--------------+------------------+-------------------+------------+-------------
a | integer | | | | plain | | rle_type | 4 | 65536 |
b | integer | | | | plain | | zlib | 3 | 16384 |
c | integer | | | | plain | | rle_type | 4 | 65536 |
d | integer | | | | plain | | rle_type | 4 | 65536 |
Checksum: t
Distributed by: (a)
Options: compresstype=rle_type, compresslevel=4, blocksize=65536
DROP TABLE aocs_alter_add_col_reorganize;
-- test case: Ensure that reads don't fail after aborting an add column + insert operation and we don't project the aborted column
CREATE TABLE aocs_addcol_abort(a int, b int) USING ao_column;
INSERT INTO aocs_addcol_abort SELECT i,i FROM generate_series(1,10)i;
BEGIN;
ALTER TABLE aocs_addcol_abort ADD COLUMN c int;
INSERT INTO aocs_addcol_abort SELECT i,i,i FROM generate_series(1,10)i;
-- check state of aocsseg for entries of add column + insert
SELECT * FROM gp_toolkit.__gp_aocsseg('aocs_addcol_abort') ORDER BY segment_id, column_num;
segment_id | segno | column_num | physical_segno | tupcount | eof | eof_uncompressed | modcount | formatversion | state
------------+-------+------------+----------------+----------+-----+------------------+----------+---------------+-------
0 | 0 | 0 | 0 | 5 | 64 | 64 | 1 | 3 | 1
0 | 1 | 0 | 1 | 5 | 64 | 64 | 2 | 3 | 1
0 | 0 | 1 | 128 | 5 | 64 | 64 | 1 | 3 | 1
0 | 1 | 1 | 129 | 5 | 64 | 64 | 2 | 3 | 1
0 | 0 | 2 | 256 | 5 | 64 | 64 | 1 | 3 | 1
0 | 1 | 2 | 257 | 5 | 48 | 48 | 2 | 3 | 1
1 | 0 | 0 | 0 | 1 | 48 | 48 | 1 | 3 | 1
1 | 1 | 0 | 1 | 1 | 48 | 48 | 2 | 3 | 1
1 | 0 | 1 | 128 | 1 | 48 | 48 | 1 | 3 | 1
1 | 1 | 1 | 129 | 1 | 48 | 48 | 2 | 3 | 1
1 | 0 | 2 | 256 | 1 | 48 | 48 | 1 | 3 | 1
1 | 1 | 2 | 257 | 1 | 48 | 48 | 2 | 3 | 1
2 | 0 | 0 | 0 | 4 | 56 | 56 | 1 | 3 | 1
2 | 1 | 0 | 1 | 4 | 56 | 56 | 2 | 3 | 1
2 | 0 | 1 | 128 | 4 | 56 | 56 | 1 | 3 | 1
2 | 1 | 1 | 129 | 4 | 56 | 56 | 2 | 3 | 1
2 | 0 | 2 | 256 | 4 | 56 | 56 | 1 | 3 | 1
2 | 1 | 2 | 257 | 4 | 48 | 48 | 2 | 3 | 1
(18 rows)
SELECT * FROM aocs_addcol_abort;
a | b | c
----+----+----
5 | 5 | 5
6 | 6 | 6
9 | 9 | 9
10 | 10 | 10
5 | 5 |
6 | 6 |
9 | 9 |
10 | 10 |
1 | 1 | 1
1 | 1 |
2 | 2 | 2
3 | 3 | 3
4 | 4 | 4
7 | 7 | 7
8 | 8 | 8
2 | 2 |
3 | 3 |
4 | 4 |
7 | 7 |
8 | 8 |
(20 rows)
ABORT;
-- check state of aocsseg if entries for new column are rolled back correctly
SELECT * FROM gp_toolkit.__gp_aocsseg('aocs_addcol_abort') ORDER BY segment_id, column_num;
segment_id | segno | column_num | physical_segno | tupcount | eof | eof_uncompressed | modcount | formatversion | state
------------+-------+------------+----------------+----------+-----+------------------+----------+---------------+-------
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 1
0 | 1 | 0 | 1 | 5 | 64 | 64 | 1 | 3 | 1
0 | 0 | 1 | 128 | 0 | 0 | 0 | 0 | 3 | 1
0 | 1 | 1 | 129 | 5 | 64 | 64 | 1 | 3 | 1
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 1
1 | 1 | 0 | 1 | 1 | 48 | 48 | 1 | 3 | 1
1 | 0 | 1 | 128 | 0 | 0 | 0 | 0 | 3 | 1
1 | 1 | 1 | 129 | 1 | 48 | 48 | 1 | 3 | 1
2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 1
2 | 1 | 0 | 1 | 4 | 56 | 56 | 1 | 3 | 1
2 | 0 | 1 | 128 | 0 | 0 | 0 | 0 | 3 | 1
2 | 1 | 1 | 129 | 4 | 56 | 56 | 1 | 3 | 1
(12 rows)
SELECT * FROM aocs_addcol_abort;
a | b
----+----
5 | 5
6 | 6
9 | 9
10 | 10
1 | 1
2 | 2
3 | 3
4 | 4
7 | 7
8 | 8
(10 rows)
DROP TABLE aocs_addcol_abort;