0002-gtt-v51-regress.patch

application/octet-stream

Filename: 0002-gtt-v51-regress.patch
Type: application/octet-stream
Part: 0
Message: Re: [Proposal] Global temporary tables

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
Series: patch v51-0002
File+
src/test/regress/expected/gtt_clean.out 14 0
src/test/regress/expected/gtt_function.out 381 0
src/test/regress/expected/gtt_parallel_1.out 90 0
src/test/regress/expected/gtt_parallel_2.out 343 0
src/test/regress/expected/gtt_prepare.out 10 0
src/test/regress/expected/gtt_stats.out 80 0
src/test/regress/expected/rules.out 88 0
src/test/regress/parallel_schedule 7 0
src/test/regress/sql/gtt_clean.sql 8 0
src/test/regress/sql/gtt_function.sql 253 0
src/test/regress/sql/gtt_parallel_1.sql 44 0
src/test/regress/sql/gtt_parallel_2.sql 154 0
src/test/regress/sql/gtt_prepare.sql 19 0
src/test/regress/sql/gtt_stats.sql 46 0
diff --git a/src/test/regress/expected/gtt_clean.out b/src/test/regress/expected/gtt_clean.out
new file mode 100644
index 0000000000..ca2d135056
--- /dev/null
+++ b/src/test/regress/expected/gtt_clean.out
@@ -0,0 +1,14 @@
+reset search_path;
+select pg_sleep(5);
+ pg_sleep 
+----------
+ 
+(1 row)
+
+drop schema gtt cascade;
+NOTICE:  drop cascades to 5 other objects
+DETAIL:  drop cascades to table gtt.gtt1
+drop cascades to table gtt.gtt2
+drop cascades to table gtt.gtt3
+drop cascades to table gtt.gtt_t_kenyon
+drop cascades to table gtt.gtt_with_seq
diff --git a/src/test/regress/expected/gtt_function.out b/src/test/regress/expected/gtt_function.out
new file mode 100644
index 0000000000..0ac9e228d2
--- /dev/null
+++ b/src/test/regress/expected/gtt_function.out
@@ -0,0 +1,381 @@
+CREATE SCHEMA IF NOT EXISTS gtt_function;
+set search_path=gtt_function,sys;
+create global temp table gtt1(a int primary key, b text);
+create global temp table gtt_test_rename(a int primary key, b text);
+create global temp table gtt2(a int primary key, b text) on commit delete rows;
+create global temp table gtt3(a int primary key, b text) on commit PRESERVE rows;
+create global temp table tmp_t0(c0 tsvector,c1 varchar(100));
+create table tbl_inherits_parent(
+a int not null,
+b varchar(32) not null default 'Got u',
+c int check (c > 0),
+d date not null
+);
+create global temp table tbl_inherits_parent_global_temp(
+a int not null,
+b varchar(32) not null default 'Got u',
+c int check (c > 0),
+d date not null
+)on commit delete rows;
+CREATE global temp TABLE products (
+    product_no integer PRIMARY KEY,
+    name text,
+    price numeric
+);
+create global temp table gtt6(n int) with (on_commit_delete_rows='true');
+begin;
+insert into gtt6 values (9);
+-- 1 row
+select * from gtt6;
+ n 
+---
+ 9
+(1 row)
+
+commit;
+-- 0 row
+select * from gtt6;
+ n 
+---
+(0 rows)
+
+-- ERROR
+create index CONCURRENTLY idx_gtt1 on gtt1 (b);
+-- ERROR
+cluster gtt1 using gtt1_pkey;
+-- ERROR
+create table gtt1(a int primary key, b text) on commit delete rows;
+ERROR:  ON COMMIT can only be used on temporary tables
+-- ERROR
+alter table gtt1 SET TABLESPACE pg_default;
+ERROR:  not support alter table set tablespace on global temporary table
+-- ERROR
+alter table gtt1 set ( on_commit_delete_rows='true');
+ERROR:  table cannot add or modify on commit parameter by ALTER TABLE command.
+-- ERROR
+create table gtt1(a int primary key, b text) with(on_commit_delete_rows=true);
+ERROR:  The parameter on_commit_delete_rows is exclusive to the global temporary table, which cannot be specified by a regular table
+-- ERROR
+create or replace global temp view gtt_v as select 5;
+ERROR:  views cannot be global temp because they do not have storage
+create table foo();
+-- ERROR
+alter table foo set (on_commit_delete_rows='true');
+ERROR:  table cannot add or modify on commit parameter by ALTER TABLE command.
+-- ok
+CREATE global temp TABLE measurement (
+    logdate         date not null,
+    peaktemp        int,
+    unitsales       int
+) PARTITION BY RANGE (logdate);
+--ok
+CREATE global temp TABLE p_table01 (
+id        bigserial NOT NULL,
+cre_time  timestamp without time zone,
+note      varchar(30)
+) PARTITION BY RANGE (cre_time)
+WITH (
+OIDS = FALSE
+)on commit delete rows;
+CREATE global temp TABLE p_table01_2018
+PARTITION OF p_table01
+FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2019-01-01 00:00:00') on commit delete rows;
+CREATE global temp TABLE p_table01_2017
+PARTITION OF p_table01
+FOR VALUES FROM ('2017-01-01 00:00:00') TO ('2018-01-01 00:00:00') on commit delete rows;
+begin;
+insert into p_table01 values(1,'2018-01-02 00:00:00','test1');
+insert into p_table01 values(1,'2018-01-02 00:00:00','test2');
+select count(*) from p_table01;
+ count 
+-------
+     2
+(1 row)
+
+commit;
+select count(*) from p_table01;
+ count 
+-------
+     0
+(1 row)
+
+--ok
+CREATE global temp TABLE p_table02 (
+id        bigserial NOT NULL,
+cre_time  timestamp without time zone,
+note      varchar(30)
+) PARTITION BY RANGE (cre_time)
+WITH (
+OIDS = FALSE
+)
+on commit PRESERVE rows;
+CREATE global temp TABLE p_table02_2018
+PARTITION OF p_table02
+FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2019-01-01 00:00:00');
+CREATE global temp TABLE p_table02_2017
+PARTITION OF p_table02
+FOR VALUES FROM ('2017-01-01 00:00:00') TO ('2018-01-01 00:00:00');
+-- ERROR
+create global temp table tbl_inherits_partition() inherits (tbl_inherits_parent);
+ERROR:  The parent table must be global temporary table
+-- ok
+create global temp table tbl_inherits_partition() inherits (tbl_inherits_parent_global_temp) on commit delete rows;
+select relname ,relkind, relpersistence, reloptions from pg_class where relname like 'p_table0%' or  relname like 'tbl_inherits%' order by relname;
+             relname             | relkind | relpersistence |          reloptions           
+---------------------------------+---------+----------------+-------------------------------
+ p_table01                       | p       | g              | {on_commit_delete_rows=true}
+ p_table01_2017                  | r       | g              | {on_commit_delete_rows=true}
+ p_table01_2018                  | r       | g              | {on_commit_delete_rows=true}
+ p_table01_id_seq                | S       | g              | 
+ p_table02                       | p       | g              | {on_commit_delete_rows=false}
+ p_table02_2017                  | r       | g              | {on_commit_delete_rows=false}
+ p_table02_2018                  | r       | g              | {on_commit_delete_rows=false}
+ p_table02_id_seq                | S       | g              | 
+ tbl_inherits_parent             | r       | p              | 
+ tbl_inherits_parent_global_temp | r       | g              | {on_commit_delete_rows=true}
+ tbl_inherits_partition          | r       | g              | {on_commit_delete_rows=true}
+(11 rows)
+
+-- ERROR
+create global temp table gtt3(a int primary key, b text) on commit drop;
+ERROR:  global temporary table not support on commit drop clause
+-- ERROR
+create global temp table gtt4(a int primary key, b text) with(on_commit_delete_rows=true) on commit delete rows;
+ERROR:  could not create global temporary table with on commit and with clause at same time
+-- ok
+create global temp table gtt5(a int primary key, b text) with(on_commit_delete_rows=true);
+--ok
+alter table gtt_test_rename rename to gtt_test_new;
+-- ok
+ALTER TABLE gtt_test_new ADD COLUMN address varchar(30);
+-- ERROR
+CREATE TABLE orders (
+    order_id integer PRIMARY KEY,
+    product_no integer REFERENCES products (product_no),
+    quantity integer
+);
+ERROR:  constraints on permanent tables may reference only permanent tables
+-- ok
+CREATE global temp TABLE orders (
+    order_id integer PRIMARY KEY,
+    product_no integer REFERENCES products (product_no),
+    quantity integer
+)on commit delete rows;
+--ERROR
+insert into orders values(1,1,1);
+ERROR:  insert or update on table "orders" violates foreign key constraint "orders_product_no_fkey"
+DETAIL:  Key (product_no)=(1) is not present in table "products".
+--ok
+insert into products values(1,'test',1.0);
+begin;
+insert into orders values(1,1,1);
+commit;
+select count(*) from products;
+ count 
+-------
+     1
+(1 row)
+
+select count(*) from orders;
+ count 
+-------
+     0
+(1 row)
+
+-- ok
+CREATE GLOBAL TEMPORARY TABLE mytable (
+  id SERIAL PRIMARY KEY,
+  data text
+) on commit preserve rows;
+-- ok
+create global temp table gtt_seq(id int GENERATED ALWAYS AS IDENTITY (START WITH 2) primary key, a int)  on commit PRESERVE rows;
+insert into gtt_seq (a) values(1);
+insert into gtt_seq (a) values(2);
+select * from gtt_seq order by id;
+ id | a 
+----+---
+  2 | 1
+  3 | 2
+(2 rows)
+
+truncate gtt_seq;
+select * from gtt_seq order by id;
+ id | a 
+----+---
+(0 rows)
+
+insert into gtt_seq (a) values(3);
+select * from gtt_seq order by id;
+ id | a 
+----+---
+  4 | 3
+(1 row)
+
+--ERROR
+CREATE MATERIALIZED VIEW mv_gtt1 as select * from gtt1;
+ERROR:  materialized views must not use global temporary tables or views
+-- ok
+create index idx_gtt1_1 on gtt1 using hash (a);
+create index idx_tmp_t0_1 on tmp_t0 using gin (c0);
+create index idx_tmp_t0_2 on tmp_t0 using gist (c0);
+--ok
+create global temp table gt (a SERIAL,b int);
+begin;
+set transaction_read_only = true;
+insert into gt (b) values(1);
+select * from gt;
+ a | b 
+---+---
+ 1 | 1
+(1 row)
+
+commit;
+create sequence seq_1;
+CREATE GLOBAL TEMPORARY TABLE gtt_s_1(c1 int PRIMARY KEY) ON COMMIT DELETE ROWS;
+CREATE GLOBAL TEMPORARY TABLE gtt_s_2(c1 int PRIMARY KEY) ON COMMIT PRESERVE ROWS;
+alter table gtt_s_1 add c2 int default nextval('seq_1');
+alter table gtt_s_2 add c2 int default nextval('seq_1');
+begin;
+insert into gtt_s_1 (c1)values(1);
+insert into gtt_s_2 (c1)values(1);
+insert into gtt_s_1 (c1)values(2);
+insert into gtt_s_2 (c1)values(2);
+select * from gtt_s_1 order by c1;
+ c1 | c2 
+----+----
+  1 |  1
+  2 |  3
+(2 rows)
+
+commit;
+select * from gtt_s_1 order by c1;
+ c1 | c2 
+----+----
+(0 rows)
+
+select * from gtt_s_2 order by c1;
+ c1 | c2 
+----+----
+  1 |  2
+  2 |  4
+(2 rows)
+
+--ok
+create global temp table gt1(a int);
+insert into gt1 values(generate_series(1,100000));
+create index idx_gt1_1 on gt1 (a);
+create index idx_gt1_2 on gt1((a + 1));
+create index idx_gt1_3 on gt1((a*10),(a+a),(a-1));
+explain (costs off) select * from gt1 where a=1;
+              QUERY PLAN              
+--------------------------------------
+ Bitmap Heap Scan on gt1
+   Recheck Cond: (a = 1)
+   ->  Bitmap Index Scan on idx_gt1_1
+         Index Cond: (a = 1)
+(4 rows)
+
+explain (costs off) select * from gt1 where a=200000;
+              QUERY PLAN              
+--------------------------------------
+ Bitmap Heap Scan on gt1
+   Recheck Cond: (a = 200000)
+   ->  Bitmap Index Scan on idx_gt1_1
+         Index Cond: (a = 200000)
+(4 rows)
+
+explain (costs off) select * from gt1 where a*10=300;
+              QUERY PLAN              
+--------------------------------------
+ Bitmap Heap Scan on gt1
+   Recheck Cond: ((a * 10) = 300)
+   ->  Bitmap Index Scan on idx_gt1_3
+         Index Cond: ((a * 10) = 300)
+(4 rows)
+
+explain (costs off) select * from gt1 where a*10=3;
+              QUERY PLAN              
+--------------------------------------
+ Bitmap Heap Scan on gt1
+   Recheck Cond: ((a * 10) = 3)
+   ->  Bitmap Index Scan on idx_gt1_3
+         Index Cond: ((a * 10) = 3)
+(4 rows)
+
+analyze gt1;
+explain (costs off) select * from gt1 where a=1;
+               QUERY PLAN               
+----------------------------------------
+ Index Only Scan using idx_gt1_1 on gt1
+   Index Cond: (a = 1)
+(2 rows)
+
+explain (costs off) select * from gt1 where a=200000;
+               QUERY PLAN               
+----------------------------------------
+ Index Only Scan using idx_gt1_1 on gt1
+   Index Cond: (a = 200000)
+(2 rows)
+
+explain (costs off) select * from gt1 where a*10=300;
+            QUERY PLAN             
+-----------------------------------
+ Index Scan using idx_gt1_3 on gt1
+   Index Cond: ((a * 10) = 300)
+(2 rows)
+
+explain (costs off) select * from gt1 where a*10=3;
+            QUERY PLAN             
+-----------------------------------
+ Index Scan using idx_gt1_3 on gt1
+   Index Cond: ((a * 10) = 3)
+(2 rows)
+
+--ok
+create global temp table gtt_test1(c1 int) with(on_commit_delete_rows='1');
+create global temp table gtt_test2(c1 int) with(on_commit_delete_rows='0');
+create global temp table gtt_test3(c1 int) with(on_commit_delete_rows='t');
+create global temp table gtt_test4(c1 int) with(on_commit_delete_rows='f');
+create global temp table gtt_test5(c1 int) with(on_commit_delete_rows='yes');
+create global temp table gtt_test6(c1 int) with(on_commit_delete_rows='no');
+create global temp table gtt_test7(c1 int) with(on_commit_delete_rows='y');
+create global temp table gtt_test8(c1 int) with(on_commit_delete_rows='n');
+--error
+create global temp table gtt_test9(c1 int) with(on_commit_delete_rows='tr');
+create global temp table gtt_test10(c1 int) with(on_commit_delete_rows='ye');
+reset search_path;
+drop schema gtt_function cascade;
+NOTICE:  drop cascades to 33 other objects
+DETAIL:  drop cascades to table gtt_function.gtt1
+drop cascades to table gtt_function.gtt_test_new
+drop cascades to table gtt_function.gtt2
+drop cascades to table gtt_function.gtt3
+drop cascades to table gtt_function.tmp_t0
+drop cascades to table gtt_function.tbl_inherits_parent
+drop cascades to table gtt_function.tbl_inherits_parent_global_temp
+drop cascades to table gtt_function.products
+drop cascades to table gtt_function.gtt6
+drop cascades to table gtt_function.foo
+drop cascades to table gtt_function.measurement
+drop cascades to table gtt_function.p_table01
+drop cascades to table gtt_function.p_table02
+drop cascades to table gtt_function.tbl_inherits_partition
+drop cascades to table gtt_function.gtt5
+drop cascades to table gtt_function.orders
+drop cascades to table gtt_function.mytable
+drop cascades to table gtt_function.gtt_seq
+drop cascades to table gtt_function.gt
+drop cascades to sequence gtt_function.seq_1
+drop cascades to table gtt_function.gtt_s_1
+drop cascades to table gtt_function.gtt_s_2
+drop cascades to table gtt_function.gt1
+drop cascades to table gtt_function.gtt_test1
+drop cascades to table gtt_function.gtt_test2
+drop cascades to table gtt_function.gtt_test3
+drop cascades to table gtt_function.gtt_test4
+drop cascades to table gtt_function.gtt_test5
+drop cascades to table gtt_function.gtt_test6
+drop cascades to table gtt_function.gtt_test7
+drop cascades to table gtt_function.gtt_test8
+drop cascades to table gtt_function.gtt_test9
+drop cascades to table gtt_function.gtt_test10
diff --git a/src/test/regress/expected/gtt_parallel_1.out b/src/test/regress/expected/gtt_parallel_1.out
new file mode 100644
index 0000000000..0646aaed73
--- /dev/null
+++ b/src/test/regress/expected/gtt_parallel_1.out
@@ -0,0 +1,90 @@
+set search_path=gtt,sys;
+select nextval('gtt_with_seq_c2_seq');
+ nextval 
+---------
+       1
+(1 row)
+
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+ a | b 
+---+---
+(0 rows)
+
+begin;
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+(1 row)
+
+commit;
+select * from gtt1 order by a;
+ a | b 
+---+---
+(0 rows)
+
+begin;
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+(1 row)
+
+rollback;
+select * from gtt1 order by a;
+ a | b 
+---+---
+(0 rows)
+
+truncate gtt1;
+select * from gtt1 order by a;
+ a | b 
+---+---
+(0 rows)
+
+begin;
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+(1 row)
+
+truncate gtt1;
+select * from gtt1 order by a;
+ a | b 
+---+---
+(0 rows)
+
+insert into gtt1 values(1, 'test1');
+rollback;
+select * from gtt1 order by a;
+ a | b 
+---+---
+(0 rows)
+
+begin;
+select * from gtt1 order by a;
+ a | b 
+---+---
+(0 rows)
+
+truncate gtt1;
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+(1 row)
+
+truncate gtt1;
+commit;
+select * from gtt1 order by a;
+ a | b 
+---+---
+(0 rows)
+
+reset search_path;
diff --git a/src/test/regress/expected/gtt_parallel_2.out b/src/test/regress/expected/gtt_parallel_2.out
new file mode 100644
index 0000000000..0fccf6b81c
--- /dev/null
+++ b/src/test/regress/expected/gtt_parallel_2.out
@@ -0,0 +1,343 @@
+set search_path=gtt,sys;
+insert into gtt3 values(1, 'test1');
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+(1 row)
+
+begin;
+insert into gtt3 values(2, 'test1');
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+ 2 | test1
+(2 rows)
+
+commit;
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+ 2 | test1
+(2 rows)
+
+begin;
+insert into gtt3 values(3, 'test1');
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+ 2 | test1
+ 3 | test1
+(3 rows)
+
+rollback;
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+ 2 | test1
+(2 rows)
+
+truncate gtt3;
+select * from gtt3 order by a;
+ a | b 
+---+---
+(0 rows)
+
+insert into gtt3 values(1, 'test1');
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+(1 row)
+
+begin;
+insert into gtt3 values(2, 'test2');
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+ 2 | test2
+(2 rows)
+
+truncate gtt3;
+select * from gtt3 order by a;
+ a | b 
+---+---
+(0 rows)
+
+insert into gtt3 values(3, 'test3');
+update gtt3 set a = 3 where b = 'test1';
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 3 | test3
+(1 row)
+
+rollback;
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+(1 row)
+
+begin;
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 1 | test1
+(1 row)
+
+truncate gtt3;
+insert into gtt3 values(5, 'test5');
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 5 | test5
+(1 row)
+
+truncate gtt3;
+insert into gtt3 values(6, 'test6');
+commit;
+select * from gtt3 order by a;
+ a |   b   
+---+-------
+ 6 | test6
+(1 row)
+
+truncate gtt3;
+insert into gtt3 values(1);
+select * from gtt3;
+ a | b 
+---+---
+ 1 | 
+(1 row)
+
+begin;
+insert into gtt3 values(2);
+select * from gtt3;
+ a | b 
+---+---
+ 1 | 
+ 2 | 
+(2 rows)
+
+SAVEPOINT save1;
+truncate gtt3;
+insert into gtt3 values(3);
+select * from gtt3;
+ a | b 
+---+---
+ 3 | 
+(1 row)
+
+SAVEPOINT save2;
+truncate gtt3;
+insert into gtt3 values(4);
+select * from gtt3;
+ a | b 
+---+---
+ 4 | 
+(1 row)
+
+SAVEPOINT save3;
+rollback to savepoint save2;
+Select * from gtt3;
+ a | b 
+---+---
+ 3 | 
+(1 row)
+
+insert into gtt3 values(5);
+select * from gtt3;
+ a | b 
+---+---
+ 3 | 
+ 5 | 
+(2 rows)
+
+rollback;
+select * from gtt3;
+ a | b 
+---+---
+ 1 | 
+(1 row)
+
+truncate gtt3;
+insert into gtt3 values(1);
+select * from gtt3;
+ a | b 
+---+---
+ 1 | 
+(1 row)
+
+begin;
+insert into gtt3 values(2);
+select * from gtt3;
+ a | b 
+---+---
+ 1 | 
+ 2 | 
+(2 rows)
+
+SAVEPOINT save1;
+truncate gtt3;
+insert into gtt3 values(3);
+select * from gtt3;
+ a | b 
+---+---
+ 3 | 
+(1 row)
+
+SAVEPOINT save2;
+truncate gtt3;
+insert into gtt3 values(4);
+select * from gtt3;
+ a | b 
+---+---
+ 4 | 
+(1 row)
+
+SAVEPOINT save3;
+rollback to savepoint save2;
+Select * from gtt3;
+ a | b 
+---+---
+ 3 | 
+(1 row)
+
+insert into gtt3 values(5);
+select * from gtt3;
+ a | b 
+---+---
+ 3 | 
+ 5 | 
+(2 rows)
+
+commit;
+select * from gtt3;
+ a | b 
+---+---
+ 3 | 
+ 5 | 
+(2 rows)
+
+truncate gtt3;
+insert into gtt3 values(generate_series(1,100000), 'testing');
+select count(*) from gtt3;
+ count  
+--------
+ 100000
+(1 row)
+
+analyze gtt3;
+explain (COSTS FALSE) select * from gtt3 where a =300;
+             QUERY PLAN             
+------------------------------------
+ Index Scan using gtt3_pkey on gtt3
+   Index Cond: (a = 300)
+(2 rows)
+
+insert into gtt_t_kenyon select generate_series(1,2000),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',500);
+insert into gtt_t_kenyon select generate_series(1,2),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',2000);
+insert into gtt_t_kenyon select generate_series(3,4),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',4000);
+insert into gtt_t_kenyon select generate_series(5,6),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',5500);
+select relname, pg_relation_size(oid),pg_relation_size(reltoastrelid),pg_table_size(oid),pg_indexes_size(oid),pg_total_relation_size(oid) from pg_class where relname = 'gtt_t_kenyon';
+   relname    | pg_relation_size | pg_relation_size | pg_table_size | pg_indexes_size | pg_total_relation_size 
+--------------+------------------+------------------+---------------+-----------------+------------------------
+ gtt_t_kenyon |           450560 |             8192 |        499712 |          114688 |                 614400
+(1 row)
+
+select relname from pg_class where relname = 'gtt_t_kenyon' and reltoastrelid != 0;
+   relname    
+--------------
+ gtt_t_kenyon
+(1 row)
+
+select
+c.relname, pg_relation_size(c.oid),pg_table_size(c.oid),pg_total_relation_size(c.oid)
+from
+pg_class c
+where
+c.oid in
+(
+select
+i.indexrelid as indexrelid
+from
+pg_index i ,pg_class cc
+where cc.relname = 'gtt_t_kenyon' and cc.oid = i.indrelid
+)
+order by c.relname;
+      relname       | pg_relation_size | pg_table_size | pg_total_relation_size 
+--------------------+------------------+---------------+------------------------
+ idx_gtt_t_kenyon_1 |            65536 |         65536 |                  65536
+ idx_gtt_t_kenyon_2 |            49152 |         49152 |                  49152
+(2 rows)
+
+select count(*) from gtt_t_kenyon;
+ count 
+-------
+  2006
+(1 row)
+
+begin;
+cluster gtt_t_kenyon using idx_gtt_t_kenyon_1;
+commit;
+select count(*) from gtt_t_kenyon;
+ count 
+-------
+  2006
+(1 row)
+
+begin;
+cluster gtt_t_kenyon using idx_gtt_t_kenyon_1;
+rollback;
+select count(*) from gtt_t_kenyon;
+ count 
+-------
+  2006
+(1 row)
+
+vacuum full gtt_t_kenyon;
+select count(*) from gtt_t_kenyon;
+ count 
+-------
+  2006
+(1 row)
+
+begin;
+truncate gtt_t_kenyon;
+insert into gtt_t_kenyon select generate_series(1,2000),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',500);
+cluster gtt_t_kenyon using idx_gtt_t_kenyon_1;
+commit;
+select count(*) from gtt_t_kenyon;
+ count 
+-------
+  2000
+(1 row)
+
+insert into gtt_t_kenyon select generate_series(1,2),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',2000);
+insert into gtt_t_kenyon select generate_series(3,4),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',4000);
+insert into gtt_t_kenyon select generate_series(5,6),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',5500);
+begin;
+truncate gtt_t_kenyon;
+insert into gtt_t_kenyon select generate_series(1,2000),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',500);
+cluster gtt_t_kenyon using idx_gtt_t_kenyon_1;
+rollback;
+select count(*) from gtt_t_kenyon;
+ count 
+-------
+  2006
+(1 row)
+
+insert into gtt_with_seq (c1) values(1);
+select * from gtt_with_seq;
+ c1 | c2 
+----+----
+  1 |  1
+(1 row)
+
+reset search_path;
diff --git a/src/test/regress/expected/gtt_prepare.out b/src/test/regress/expected/gtt_prepare.out
new file mode 100644
index 0000000000..8c0c376429
--- /dev/null
+++ b/src/test/regress/expected/gtt_prepare.out
@@ -0,0 +1,10 @@
+CREATE SCHEMA IF NOT EXISTS gtt;
+set search_path=gtt,sys;
+create global temp table gtt1(a int primary key, b text) on commit delete rows;
+create global temp table gtt2(a int primary key, b text) on commit delete rows;
+create global temp table gtt3(a int primary key, b text);
+create global temp table gtt_t_kenyon(id int,vname varchar(48),remark text) on commit PRESERVE rows;
+create index idx_gtt_t_kenyon_1 on gtt_t_kenyon(id);
+create index idx_gtt_t_kenyon_2 on gtt_t_kenyon(remark);
+CREATE GLOBAL TEMPORARY TABLE gtt_with_seq(c1 bigint, c2 bigserial) on commit PRESERVE rows;
+reset search_path;
diff --git a/src/test/regress/expected/gtt_stats.out b/src/test/regress/expected/gtt_stats.out
new file mode 100644
index 0000000000..4420fdbd8f
--- /dev/null
+++ b/src/test/regress/expected/gtt_stats.out
@@ -0,0 +1,80 @@
+CREATE SCHEMA IF NOT EXISTS gtt_stats;
+set search_path=gtt_stats,sys;
+-- expect 0
+select count(*) from pg_gtt_attached_pids;
+ count 
+-------
+     0
+(1 row)
+
+-- expect 0
+select count(*) from pg_list_gtt_relfrozenxids();
+ count 
+-------
+     0
+(1 row)
+
+create global temp table gtt_stats.gtt(a int primary key, b text) on commit PRESERVE rows;
+-- expect 0
+select count(*) from pg_gtt_attached_pids;
+ count 
+-------
+     1
+(1 row)
+
+-- expect 0
+select count(*) from pg_list_gtt_relfrozenxids();
+ count 
+-------
+     2
+(1 row)
+
+insert into gtt values(generate_series(1,10000),'test');
+-- expect 1
+select count(*) from pg_gtt_attached_pids;
+ count 
+-------
+     1
+(1 row)
+
+-- expect 2
+select count(*) from pg_list_gtt_relfrozenxids();
+ count 
+-------
+     2
+(1 row)
+
+-- expect 2
+select schemaname, tablename, relpages, reltuples, relallvisible from pg_gtt_relstats where schemaname = 'gtt_stats' order by tablename;
+ schemaname | tablename | relpages | reltuples | relallvisible 
+------------+-----------+----------+-----------+---------------
+ gtt_stats  | gtt       |        0 |         0 |             0
+ gtt_stats  | gtt_pkey  |        1 |         0 |             0
+(2 rows)
+
+-- expect 0
+select * from pg_gtt_stats order by tablename;
+ schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram 
+------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------
+(0 rows)
+
+reindex table gtt;
+reindex index gtt_pkey;
+analyze gtt;
+select schemaname, tablename, relpages, reltuples, relallvisible from pg_gtt_relstats where schemaname = 'gtt_stats' order by tablename;
+ schemaname | tablename | relpages | reltuples | relallvisible 
+------------+-----------+----------+-----------+---------------
+ gtt_stats  | gtt       |       55 |     10000 |             0
+ gtt_stats  | gtt_pkey  |       30 |     10000 |             0
+(2 rows)
+
+select * from pg_gtt_stats order by tablename;
+ schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs |                                                                                                                                                                                                                                                histogram_bounds                                                                                                                                                                                                                                                 | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram 
+------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-------------------+------------------------+----------------------
+ gtt_stats  | gtt       | a       | f         |         0 |         4 |         -1 |                  |                   | {1,100,200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,3000,3100,3200,3300,3400,3500,3600,3700,3800,3900,4000,4100,4200,4300,4400,4500,4600,4700,4800,4900,5000,5100,5200,5300,5400,5500,5600,5700,5800,5900,6000,6100,6200,6300,6400,6500,6600,6700,6800,6900,7000,7100,7200,7300,7400,7500,7600,7700,7800,7900,8000,8100,8200,8300,8400,8500,8600,8700,8800,8900,9000,9100,9200,9300,9400,9500,9600,9700,9800,9900,10000} |           1 |                   |                        | 
+ gtt_stats  | gtt       | b       | f         |         0 |         5 |          1 | {test}           | {1}               |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |           1 |                   |                        | 
+(2 rows)
+
+reset search_path;
+drop schema gtt_stats cascade;
+NOTICE:  drop cascades to table gtt_stats.gtt
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e5ab11275d..23b2863fec 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1359,6 +1359,94 @@ pg_group| SELECT pg_authid.rolname AS groname,
           WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist
    FROM pg_authid
   WHERE (NOT pg_authid.rolcanlogin);
+pg_gtt_attached_pids| SELECT n.nspname AS schemaname,
+    c.relname AS tablename,
+    s.relid,
+    s.pid
+   FROM (pg_class c
+     LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))),
+    LATERAL pg_gtt_attached_pid(c.oid) s(relid, pid)
+  WHERE ((c.relpersistence = 'g'::"char") AND (c.relkind = ANY (ARRAY['r'::"char", 'S'::"char"])) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
+pg_gtt_relstats| SELECT n.nspname AS schemaname,
+    c.relname AS tablename,
+    s.relfilenode,
+    s.relpages,
+    s.reltuples,
+    s.relallvisible,
+    s.relfrozenxid,
+    s.relminmxid
+   FROM (pg_class c
+     LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))),
+    LATERAL pg_get_gtt_relstats(c.oid) s(relfilenode, relpages, reltuples, relallvisible, relfrozenxid, relminmxid)
+  WHERE ((c.relpersistence = 'g'::"char") AND (c.relkind = ANY (ARRAY['r'::"char", 'p'::"char", 'i'::"char", 't'::"char"])) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
+pg_gtt_stats| SELECT n.nspname AS schemaname,
+    c.relname AS tablename,
+    a.attname,
+    s.stainherit AS inherited,
+    s.stanullfrac AS null_frac,
+    s.stawidth AS avg_width,
+    s.stadistinct AS n_distinct,
+        CASE
+            WHEN (s.stakind1 = 1) THEN s.stavalues1
+            WHEN (s.stakind2 = 1) THEN s.stavalues2
+            WHEN (s.stakind3 = 1) THEN s.stavalues3
+            WHEN (s.stakind4 = 1) THEN s.stavalues4
+            WHEN (s.stakind5 = 1) THEN s.stavalues5
+            ELSE NULL::text[]
+        END AS most_common_vals,
+        CASE
+            WHEN (s.stakind1 = 1) THEN s.stanumbers1
+            WHEN (s.stakind2 = 1) THEN s.stanumbers2
+            WHEN (s.stakind3 = 1) THEN s.stanumbers3
+            WHEN (s.stakind4 = 1) THEN s.stanumbers4
+            WHEN (s.stakind5 = 1) THEN s.stanumbers5
+            ELSE NULL::real[]
+        END AS most_common_freqs,
+        CASE
+            WHEN (s.stakind1 = 2) THEN s.stavalues1
+            WHEN (s.stakind2 = 2) THEN s.stavalues2
+            WHEN (s.stakind3 = 2) THEN s.stavalues3
+            WHEN (s.stakind4 = 2) THEN s.stavalues4
+            WHEN (s.stakind5 = 2) THEN s.stavalues5
+            ELSE NULL::text[]
+        END AS histogram_bounds,
+        CASE
+            WHEN (s.stakind1 = 3) THEN s.stanumbers1[1]
+            WHEN (s.stakind2 = 3) THEN s.stanumbers2[1]
+            WHEN (s.stakind3 = 3) THEN s.stanumbers3[1]
+            WHEN (s.stakind4 = 3) THEN s.stanumbers4[1]
+            WHEN (s.stakind5 = 3) THEN s.stanumbers5[1]
+            ELSE NULL::real
+        END AS correlation,
+        CASE
+            WHEN (s.stakind1 = 4) THEN s.stavalues1
+            WHEN (s.stakind2 = 4) THEN s.stavalues2
+            WHEN (s.stakind3 = 4) THEN s.stavalues3
+            WHEN (s.stakind4 = 4) THEN s.stavalues4
+            WHEN (s.stakind5 = 4) THEN s.stavalues5
+            ELSE NULL::text[]
+        END AS most_common_elems,
+        CASE
+            WHEN (s.stakind1 = 4) THEN s.stanumbers1
+            WHEN (s.stakind2 = 4) THEN s.stanumbers2
+            WHEN (s.stakind3 = 4) THEN s.stanumbers3
+            WHEN (s.stakind4 = 4) THEN s.stanumbers4
+            WHEN (s.stakind5 = 4) THEN s.stanumbers5
+            ELSE NULL::real[]
+        END AS most_common_elem_freqs,
+        CASE
+            WHEN (s.stakind1 = 5) THEN s.stanumbers1
+            WHEN (s.stakind2 = 5) THEN s.stanumbers2
+            WHEN (s.stakind3 = 5) THEN s.stanumbers3
+            WHEN (s.stakind4 = 5) THEN s.stanumbers4
+            WHEN (s.stakind5 = 5) THEN s.stanumbers5
+            ELSE NULL::real[]
+        END AS elem_count_histogram
+   FROM ((pg_class c
+     JOIN pg_attribute a ON ((c.oid = a.attrelid)))
+     LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))),
+    LATERAL pg_get_gtt_statistics(c.oid, (a.attnum)::integer, ''::text) s(starelid, staattnum, stainherit, stanullfrac, stawidth, stadistinct, stakind1, stakind2, stakind3, stakind4, stakind5, staop1, staop2, staop3, staop4, staop5, stacoll1, stacoll2, stacoll3, stacoll4, stacoll5, stanumbers1, stanumbers2, stanumbers3, stanumbers4, stanumbers5, stavalues1, stavalues2, stavalues3, stavalues4, stavalues5)
+  WHERE ((c.relpersistence = 'g'::"char") AND (c.relkind = ANY (ARRAY['r'::"char", 'p'::"char", 'i'::"char", 't'::"char"])) AND (NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
 pg_hba_file_rules| SELECT a.line_number,
     a.type,
     a.database,
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 7be89178f0..d039f0fbb1 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -130,3 +130,10 @@ test: fast_default
 
 # run stats by itself because its delay may be insufficient under heavy load
 test: stats
+
+# global temp table test
+test: gtt_stats
+test: gtt_function
+test: gtt_prepare
+test: gtt_parallel_1 gtt_parallel_2
+test: gtt_clean
diff --git a/src/test/regress/sql/gtt_clean.sql b/src/test/regress/sql/gtt_clean.sql
new file mode 100644
index 0000000000..2c8e5868d1
--- /dev/null
+++ b/src/test/regress/sql/gtt_clean.sql
@@ -0,0 +1,8 @@
+
+
+reset search_path;
+
+select pg_sleep(5);
+
+drop schema gtt cascade;
+
diff --git a/src/test/regress/sql/gtt_function.sql b/src/test/regress/sql/gtt_function.sql
new file mode 100644
index 0000000000..fd8b4d3e3b
--- /dev/null
+++ b/src/test/regress/sql/gtt_function.sql
@@ -0,0 +1,253 @@
+
+CREATE SCHEMA IF NOT EXISTS gtt_function;
+
+set search_path=gtt_function,sys;
+
+create global temp table gtt1(a int primary key, b text);
+
+create global temp table gtt_test_rename(a int primary key, b text);
+
+create global temp table gtt2(a int primary key, b text) on commit delete rows;
+
+create global temp table gtt3(a int primary key, b text) on commit PRESERVE rows;
+
+create global temp table tmp_t0(c0 tsvector,c1 varchar(100));
+
+create table tbl_inherits_parent(
+a int not null,
+b varchar(32) not null default 'Got u',
+c int check (c > 0),
+d date not null
+);
+
+create global temp table tbl_inherits_parent_global_temp(
+a int not null,
+b varchar(32) not null default 'Got u',
+c int check (c > 0),
+d date not null
+)on commit delete rows;
+
+CREATE global temp TABLE products (
+    product_no integer PRIMARY KEY,
+    name text,
+    price numeric
+);
+
+create global temp table gtt6(n int) with (on_commit_delete_rows='true');
+
+begin;
+insert into gtt6 values (9);
+-- 1 row
+select * from gtt6;
+commit;
+-- 0 row
+select * from gtt6;
+
+-- ERROR
+create index CONCURRENTLY idx_gtt1 on gtt1 (b);
+
+-- ERROR
+cluster gtt1 using gtt1_pkey;
+
+-- ERROR
+create table gtt1(a int primary key, b text) on commit delete rows;
+
+-- ERROR
+alter table gtt1 SET TABLESPACE pg_default;
+
+-- ERROR
+alter table gtt1 set ( on_commit_delete_rows='true');
+
+-- ERROR
+create table gtt1(a int primary key, b text) with(on_commit_delete_rows=true);
+
+-- ERROR
+create or replace global temp view gtt_v as select 5;
+
+create table foo();
+-- ERROR
+alter table foo set (on_commit_delete_rows='true');
+
+-- ok
+CREATE global temp TABLE measurement (
+    logdate         date not null,
+    peaktemp        int,
+    unitsales       int
+) PARTITION BY RANGE (logdate);
+
+--ok
+CREATE global temp TABLE p_table01 (
+id        bigserial NOT NULL,
+cre_time  timestamp without time zone,
+note      varchar(30)
+) PARTITION BY RANGE (cre_time)
+WITH (
+OIDS = FALSE
+)on commit delete rows;
+
+CREATE global temp TABLE p_table01_2018
+PARTITION OF p_table01
+FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2019-01-01 00:00:00') on commit delete rows;
+
+CREATE global temp TABLE p_table01_2017
+PARTITION OF p_table01
+FOR VALUES FROM ('2017-01-01 00:00:00') TO ('2018-01-01 00:00:00') on commit delete rows;
+
+begin;
+insert into p_table01 values(1,'2018-01-02 00:00:00','test1');
+insert into p_table01 values(1,'2018-01-02 00:00:00','test2');
+select count(*) from p_table01;
+commit;
+
+select count(*) from p_table01;
+
+--ok
+CREATE global temp TABLE p_table02 (
+id        bigserial NOT NULL,
+cre_time  timestamp without time zone,
+note      varchar(30)
+) PARTITION BY RANGE (cre_time)
+WITH (
+OIDS = FALSE
+)
+on commit PRESERVE rows;
+
+CREATE global temp TABLE p_table02_2018
+PARTITION OF p_table02
+FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2019-01-01 00:00:00');
+
+CREATE global temp TABLE p_table02_2017
+PARTITION OF p_table02
+FOR VALUES FROM ('2017-01-01 00:00:00') TO ('2018-01-01 00:00:00');
+
+-- ERROR
+create global temp table tbl_inherits_partition() inherits (tbl_inherits_parent);
+
+-- ok
+create global temp table tbl_inherits_partition() inherits (tbl_inherits_parent_global_temp) on commit delete rows;
+
+select relname ,relkind, relpersistence, reloptions from pg_class where relname like 'p_table0%' or  relname like 'tbl_inherits%' order by relname;
+
+-- ERROR
+create global temp table gtt3(a int primary key, b text) on commit drop;
+
+-- ERROR
+create global temp table gtt4(a int primary key, b text) with(on_commit_delete_rows=true) on commit delete rows;
+
+-- ok
+create global temp table gtt5(a int primary key, b text) with(on_commit_delete_rows=true);
+
+--ok
+alter table gtt_test_rename rename to gtt_test_new;
+
+-- ok
+ALTER TABLE gtt_test_new ADD COLUMN address varchar(30);
+
+-- ERROR
+CREATE TABLE orders (
+    order_id integer PRIMARY KEY,
+    product_no integer REFERENCES products (product_no),
+    quantity integer
+);
+
+-- ok
+CREATE global temp TABLE orders (
+    order_id integer PRIMARY KEY,
+    product_no integer REFERENCES products (product_no),
+    quantity integer
+)on commit delete rows;
+
+--ERROR
+insert into orders values(1,1,1);
+
+--ok
+insert into products values(1,'test',1.0);
+
+begin;
+insert into orders values(1,1,1);
+commit;
+
+select count(*) from products;
+select count(*) from orders;
+
+-- ok
+CREATE GLOBAL TEMPORARY TABLE mytable (
+  id SERIAL PRIMARY KEY,
+  data text
+) on commit preserve rows;
+
+-- ok
+create global temp table gtt_seq(id int GENERATED ALWAYS AS IDENTITY (START WITH 2) primary key, a int)  on commit PRESERVE rows;
+insert into gtt_seq (a) values(1);
+insert into gtt_seq (a) values(2);
+select * from gtt_seq order by id;
+truncate gtt_seq;
+select * from gtt_seq order by id;
+insert into gtt_seq (a) values(3);
+select * from gtt_seq order by id;
+
+--ERROR
+CREATE MATERIALIZED VIEW mv_gtt1 as select * from gtt1;
+
+-- ok
+create index idx_gtt1_1 on gtt1 using hash (a);
+create index idx_tmp_t0_1 on tmp_t0 using gin (c0);
+create index idx_tmp_t0_2 on tmp_t0 using gist (c0);
+
+--ok
+create global temp table gt (a SERIAL,b int);
+begin;
+set transaction_read_only = true;
+insert into gt (b) values(1);
+select * from gt;
+commit;
+
+create sequence seq_1;
+CREATE GLOBAL TEMPORARY TABLE gtt_s_1(c1 int PRIMARY KEY) ON COMMIT DELETE ROWS;
+CREATE GLOBAL TEMPORARY TABLE gtt_s_2(c1 int PRIMARY KEY) ON COMMIT PRESERVE ROWS;
+alter table gtt_s_1 add c2 int default nextval('seq_1');
+alter table gtt_s_2 add c2 int default nextval('seq_1');
+begin;
+insert into gtt_s_1 (c1)values(1);
+insert into gtt_s_2 (c1)values(1);
+insert into gtt_s_1 (c1)values(2);
+insert into gtt_s_2 (c1)values(2);
+select * from gtt_s_1 order by c1;
+commit;
+select * from gtt_s_1 order by c1;
+select * from gtt_s_2 order by c1;
+
+--ok
+create global temp table gt1(a int);
+insert into gt1 values(generate_series(1,100000));
+create index idx_gt1_1 on gt1 (a);
+create index idx_gt1_2 on gt1((a + 1));
+create index idx_gt1_3 on gt1((a*10),(a+a),(a-1));
+explain (costs off) select * from gt1 where a=1;
+explain (costs off) select * from gt1 where a=200000;
+explain (costs off) select * from gt1 where a*10=300;
+explain (costs off) select * from gt1 where a*10=3;
+analyze gt1;
+explain (costs off) select * from gt1 where a=1;
+explain (costs off) select * from gt1 where a=200000;
+explain (costs off) select * from gt1 where a*10=300;
+explain (costs off) select * from gt1 where a*10=3;
+
+--ok
+create global temp table gtt_test1(c1 int) with(on_commit_delete_rows='1');
+create global temp table gtt_test2(c1 int) with(on_commit_delete_rows='0');
+create global temp table gtt_test3(c1 int) with(on_commit_delete_rows='t');
+create global temp table gtt_test4(c1 int) with(on_commit_delete_rows='f');
+create global temp table gtt_test5(c1 int) with(on_commit_delete_rows='yes');
+create global temp table gtt_test6(c1 int) with(on_commit_delete_rows='no');
+create global temp table gtt_test7(c1 int) with(on_commit_delete_rows='y');
+create global temp table gtt_test8(c1 int) with(on_commit_delete_rows='n');
+
+--error
+create global temp table gtt_test9(c1 int) with(on_commit_delete_rows='tr');
+create global temp table gtt_test10(c1 int) with(on_commit_delete_rows='ye');
+
+reset search_path;
+
+drop schema gtt_function cascade;
+
diff --git a/src/test/regress/sql/gtt_parallel_1.sql b/src/test/regress/sql/gtt_parallel_1.sql
new file mode 100644
index 0000000000..d05745e313
--- /dev/null
+++ b/src/test/regress/sql/gtt_parallel_1.sql
@@ -0,0 +1,44 @@
+
+
+set search_path=gtt,sys;
+
+select nextval('gtt_with_seq_c2_seq');
+
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+
+begin;
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+commit;
+select * from gtt1 order by a;
+
+begin;
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+rollback;
+select * from gtt1 order by a;
+
+truncate gtt1;
+select * from gtt1 order by a;
+
+begin;
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+truncate gtt1;
+select * from gtt1 order by a;
+insert into gtt1 values(1, 'test1');
+rollback;
+select * from gtt1 order by a;
+
+begin;
+select * from gtt1 order by a;
+truncate gtt1;
+insert into gtt1 values(1, 'test1');
+select * from gtt1 order by a;
+truncate gtt1;
+commit;
+select * from gtt1 order by a;
+
+reset search_path;
+
diff --git a/src/test/regress/sql/gtt_parallel_2.sql b/src/test/regress/sql/gtt_parallel_2.sql
new file mode 100644
index 0000000000..81a60392c2
--- /dev/null
+++ b/src/test/regress/sql/gtt_parallel_2.sql
@@ -0,0 +1,154 @@
+
+
+set search_path=gtt,sys;
+
+insert into gtt3 values(1, 'test1');
+select * from gtt3 order by a;
+
+begin;
+insert into gtt3 values(2, 'test1');
+select * from gtt3 order by a;
+commit;
+select * from gtt3 order by a;
+
+begin;
+insert into gtt3 values(3, 'test1');
+select * from gtt3 order by a;
+rollback;
+select * from gtt3 order by a;
+
+truncate gtt3;
+select * from gtt3 order by a;
+
+insert into gtt3 values(1, 'test1');
+select * from gtt3 order by a;
+
+begin;
+insert into gtt3 values(2, 'test2');
+select * from gtt3 order by a;
+truncate gtt3;
+select * from gtt3 order by a;
+insert into gtt3 values(3, 'test3');
+update gtt3 set a = 3 where b = 'test1';
+select * from gtt3 order by a;
+rollback;
+select * from gtt3 order by a;
+
+begin;
+select * from gtt3 order by a;
+truncate gtt3;
+insert into gtt3 values(5, 'test5');
+select * from gtt3 order by a;
+truncate gtt3;
+insert into gtt3 values(6, 'test6');
+commit;
+select * from gtt3 order by a;
+
+truncate gtt3;
+insert into gtt3 values(1);
+select * from gtt3;
+begin;
+insert into gtt3 values(2);
+select * from gtt3;
+SAVEPOINT save1;
+truncate gtt3;
+insert into gtt3 values(3);
+select * from gtt3;
+SAVEPOINT save2;
+truncate gtt3;
+insert into gtt3 values(4);
+select * from gtt3;
+SAVEPOINT save3;
+rollback to savepoint save2;
+Select * from gtt3;
+insert into gtt3 values(5);
+select * from gtt3;
+rollback;
+select * from gtt3;
+
+truncate gtt3;
+insert into gtt3 values(1);
+select * from gtt3;
+begin;
+insert into gtt3 values(2);
+select * from gtt3;
+SAVEPOINT save1;
+truncate gtt3;
+insert into gtt3 values(3);
+select * from gtt3;
+SAVEPOINT save2;
+truncate gtt3;
+insert into gtt3 values(4);
+select * from gtt3;
+SAVEPOINT save3;
+rollback to savepoint save2;
+Select * from gtt3;
+insert into gtt3 values(5);
+select * from gtt3;
+commit;
+select * from gtt3;
+
+truncate gtt3;
+insert into gtt3 values(generate_series(1,100000), 'testing');
+select count(*) from gtt3;
+analyze gtt3;
+explain (COSTS FALSE) select * from gtt3 where a =300;
+
+insert into gtt_t_kenyon select generate_series(1,2000),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',500);
+insert into gtt_t_kenyon select generate_series(1,2),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',2000);
+insert into gtt_t_kenyon select generate_series(3,4),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',4000);
+insert into gtt_t_kenyon select generate_series(5,6),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',5500);
+select relname, pg_relation_size(oid),pg_relation_size(reltoastrelid),pg_table_size(oid),pg_indexes_size(oid),pg_total_relation_size(oid) from pg_class where relname = 'gtt_t_kenyon';
+select relname from pg_class where relname = 'gtt_t_kenyon' and reltoastrelid != 0;
+
+select
+c.relname, pg_relation_size(c.oid),pg_table_size(c.oid),pg_total_relation_size(c.oid)
+from
+pg_class c
+where
+c.oid in
+(
+select
+i.indexrelid as indexrelid
+from
+pg_index i ,pg_class cc
+where cc.relname = 'gtt_t_kenyon' and cc.oid = i.indrelid
+)
+order by c.relname;
+
+select count(*) from gtt_t_kenyon;
+begin;
+cluster gtt_t_kenyon using idx_gtt_t_kenyon_1;
+commit;
+select count(*) from gtt_t_kenyon;
+
+begin;
+cluster gtt_t_kenyon using idx_gtt_t_kenyon_1;
+rollback;
+select count(*) from gtt_t_kenyon;
+
+vacuum full gtt_t_kenyon;
+select count(*) from gtt_t_kenyon;
+
+begin;
+truncate gtt_t_kenyon;
+insert into gtt_t_kenyon select generate_series(1,2000),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',500);
+cluster gtt_t_kenyon using idx_gtt_t_kenyon_1;
+commit;
+select count(*) from gtt_t_kenyon;
+
+insert into gtt_t_kenyon select generate_series(1,2),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',2000);
+insert into gtt_t_kenyon select generate_series(3,4),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',4000);
+insert into gtt_t_kenyon select generate_series(5,6),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God,Remark here!!',5500);
+begin;
+truncate gtt_t_kenyon;
+insert into gtt_t_kenyon select generate_series(1,2000),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',500);
+cluster gtt_t_kenyon using idx_gtt_t_kenyon_1;
+rollback;
+select count(*) from gtt_t_kenyon;
+
+insert into gtt_with_seq (c1) values(1);
+select * from gtt_with_seq;
+
+reset search_path;
+
diff --git a/src/test/regress/sql/gtt_prepare.sql b/src/test/regress/sql/gtt_prepare.sql
new file mode 100644
index 0000000000..dbe84d1b80
--- /dev/null
+++ b/src/test/regress/sql/gtt_prepare.sql
@@ -0,0 +1,19 @@
+
+CREATE SCHEMA IF NOT EXISTS gtt;
+
+set search_path=gtt,sys;
+
+create global temp table gtt1(a int primary key, b text) on commit delete rows;
+
+create global temp table gtt2(a int primary key, b text) on commit delete rows;
+
+create global temp table gtt3(a int primary key, b text);
+
+create global temp table gtt_t_kenyon(id int,vname varchar(48),remark text) on commit PRESERVE rows;
+create index idx_gtt_t_kenyon_1 on gtt_t_kenyon(id);
+create index idx_gtt_t_kenyon_2 on gtt_t_kenyon(remark);
+
+CREATE GLOBAL TEMPORARY TABLE gtt_with_seq(c1 bigint, c2 bigserial) on commit PRESERVE rows;
+
+reset search_path;
+
diff --git a/src/test/regress/sql/gtt_stats.sql b/src/test/regress/sql/gtt_stats.sql
new file mode 100644
index 0000000000..d61b0ff828
--- /dev/null
+++ b/src/test/regress/sql/gtt_stats.sql
@@ -0,0 +1,46 @@
+
+CREATE SCHEMA IF NOT EXISTS gtt_stats;
+
+set search_path=gtt_stats,sys;
+
+-- expect 0
+select count(*) from pg_gtt_attached_pids;
+
+-- expect 0
+select count(*) from pg_list_gtt_relfrozenxids();
+
+create global temp table gtt_stats.gtt(a int primary key, b text) on commit PRESERVE rows;
+-- expect 0
+select count(*) from pg_gtt_attached_pids;
+
+-- expect 0
+select count(*) from pg_list_gtt_relfrozenxids();
+
+insert into gtt values(generate_series(1,10000),'test');
+
+-- expect 1
+select count(*) from pg_gtt_attached_pids;
+
+-- expect 2
+select count(*) from pg_list_gtt_relfrozenxids();
+
+-- expect 2
+select schemaname, tablename, relpages, reltuples, relallvisible from pg_gtt_relstats where schemaname = 'gtt_stats' order by tablename;
+
+-- expect 0
+select * from pg_gtt_stats order by tablename;
+
+reindex table gtt;
+
+reindex index gtt_pkey;
+
+analyze gtt;
+
+select schemaname, tablename, relpages, reltuples, relallvisible from pg_gtt_relstats where schemaname = 'gtt_stats' order by tablename;
+
+select * from pg_gtt_stats order by tablename;
+
+reset search_path;
+
+drop schema gtt_stats cascade;
+
-- 
2.27.0