0004-gtt-v63-regress.patch
application/octet-stream
Filename: 0004-gtt-v63-regress.patch
Type: application/octet-stream
Part: 2
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 v63-0004
| File | + | − |
|---|---|---|
| src/test/isolation/expected/gtt-sequence.out | 48 | 0 |
| src/test/isolation/expected/gtt-table.out | 675 | 0 |
| src/test/isolation/isolation_schedule | 2 | 0 |
| src/test/isolation/isolationtester.c | 40 | 1 |
| src/test/isolation/isolationtester.h | 2 | 0 |
| src/test/isolation/specparse.y | 23 | 9 |
| src/test/isolation/specscanner.l | 2 | 0 |
| src/test/isolation/specs/gtt-sequence.spec | 39 | 0 |
| src/test/isolation/specs/gtt-table.spec | 135 | 0 |
| src/test/regress/expected/global_temporary_table.out | 574 | 0 |
| src/test/regress/expected/rules.out | 88 | 0 |
| src/test/regress/parallel_schedule | 3 | 0 |
| src/test/regress/sql/global_temporary_table.sql | 313 | 0 |
diff --git a/src/test/isolation/expected/gtt-sequence.out b/src/test/isolation/expected/gtt-sequence.out
new file mode 100644
index 00000000000..31db2ebd423
--- /dev/null
+++ b/src/test/isolation/expected/gtt-sequence.out
@@ -0,0 +1,48 @@
+unused step name: s1_seq_restart
+Parsed test spec with 2 sessions
+
+starting permutation: s1_seq_next s2_seq_next s1_seq_next
+step s1_seq_next: select nextval('gtt_with_seq_c2_seq');
+nextval
+-------
+ 1
+(1 row)
+
+step s2_seq_next: select nextval('gtt_with_seq_c2_seq');
+nextval
+-------
+ 1
+(1 row)
+
+step s1_seq_next: select nextval('gtt_with_seq_c2_seq');
+nextval
+-------
+ 2
+(1 row)
+
+
+starting permutation: s1_select s2_select s1_insert s2_insert s1_select s2_select
+step s1_select: select * from gtt_with_seq order by c1,c2;
+c1|c2
+--+--
+(0 rows)
+
+step s2_select: select * from gtt_with_seq order by c1,c2;
+c1|c2
+--+--
+(0 rows)
+
+step s1_insert: insert into gtt_with_seq values(1);
+step s2_insert: insert into gtt_with_seq values(10);
+step s1_select: select * from gtt_with_seq order by c1,c2;
+c1|c2
+--+--
+ 1| 3
+(1 row)
+
+step s2_select: select * from gtt_with_seq order by c1,c2;
+c1|c2
+--+--
+10| 1
+(1 row)
+
diff --git a/src/test/isolation/expected/gtt-table.out b/src/test/isolation/expected/gtt-table.out
new file mode 100644
index 00000000000..5825773aa12
--- /dev/null
+++ b/src/test/isolation/expected/gtt-table.out
@@ -0,0 +1,675 @@
+Parsed test spec with 3 sessions
+
+starting permutation: s1_update_d
+step s1_update_d: update gtt_on_commit_delete_row set b = 'update'
+
+starting permutation: s1_select_d s1_insert_d s1_select_d
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s1_select_d s1_begin s1_insert_d s1_select_d s1_commit s1_select_d
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_begin: begin
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+1|test1
+(1 row)
+
+step s1_commit: commit
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s1_select_d s1_begin s1_insert_d s1_select_d s1_rollback s1_select_d
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_begin: begin
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+1|test1
+(1 row)
+
+step s1_rollback: rollback
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s1_select_d s1_insert_d s1_select_d s1_truncate_d s1_select_d
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_truncate_d: truncate gtt_on_commit_delete_row
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s1_select_d s1_insert_d s1_begin s1_insert_d s1_select_d s1_truncate_d s1_select_d s1_insert_d s1_select_d s1_commit s1_select_d
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_begin: begin
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+2|test1
+(1 row)
+
+step s1_truncate_d: truncate gtt_on_commit_delete_row
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+3|test1
+(1 row)
+
+step s1_commit: commit
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s1_select_d s1_insert_d s1_begin s1_insert_d s1_select_d s1_truncate_d s1_select_d s1_insert_d s1_select_d s1_rollback s1_select_d
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_begin: begin
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+2|test1
+(1 row)
+
+step s1_truncate_d: truncate gtt_on_commit_delete_row
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+3|test1
+(1 row)
+
+step s1_rollback: rollback
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s1_insert_d s1_select_d s1_begin s1_insert_d s1_select_d s1_save_1 s1_truncate_d s1_insert_d s1_select_d s1_save_2 s1_truncate_d s1_insert_d s1_select_d s1_save_3 s1_rollback_to_save_2 s1_select_d s1_insert_d s1_select_d s1_commit s1_select_d
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_begin: begin
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+2|test1
+(1 row)
+
+step s1_save_1: SAVEPOINT save1
+step s1_truncate_d: truncate gtt_on_commit_delete_row
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+3|test1
+(1 row)
+
+step s1_save_2: SAVEPOINT save2
+step s1_truncate_d: truncate gtt_on_commit_delete_row
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+4|test1
+(1 row)
+
+step s1_save_3: SAVEPOINT save3
+step s1_rollback_to_save_2: rollback to savepoint save2
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+3|test1
+(1 row)
+
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+3|test1
+5|test1
+(2 rows)
+
+step s1_commit: commit
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s1_insert_d s1_select_d s1_begin s1_insert_d s1_select_d s1_save_1 s1_truncate_d s1_insert_d s1_select_d s1_save_2 s1_truncate_d s1_insert_d s1_select_d s1_save_3 s1_rollback_to_save_2 s1_select_d s1_insert_d s1_select_d s1_rollback s1_select_d
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s1_begin: begin
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+2|test1
+(1 row)
+
+step s1_save_1: SAVEPOINT save1
+step s1_truncate_d: truncate gtt_on_commit_delete_row
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+3|test1
+(1 row)
+
+step s1_save_2: SAVEPOINT save2
+step s1_truncate_d: truncate gtt_on_commit_delete_row
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+4|test1
+(1 row)
+
+step s1_save_3: SAVEPOINT save3
+step s1_rollback_to_save_2: rollback to savepoint save2
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+3|test1
+(1 row)
+
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-----
+3|test1
+5|test1
+(2 rows)
+
+step s1_rollback: rollback
+step s1_select_d: select a,b from gtt_on_commit_delete_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s2_update_p
+step s2_update_p: update gtt_on_commit_preserve_row set b = 'update'
+
+starting permutation: s2_select_p s2_insert_p s2_select_p
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+
+starting permutation: s2_select_p s2_begin s2_insert_p s2_select_p s2_commit s2_select_p
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s2_begin: begin
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+step s2_commit: commit
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+
+starting permutation: s2_select_p s2_begin s2_insert_p s2_select_p s2_rollback s2_select_p
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s2_begin: begin
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+step s2_rollback: rollback
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s2_select_p s2_insert_p s2_select_p s2_truncate_p s2_select_p
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+step s2_truncate_p: truncate gtt_on_commit_preserve_row
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s2_select_p s2_insert_p s2_begin s2_insert_p s2_select_p s2_truncate_p s2_select_p s2_insert_p s2_select_p s2_commit s2_select_p
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_begin: begin
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+2|test10
+(2 rows)
+
+step s2_truncate_p: truncate gtt_on_commit_preserve_row
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+(1 row)
+
+step s2_commit: commit
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+(1 row)
+
+
+starting permutation: s2_select_p s2_insert_p s2_begin s2_insert_p s2_select_p s2_truncate_p s2_select_p s2_insert_p s2_select_p s2_rollback s2_select_p
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_begin: begin
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+2|test10
+(2 rows)
+
+step s2_truncate_p: truncate gtt_on_commit_preserve_row
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+(1 row)
+
+step s2_rollback: rollback
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+
+starting permutation: s2_insert_p s2_select_p s2_begin s2_insert_p s2_select_p s2_save_1 s2_truncate_p s2_insert_p s2_select_p s2_save_2 s2_truncate_p s2_insert_p s2_select_p s2_save_3 s2_rollback_to_save_2 s2_select_p s2_insert_p s2_select_p s2_commit s2_select_p
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+step s2_begin: begin
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+2|test10
+(2 rows)
+
+step s2_save_1: SAVEPOINT save1
+step s2_truncate_p: truncate gtt_on_commit_preserve_row
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+(1 row)
+
+step s2_save_2: SAVEPOINT save2
+step s2_truncate_p: truncate gtt_on_commit_preserve_row
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+4|test10
+(1 row)
+
+step s2_save_3: SAVEPOINT save3
+step s2_rollback_to_save_2: rollback to savepoint save2
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+(1 row)
+
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+5|test10
+(2 rows)
+
+step s2_commit: commit
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+5|test10
+(2 rows)
+
+
+starting permutation: s2_insert_p s2_select_p s2_begin s2_insert_p s2_select_p s2_save_1 s2_truncate_p s2_insert_p s2_select_p s2_save_2 s2_truncate_p s2_insert_p s2_select_p s2_save_3 s2_rollback_to_save_2 s2_select_p s2_insert_p s2_select_p s2_rollback s2_select_p
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+step s2_begin: begin
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+2|test10
+(2 rows)
+
+step s2_save_1: SAVEPOINT save1
+step s2_truncate_p: truncate gtt_on_commit_preserve_row
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+(1 row)
+
+step s2_save_2: SAVEPOINT save2
+step s2_truncate_p: truncate gtt_on_commit_preserve_row
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+4|test10
+(1 row)
+
+step s2_save_3: SAVEPOINT save3
+step s2_rollback_to_save_2: rollback to savepoint save2
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+(1 row)
+
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+3|test10
+5|test10
+(2 rows)
+
+step s2_rollback: rollback
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+
+starting permutation: s1_insert_p s2_insert_p s1_select_p s2_select_p
+step s1_insert_p: insert into gtt_on_commit_preserve_row (b) values('test20')
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s1_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test20
+(1 row)
+
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+
+starting permutation: s1_begin s2_begin s1_insert_p s2_insert_p s1_truncate_p s2_truncate_p s1_commit s2_commit s1_select_p s2_select_p
+step s1_begin: begin
+step s2_begin: begin
+step s1_insert_p: insert into gtt_on_commit_preserve_row (b) values('test20')
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s1_truncate_p: truncate gtt_on_commit_preserve_row
+step s2_truncate_p: truncate gtt_on_commit_preserve_row
+step s1_commit: commit
+step s2_commit: commit
+step s1_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+-
+(0 rows)
+
+
+starting permutation: s1_begin s1_insert_d s2_insert_d s1_truncate_d s2_insert_d s1_commit
+step s1_begin: begin
+step s1_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s2_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_truncate_d: truncate gtt_on_commit_delete_row
+step s2_insert_d: insert into gtt_on_commit_delete_row (b) values('test1')
+step s1_commit: commit
+
+starting permutation: s1_begin s2_begin s1_insert_p s2_insert_p s1_reindex_p s2_reindex_p s1_commit s2_commit s1_select_p s2_select_p
+step s1_begin: begin
+step s2_begin: begin
+step s1_insert_p: insert into gtt_on_commit_preserve_row (b) values('test20')
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s1_reindex_p: reindex table gtt_on_commit_preserve_row
+step s2_reindex_p: reindex table gtt_on_commit_preserve_row
+step s1_commit: commit
+step s2_commit: commit
+step s1_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test20
+(1 row)
+
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+
+starting permutation: s1_begin s2_begin s1_insert_p s2_insert_p s1_reindex_i_p s2_reindex_i_p s1_commit s2_commit s1_select_p s2_select_p
+step s1_begin: begin
+step s2_begin: begin
+step s1_insert_p: insert into gtt_on_commit_preserve_row (b) values('test20')
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s1_reindex_i_p: reindex index gtt_on_commit_preserve_row_pkey
+step s2_reindex_i_p: reindex index gtt_on_commit_preserve_row_pkey
+step s1_commit: commit
+step s2_commit: commit
+step s1_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test20
+(1 row)
+
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
+
+starting permutation: s2_insert_c s3_create_c s3_insert_c s1_insert_c s1_analyze_c s2_analyze_c s3_analyze_c s1_select_c s2_select_c s3_select_c
+step s2_insert_c: insert into gtt_test_createindex(a,b) values(generate_series(1,100000),'test create index')
+step s3_create_c: create unique index idx_temp_table_a on gtt_test_createindex(a)
+step s3_insert_c: insert into gtt_test_createindex(a,b) values(generate_series(1,100000),'test create index')
+step s1_insert_c: insert into gtt_test_createindex(a,b) values(generate_series(1,100000),'test create index')
+step s1_analyze_c: analyze gtt_test_createindex
+step s2_analyze_c: analyze gtt_test_createindex
+step s3_analyze_c: analyze gtt_test_createindex
+step s1_select_c: explain (costs off) select * from gtt_test_createindex where a = 1
+QUERY PLAN
+---------------------------------------------------------
+Index Scan using idx_temp_table_a on gtt_test_createindex
+ Index Cond: (a = 1)
+(2 rows)
+
+step s2_select_c: explain (costs off) select * from gtt_test_createindex where a = 1
+QUERY PLAN
+--------------------------------
+Seq Scan on gtt_test_createindex
+ Filter: (a = 1)
+(2 rows)
+
+step s3_select_c: explain (costs off) select * from gtt_test_createindex where a = 1
+QUERY PLAN
+---------------------------------------------------------
+Index Scan using idx_temp_table_a on gtt_test_createindex
+ Index Cond: (a = 1)
+(2 rows)
+
+
+starting permutation: s1_begin s2_begin s1_lock_p s2_lock_p s1_truncate_p s2_truncate_p s1_insert_p s2_insert_p s1_commit s2_commit s1_select_p s2_select_p
+step s1_begin: begin
+step s2_begin: begin
+step s1_lock_p: LOCK TABLE gtt_on_commit_preserve_row in ACCESS EXCLUSIVE MODE
+step s2_lock_p: LOCK TABLE gtt_on_commit_preserve_row in ACCESS EXCLUSIVE MODE
+step s1_truncate_p: truncate gtt_on_commit_preserve_row
+step s2_truncate_p: truncate gtt_on_commit_preserve_row
+step s1_insert_p: insert into gtt_on_commit_preserve_row (b) values('test20')
+step s2_insert_p: insert into gtt_on_commit_preserve_row (b) values('test10')
+step s1_commit: commit
+step s2_commit: commit
+step s1_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test20
+(1 row)
+
+step s2_select_p: select a,b from gtt_on_commit_preserve_row order by a,b
+a|b
+-+------
+1|test10
+(1 row)
+
diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule
index 99c23b16ffe..f5c8eec533d 100644
--- a/src/test/isolation/isolation_schedule
+++ b/src/test/isolation/isolation_schedule
@@ -97,3 +97,5 @@ test: plpgsql-toast
test: truncate-conflict
test: serializable-parallel
test: serializable-parallel-2
+test: gtt-sequence
+test: gtt-table
diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index 12179f25146..7cf0b20e636 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -80,9 +80,30 @@ disconnect_atexit(void)
{
int i;
- for (i = 0; i < nconns; i++)
+ for (i = 1; i < nconns; i++)
if (conns[i].conn)
PQfinish(conns[i].conn);
+
+ if (parseresult.destroy)
+ {
+ PGresult *res;
+
+ res = PQexec(conns[0].conn, parseresult.destroy);
+ if (PQresultStatus(res) == PGRES_TUPLES_OK)
+ {
+ printResultSet(res);
+ }
+ else if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "destroy failed: %s",
+ PQerrorMessage(conns[0].conn));
+ /* don't exit on teardown failure */
+ }
+ PQclear(res);
+ }
+
+ if (conns[0].conn)
+ PQfinish(conns[0].conn);
}
int
@@ -238,6 +259,24 @@ main(int argc, char **argv)
PQclear(res);
termPQExpBuffer(&wait_query);
+ if (parseresult.initialize)
+ {
+ PGresult *res;
+
+ res = PQexec(conns[0].conn, parseresult.initialize);
+ if (PQresultStatus(res) == PGRES_TUPLES_OK)
+ {
+ printResultSet(res);
+ }
+ else if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "initialize failed: %s",
+ PQerrorMessage(conns[0].conn));
+ /* don't exit on teardown failure */
+ }
+ PQclear(res);
+ }
+
/*
* Run the permutations specified in the spec, or all if none were
* explicitly specified.
diff --git a/src/test/isolation/isolationtester.h b/src/test/isolation/isolationtester.h
index 5f300219c20..b5a29893da9 100644
--- a/src/test/isolation/isolationtester.h
+++ b/src/test/isolation/isolationtester.h
@@ -81,6 +81,8 @@ typedef struct
int nsessions;
Permutation **permutations;
int npermutations;
+ char *initialize;
+ char *destroy;
} TestSpec;
extern TestSpec parseresult;
diff --git a/src/test/isolation/specparse.y b/src/test/isolation/specparse.y
index c25aa1a73fa..2784f758ed9 100644
--- a/src/test/isolation/specparse.y
+++ b/src/test/isolation/specparse.y
@@ -39,7 +39,7 @@ TestSpec parseresult; /* result of parsing is left here */
}
%type <ptr_list> setup_list
-%type <str> opt_setup opt_teardown
+%type <str> opt_setup opt_teardown opt_initialize opt_destroy
%type <str> setup
%type <ptr_list> step_list session_list permutation_list opt_permutation_list
%type <ptr_list> permutation_step_list blocker_list
@@ -51,23 +51,27 @@ TestSpec parseresult; /* result of parsing is left here */
%token <str> sqlblock identifier
%token <integer> INTEGER
-%token NOTICES PERMUTATION SESSION SETUP STEP TEARDOWN TEST
+%token NOTICES PERMUTATION SESSION SETUP STEP TEARDOWN TEST INITIALIZE DESTROY
%%
TestSpec:
+ opt_initialize
setup_list
opt_teardown
+ opt_destroy
session_list
opt_permutation_list
{
- parseresult.setupsqls = (char **) $1.elements;
- parseresult.nsetupsqls = $1.nelements;
- parseresult.teardownsql = $2;
- parseresult.sessions = (Session **) $3.elements;
- parseresult.nsessions = $3.nelements;
- parseresult.permutations = (Permutation **) $4.elements;
- parseresult.npermutations = $4.nelements;
+ parseresult.setupsqls = (char **) $2.elements;
+ parseresult.nsetupsqls = $2.nelements;
+ parseresult.teardownsql = $3;
+ parseresult.sessions = (Session **) $5.elements;
+ parseresult.nsessions = $5.nelements;
+ parseresult.permutations = (Permutation **) $6.elements;
+ parseresult.npermutations = $6.nelements;
+ parseresult.initialize = $1;
+ parseresult.destroy = $4;
}
;
@@ -100,6 +104,16 @@ opt_teardown:
| TEARDOWN sqlblock { $$ = $2; }
;
+opt_initialize:
+ /* EMPTY */ { $$ = NULL; }
+ | INITIALIZE sqlblock { $$ = $2; }
+ ;
+
+opt_destroy:
+ /* EMPTY */ { $$ = NULL; }
+ | DESTROY sqlblock { $$ = $2; }
+ ;
+
session_list:
session_list session
{
diff --git a/src/test/isolation/specs/gtt-sequence.spec b/src/test/isolation/specs/gtt-sequence.spec
new file mode 100644
index 00000000000..88eece45e29
--- /dev/null
+++ b/src/test/isolation/specs/gtt-sequence.spec
@@ -0,0 +1,39 @@
+# Tests for global temporary relations
+
+initialize
+{
+ CREATE GLOBAL TEMPORARY TABLE if not exists gtt_with_seq(c1 bigint, c2 bigserial) on commit PRESERVE rows;
+}
+
+destroy
+{
+ /* wait other backend exit */
+ select pg_sleep(1);
+
+ DROP TABLE gtt_with_seq;
+}
+
+# Session 1
+session "s1"
+step "s1_seq_next" { select nextval('gtt_with_seq_c2_seq'); }
+step "s1_seq_restart" { alter sequence gtt_with_seq_c2_seq RESTART; }
+step "s1_insert" { insert into gtt_with_seq values(1); }
+step "s1_select" { select * from gtt_with_seq order by c1,c2; }
+teardown
+{
+ TRUNCATE gtt_with_seq;
+}
+
+# Session 2
+session "s2"
+step "s2_seq_next" { select nextval('gtt_with_seq_c2_seq'); }
+step "s2_insert" { insert into gtt_with_seq values(10); }
+step "s2_select" { select * from gtt_with_seq order by c1,c2; }
+teardown
+{
+ TRUNCATE gtt_with_seq RESTART IDENTITY;
+}
+
+permutation "s1_seq_next" "s2_seq_next" "s1_seq_next"
+permutation "s1_select" "s2_select" "s1_insert" "s2_insert" "s1_select" "s2_select"
+
diff --git a/src/test/isolation/specs/gtt-table.spec b/src/test/isolation/specs/gtt-table.spec
new file mode 100644
index 00000000000..e0396b21ef0
--- /dev/null
+++ b/src/test/isolation/specs/gtt-table.spec
@@ -0,0 +1,135 @@
+# Tests for global temporary relations
+
+initialize
+{
+ create global temp table gtt_on_commit_delete_row(a bigserial primary key, b text) on commit delete rows;
+ create global temp table gtt_on_commit_preserve_row(a bigserial primary key, b text) on commit preserve rows;
+ create global temp table gtt_test_createindex(a int, b char(1000)) on commit preserve rows;
+}
+
+destroy
+{
+ /* wait other backend exit */
+ select pg_sleep(1);
+
+ DROP TABLE gtt_on_commit_delete_row;
+ DROP TABLE gtt_on_commit_preserve_row;
+ DROP TABLE gtt_test_createindex;
+}
+
+# Session 1
+session "s1"
+step "s1_begin" {begin}
+step "s1_commit" {commit}
+step "s1_rollback" {rollback}
+step "s1_insert_d" {insert into gtt_on_commit_delete_row (b) values('test1')}
+step "s1_select_d" {select a,b from gtt_on_commit_delete_row order by a,b}
+step "s1_insert_p" {insert into gtt_on_commit_preserve_row (b) values('test20')}
+step "s1_select_p" {select a,b from gtt_on_commit_preserve_row order by a,b}
+step "s1_truncate_d" {truncate gtt_on_commit_delete_row}
+step "s1_truncate_p" {truncate gtt_on_commit_preserve_row}
+step "s1_lock_p" {LOCK TABLE gtt_on_commit_preserve_row in ACCESS EXCLUSIVE MODE}
+step "s1_update_d" {update gtt_on_commit_delete_row set b = 'update'}
+step "s1_save_1" {SAVEPOINT save1}
+step "s1_save_2" {SAVEPOINT save2}
+step "s1_save_3" {SAVEPOINT save3}
+step "s1_rollback_to_save_2" {rollback to savepoint save2}
+step "s1_reindex_p" {reindex table gtt_on_commit_preserve_row}
+step "s1_reindex_i_p" {reindex index gtt_on_commit_preserve_row_pkey}
+step "s1_insert_c" {insert into gtt_test_createindex(a,b) values(generate_series(1,100000),'test create index')}
+step "s1_select_c" {explain (costs off) select * from gtt_test_createindex where a = 1}
+step "s1_analyze_c" {analyze gtt_test_createindex}
+teardown
+{
+ TRUNCATE gtt_on_commit_delete_row RESTART IDENTITY;
+ TRUNCATE gtt_on_commit_preserve_row RESTART IDENTITY;
+}
+
+# Session 2
+session "s2"
+step "s2_begin" {begin}
+step "s2_commit" {commit}
+step "s2_rollback" {rollback}
+step "s2_insert_p" {insert into gtt_on_commit_preserve_row (b) values('test10')}
+step "s2_select_p" {select a,b from gtt_on_commit_preserve_row order by a,b}
+step "s2_insert_d" {insert into gtt_on_commit_delete_row (b) values('test1')}
+step "s2_truncate_p" {truncate gtt_on_commit_preserve_row}
+step "s2_update_p" {update gtt_on_commit_preserve_row set b = 'update'}
+step "s2_lock_p" {LOCK TABLE gtt_on_commit_preserve_row in ACCESS EXCLUSIVE MODE}
+step "s2_save_1" {SAVEPOINT save1}
+step "s2_save_2" {SAVEPOINT save2}
+step "s2_save_3" {SAVEPOINT save3}
+step "s2_rollback_to_save_2" {rollback to savepoint save2}
+step "s2_reindex_p" {reindex table gtt_on_commit_preserve_row}
+step "s2_reindex_i_p" {reindex index gtt_on_commit_preserve_row_pkey}
+step "s2_insert_c" {insert into gtt_test_createindex(a,b) values(generate_series(1,100000),'test create index')}
+step "s2_select_c" {explain (costs off) select * from gtt_test_createindex where a = 1}
+step "s2_analyze_c" {analyze gtt_test_createindex}
+teardown
+{
+ TRUNCATE gtt_on_commit_delete_row RESTART IDENTITY;
+ TRUNCATE gtt_on_commit_preserve_row RESTART IDENTITY;
+}
+
+session "s3"
+step "s3_create_c" {create unique index idx_temp_table_a on gtt_test_createindex(a)}
+step "s3_insert_c" {insert into gtt_test_createindex(a,b) values(generate_series(1,100000),'test create index')}
+step "s3_select_c" {explain (costs off) select * from gtt_test_createindex where a = 1}
+step "s3_analyze_c" {analyze gtt_test_createindex}
+
+
+#
+# test on commit delete temp table
+#
+
+# test update empty temp table
+permutation "s1_update_d"
+# test insert into temp table
+permutation "s1_select_d" "s1_insert_d" "s1_select_d"
+# test temp table in transaction(commit)
+permutation "s1_select_d" "s1_begin" "s1_insert_d" "s1_select_d" "s1_commit" "s1_select_d"
+# test temp table in transaction(rollback)
+permutation "s1_select_d" "s1_begin" "s1_insert_d" "s1_select_d" "s1_rollback" "s1_select_d"
+# test truncate
+permutation "s1_select_d" "s1_insert_d" "s1_select_d" "s1_truncate_d" "s1_select_d"
+# test truncate in transaction block
+permutation "s1_select_d" "s1_insert_d" "s1_begin" "s1_insert_d" "s1_select_d" "s1_truncate_d" "s1_select_d" "s1_insert_d" "s1_select_d" "s1_commit" "s1_select_d"
+permutation "s1_select_d" "s1_insert_d" "s1_begin" "s1_insert_d" "s1_select_d" "s1_truncate_d" "s1_select_d" "s1_insert_d" "s1_select_d" "s1_rollback" "s1_select_d"
+# test temp table with subtransaction or savepoint
+permutation "s1_insert_d" "s1_select_d" "s1_begin" "s1_insert_d" "s1_select_d" "s1_save_1" "s1_truncate_d" "s1_insert_d" "s1_select_d" "s1_save_2" "s1_truncate_d" "s1_insert_d" "s1_select_d" "s1_save_3" "s1_rollback_to_save_2" "s1_select_d" "s1_insert_d" "s1_select_d" "s1_commit" "s1_select_d"
+permutation "s1_insert_d" "s1_select_d" "s1_begin" "s1_insert_d" "s1_select_d" "s1_save_1" "s1_truncate_d" "s1_insert_d" "s1_select_d" "s1_save_2" "s1_truncate_d" "s1_insert_d" "s1_select_d" "s1_save_3" "s1_rollback_to_save_2" "s1_select_d" "s1_insert_d" "s1_select_d" "s1_rollback" "s1_select_d"
+
+#
+# test on commit preserve table
+#
+
+# same as test on commit delete temp table
+permutation "s2_update_p"
+permutation "s2_select_p" "s2_insert_p" "s2_select_p"
+permutation "s2_select_p" "s2_begin" "s2_insert_p" "s2_select_p" "s2_commit" "s2_select_p"
+permutation "s2_select_p" "s2_begin" "s2_insert_p" "s2_select_p" "s2_rollback" "s2_select_p"
+permutation "s2_select_p" "s2_insert_p" "s2_select_p" "s2_truncate_p" "s2_select_p"
+permutation "s2_select_p" "s2_insert_p" "s2_begin" "s2_insert_p" "s2_select_p" "s2_truncate_p" "s2_select_p" "s2_insert_p" "s2_select_p" "s2_commit" "s2_select_p"
+permutation "s2_select_p" "s2_insert_p" "s2_begin" "s2_insert_p" "s2_select_p" "s2_truncate_p" "s2_select_p" "s2_insert_p" "s2_select_p" "s2_rollback" "s2_select_p"
+permutation "s2_insert_p" "s2_select_p" "s2_begin" "s2_insert_p" "s2_select_p" "s2_save_1" "s2_truncate_p" "s2_insert_p" "s2_select_p" "s2_save_2" "s2_truncate_p" "s2_insert_p" "s2_select_p" "s2_save_3" "s2_rollback_to_save_2" "s2_select_p" "s2_insert_p" "s2_select_p" "s2_commit" "s2_select_p"
+permutation "s2_insert_p" "s2_select_p" "s2_begin" "s2_insert_p" "s2_select_p" "s2_save_1" "s2_truncate_p" "s2_insert_p" "s2_select_p" "s2_save_2" "s2_truncate_p" "s2_insert_p" "s2_select_p" "s2_save_3" "s2_rollback_to_save_2" "s2_select_p" "s2_insert_p" "s2_select_p" "s2_rollback" "s2_select_p"
+
+#
+# test concurrent operation on temp table
+#
+
+# test concurrent read
+permutation "s1_insert_p" "s2_insert_p" "s1_select_p" "s2_select_p"
+# test concurrent truncate
+permutation "s1_begin" "s2_begin" "s1_insert_p" "s2_insert_p" "s1_truncate_p" "s2_truncate_p" "s1_commit" "s2_commit" "s1_select_p" "s2_select_p"
+permutation "s1_begin" "s1_insert_d" "s2_insert_d" "s1_truncate_d" "s2_insert_d" "s1_commit"
+# test concurrent reindex table
+permutation "s1_begin" "s2_begin" "s1_insert_p" "s2_insert_p" "s1_reindex_p" "s2_reindex_p" "s1_commit" "s2_commit" "s1_select_p" "s2_select_p"
+# test concurrent reindex index
+permutation "s1_begin" "s2_begin" "s1_insert_p" "s2_insert_p" "s1_reindex_i_p" "s2_reindex_i_p" "s1_commit" "s2_commit" "s1_select_p" "s2_select_p"
+
+# test create index
+permutation "s2_insert_c" "s3_create_c" "s3_insert_c" "s1_insert_c" "s1_analyze_c" "s2_analyze_c" "s3_analyze_c" "s1_select_c" "s2_select_c" "s3_select_c"
+
+# test lock gtt
+permutation "s1_begin" "s2_begin" "s1_lock_p" "s2_lock_p" "s1_truncate_p" "s2_truncate_p" "s1_insert_p" "s2_insert_p" "s1_commit" "s2_commit" "s1_select_p" "s2_select_p"
diff --git a/src/test/isolation/specscanner.l b/src/test/isolation/specscanner.l
index d9fa6a5b54a..697db975479 100644
--- a/src/test/isolation/specscanner.l
+++ b/src/test/isolation/specscanner.l
@@ -67,6 +67,8 @@ session { return SESSION; }
setup { return SETUP; }
step { return STEP; }
teardown { return TEARDOWN; }
+initialize { return INITIALIZE; }
+destroy { return DESTROY; }
/* Whitespace and comments */
[\n] { yyline++; }
diff --git a/src/test/regress/expected/global_temporary_table.out b/src/test/regress/expected/global_temporary_table.out
new file mode 100644
index 00000000000..5adc58d77e1
--- /dev/null
+++ b/src/test/regress/expected/global_temporary_table.out
@@ -0,0 +1,574 @@
+--
+-- GLobal emparary table test case
+--
+CREATE SCHEMA IF NOT EXISTS global_temporary_table;
+set search_path=global_temporary_table,sys;
+--
+-- test create global temp table basic syntax
+--
+create global temp table gtt_on_commit_default(a int primary key, b text);
+create global temp table gtt_on_commit_delete(a int primary key, b text) on commit delete rows;
+create global temp table gtt_on_commit_delete2(n int) with (on_commit_delete_rows='true');
+create global temp table gtt_on_commit_preserve(a int primary key, b text) on commit PRESERVE rows;
+create global temp table gtt_test_rename(a int primary key, b text);
+create global temp table gtt_test_createindex(c0 tsvector,c1 varchar(100), c2 int);
+create global temp table gtt_test_alter(b text) with(on_commit_delete_rows=true);
+--
+-- test DML on global temp table
+--
+-- update empty temp table
+update gtt_on_commit_delete set b ='test';
+begin;
+insert into gtt_on_commit_delete values (1);
+update gtt_on_commit_delete set b ='test';
+-- should 1 row
+select * from gtt_on_commit_delete;
+ a | b
+---+------
+ 1 | test
+(1 row)
+
+commit;
+-- data delete after transaction commit
+-- should 0 row
+select * from gtt_on_commit_delete;
+ a | b
+---+---
+(0 rows)
+
+-- update empty temp table
+update gtt_on_commit_preserve set b ='test';
+insert into gtt_on_commit_preserve values (2);
+begin;
+insert into gtt_on_commit_preserve values (3);
+update gtt_on_commit_preserve set b ='test';
+-- should 2 row
+select * from gtt_on_commit_preserve order by a;
+ a | b
+---+------
+ 2 | test
+ 3 | test
+(2 rows)
+
+delete from gtt_on_commit_preserve where a=2;
+commit;
+-- should 1 row
+select * from gtt_on_commit_preserve order by a;
+ a | b
+---+------
+ 3 | test
+(1 row)
+
+begin;
+insert into gtt_on_commit_preserve values (4);
+-- temp table support truncate;
+truncate gtt_on_commit_preserve;
+select * from gtt_on_commit_preserve order by a;
+ a | b
+---+---
+(0 rows)
+
+rollback;
+-- should 1 row
+select * from gtt_on_commit_preserve order by a;
+ a | b
+---+------
+ 3 | test
+(1 row)
+
+--
+-- test unsupported global temp partition table
+--
+-- should fail
+CREATE global temp TABLE global_temp_partition_01 (
+id bigserial NOT NULL,
+cre_time timestamp without time zone,
+note varchar(30)
+) PARTITION BY RANGE (cre_time)
+on commit delete rows;
+ERROR: Only support global temporary regular table.
+CREATE TABLE regular_partition_01_2019 (
+id bigserial NOT NULL,
+cre_time timestamp without time zone,
+note varchar(30)
+);
+CREATE TABLE regular_partition01 (
+id bigserial NOT NULL,
+cre_time timestamp without time zone,
+note varchar(30)
+) PARTITION BY RANGE (cre_time);
+-- should fail
+CREATE global temp TABLE temp_partition01_2018
+PARTITION OF regular_partition01
+FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2019-01-01 00:00:00');
+ERROR: Not support global temporary partition table or inherit table.
+CREATE global temp TABLE global_temp_partition_01_2021 (
+id bigserial NOT NULL,
+cre_time timestamp without time zone,
+note varchar(30)
+)on commit delete rows;
+-- should fail
+ALTER TABLE regular_partition01 ATTACH PARTITION global_temp_partition_01_2021 FOR VALUES FROM ('2021-01-01 00:00:00') TO ('2022-01-01 00:00:00');
+ERROR: cannot attach a global temporary relation as partition of permanent relation "regular_partition01"
+--
+-- test unsupported inherit table
+--
+create table 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 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;
+-- should fail
+create global temp table temp_inherit() inherits (inherits_parent);
+ERROR: Not support global temporary partition table or inherit table.
+-- should fail
+create global temp table temp_inherit() inherits (inherits_parent_global_temp) on commit delete rows;
+ERROR: Not support global temporary partition table or inherit table.
+--
+-- test DDL on global temp table
+--
+create index idx_gtt_test_alter_b on gtt_test_alter (b);
+insert into gtt_test_alter values('test');
+alter table gtt_test_alter alter b type varchar;
+create index gtt_idx_1 on gtt_test_createindex using gin (c0);
+create index gtt_idx_2 on gtt_test_createindex using gist (c0);
+create index gtt_idx_3 on gtt_test_createindex using hash (c2);
+alter table gtt_test_rename rename to gtt_test_new;
+ALTER TABLE gtt_test_new ADD COLUMN address varchar(30);
+create index CONCURRENTLY idx_b on gtt_on_commit_default (b);
+cluster gtt_on_commit_default using gtt_on_commit_default_pkey;
+insert into gtt_on_commit_default values(1,'test');
+create global temp table gtt_test_alter1 (a int primary key,b text);
+alter table gtt_test_alter1 alter a type varchar;
+-- should fail
+alter table gtt_on_commit_default alter a type varchar;
+ERROR: Only support alter global temporary table in an empty context.
+HINT: Please create a new connection and execute ALTER TABLE on the new connection.
+-- should fail
+cluster gtt_on_commit_default using gtt_on_commit_default_pkey;
+ERROR: not support cluster global temporary table yet
+-- should fail
+create table gtt_on_commit_default(a int primary key, b text) on commit delete rows;
+ERROR: ON COMMIT can only be used on temporary tables
+-- should fail
+alter table gtt_on_commit_default SET TABLESPACE pg_default;
+ERROR: not support alter table set tablespace on global temporary table
+-- should fail
+alter table gtt_on_commit_default set ( on_commit_delete_rows='true');
+ERROR: table cannot add or modify on commit parameter by ALTER TABLE command.
+-- should fail
+create table gtt_on_commit_default(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
+-- should fail
+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();
+-- should fail
+alter table foo set (on_commit_delete_rows='true');
+ERROR: table cannot add or modify on commit parameter by ALTER TABLE command.
+-- should fail
+create global temp table gtt_on_commit_preserve(a int primary key, b text) on commit drop;
+ERROR: global temporary table not support on commit drop clause
+-- should fail
+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
+-- should fail
+CREATE MATERIALIZED VIEW mv_gtt_on_commit_default as select * from gtt_on_commit_default;
+ERROR: materialized views must not use global temporary tables or views
+-- test create table as select
+CREATE GLOBAL TEMPORARY TABLE test_create_table_as AS SELECT 1 AS a;
+-- test copy stmt
+create global temp table gtt_copytest (
+ c1 int,
+ "col with , comma" text,
+ "col with "" quote" int);
+copy gtt_copytest from stdin csv header;
+select count(*) from gtt_copytest;
+ count
+-------
+ 2
+(1 row)
+
+--
+-- test foreign key dependencies for global temp table
+--
+CREATE global temp TABLE temp_products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+CREATE global temp TABLE products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+CREATE global temp TABLE temp_orders (
+ order_id integer PRIMARY KEY,
+ product_no integer REFERENCES temp_products(product_no),
+ quantity integer
+)on commit delete rows;
+-- should fail
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ product_no integer REFERENCES temp_products(product_no),
+ quantity integer
+);
+ERROR: constraints on permanent tables may reference only permanent tables
+CREATE global temp TABLE temp_orders_2 (
+ order_id integer PRIMARY KEY,
+ product_no integer REFERENCES products(product_no),
+ quantity integer
+);
+--should fail
+insert into temp_orders values(1,1,1);
+ERROR: insert or update on table "temp_orders" violates foreign key constraint "temp_orders_product_no_fkey"
+DETAIL: Key (product_no)=(1) is not present in table "temp_products".
+insert into temp_products values(1,'test',1.0);
+begin;
+insert into temp_orders values(1,1,1);
+commit;
+-- should 1 row
+select count(*) from temp_products;
+ count
+-------
+ 1
+(1 row)
+
+-- should 0 row
+select count(*) from temp_orders;
+ count
+-------
+ 0
+(1 row)
+
+--
+-- test sequence on global temp table
+--
+create global temp table global_temp_with_serial (a SERIAL,b int);
+begin;
+set transaction_read_only = true;
+-- support insert data to temp table in read only transaction
+insert into global_temp_with_serial (b) values(1);
+select * from global_temp_with_serial;
+ a | b
+---+---
+ 1 | 1
+(1 row)
+
+commit;
+create sequence seq_1;
+CREATE GLOBAL TEMPORARY TABLE temp_table_with_sequence_oncommit_delete(c1 int PRIMARY KEY) ON COMMIT DELETE ROWS;
+CREATE GLOBAL TEMPORARY TABLE temp_table_with_sequence_oncommit_preserve(c1 int PRIMARY KEY) ON COMMIT PRESERVE ROWS;
+alter table temp_table_with_sequence_oncommit_delete add c2 int default nextval('seq_1');
+alter table temp_table_with_sequence_oncommit_preserve add c2 int default nextval('seq_1');
+begin;
+insert into temp_table_with_sequence_oncommit_delete (c1)values(1);
+insert into temp_table_with_sequence_oncommit_preserve (c1)values(2);
+insert into temp_table_with_sequence_oncommit_delete (c1)values(3);
+insert into temp_table_with_sequence_oncommit_preserve (c1)values(4);
+-- should 2 row
+select * from temp_table_with_sequence_oncommit_delete order by c1;
+ c1 | c2
+----+----
+ 1 | 1
+ 3 | 3
+(2 rows)
+
+commit;
+-- should 0 row
+select * from temp_table_with_sequence_oncommit_delete order by c1;
+ c1 | c2
+----+----
+(0 rows)
+
+-- should 2 row
+select * from temp_table_with_sequence_oncommit_preserve order by c1;
+ c1 | c2
+----+----
+ 2 | 2
+ 4 | 4
+(2 rows)
+
+--
+-- test statistics on temp table
+--
+create global temp table temp_table_test_statistics(a int);
+insert into temp_table_test_statistics values(generate_series(1,100000));
+create index idx_test_1 on temp_table_test_statistics (a);
+create index idx_test_2 on temp_table_test_statistics((a*10));
+explain (costs off) select * from temp_table_test_statistics where a=200000;
+ QUERY PLAN
+------------------------------------------------
+ Bitmap Heap Scan on temp_table_test_statistics
+ Recheck Cond: (a = 200000)
+ -> Bitmap Index Scan on idx_test_1
+ Index Cond: (a = 200000)
+(4 rows)
+
+explain (costs off) select * from temp_table_test_statistics where a*10=3;
+ QUERY PLAN
+------------------------------------------------
+ Bitmap Heap Scan on temp_table_test_statistics
+ Recheck Cond: ((a * 10) = 3)
+ -> Bitmap Index Scan on idx_test_2
+ Index Cond: ((a * 10) = 3)
+(4 rows)
+
+-- test statistic for whole row
+explain (costs off) select count(*) from temp_table_test_statistics group by temp_table_test_statistics;
+ QUERY PLAN
+----------------------------------------------
+ HashAggregate
+ Group Key: temp_table_test_statistics.*
+ -> Seq Scan on temp_table_test_statistics
+(3 rows)
+
+-- test statistic for system column
+explain (costs off) select count(*) from temp_table_test_statistics group by tableoid;
+ QUERY PLAN
+----------------------------------------------
+ HashAggregate
+ Group Key: tableoid
+ -> Seq Scan on temp_table_test_statistics
+(3 rows)
+
+analyze temp_table_test_statistics;
+-- indexscan by idx_test_1
+explain (costs off) select * from temp_table_test_statistics where a=200000;
+ QUERY PLAN
+----------------------------------------------------------------
+ Index Only Scan using idx_test_1 on temp_table_test_statistics
+ Index Cond: (a = 200000)
+(2 rows)
+
+-- indexscan by idx_test_2
+explain (costs off) select * from temp_table_test_statistics where a*10=3;
+ QUERY PLAN
+-----------------------------------------------------------
+ Index Scan using idx_test_2 on temp_table_test_statistics
+ Index Cond: ((a * 10) = 3)
+(2 rows)
+
+explain (costs off) select count(*) from temp_table_test_statistics group by temp_table_test_statistics;
+ QUERY PLAN
+----------------------------------------------
+ HashAggregate
+ Group Key: temp_table_test_statistics.*
+ -> Seq Scan on temp_table_test_statistics
+(3 rows)
+
+explain (costs off) select count(*) from temp_table_test_statistics group by tableoid;
+ QUERY PLAN
+----------------------------------------------
+ HashAggregate
+ Group Key: tableoid
+ -> Seq Scan on temp_table_test_statistics
+(3 rows)
+
+--
+-- test temp table with toast table
+--
+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);
+insert into gtt_t_kenyon select generate_series(1,2000),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',500);
+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 like '%t_kenyon%' order by relname;
+ relname | pg_relation_size | pg_relation_size | pg_table_size | pg_indexes_size | pg_total_relation_size
+--------------------+------------------+------------------+---------------+-----------------+------------------------
+ gtt_t_kenyon | 450560 | 0 | 483328 | 98304 | 581632
+ idx_gtt_t_kenyon_1 | 65536 | | 65536 | 0 | 65536
+ idx_gtt_t_kenyon_2 | 32768 | | 32768 | 0 | 32768
+(3 rows)
+
+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 like '%t_kenyon%' order by relname;
+ relname | pg_relation_size | pg_relation_size | pg_table_size | pg_indexes_size | pg_total_relation_size
+--------------------+------------------+------------------+---------------+-----------------+------------------------
+ gtt_t_kenyon | 450560 | 8192 | 499712 | 106496 | 606208
+ idx_gtt_t_kenyon_1 | 65536 | | 65536 | 0 | 65536
+ idx_gtt_t_kenyon_2 | 40960 | | 40960 | 0 | 40960
+(3 rows)
+
+begin;
+truncate gtt_t_kenyon;
+insert into gtt_t_kenyon select generate_series(1,10),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',10);
+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 like '%t_kenyon%' order by relname;
+ relname | pg_relation_size | pg_relation_size | pg_table_size | pg_indexes_size | pg_total_relation_size
+--------------------+------------------+------------------+---------------+-----------------+------------------------
+ gtt_t_kenyon | 8192 | 0 | 16384 | 32768 | 49152
+ idx_gtt_t_kenyon_1 | 16384 | | 16384 | 0 | 16384
+ idx_gtt_t_kenyon_2 | 16384 | | 16384 | 0 | 16384
+(3 rows)
+
+rollback;
+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 like '%t_kenyon%' order by relname;
+ relname | pg_relation_size | pg_relation_size | pg_table_size | pg_indexes_size | pg_total_relation_size
+--------------------+------------------+------------------+---------------+-----------------+------------------------
+ gtt_t_kenyon | 450560 | 8192 | 499712 | 106496 | 606208
+ idx_gtt_t_kenyon_1 | 65536 | | 65536 | 0 | 65536
+ idx_gtt_t_kenyon_2 | 40960 | | 40960 | 0 | 40960
+(3 rows)
+
+-- test analyze/vacuum on global temp table
+ANALYZE gtt_t_kenyon;
+VACUUM gtt_t_kenyon;
+--
+-- test global temp table system view
+--
+create global temp table temp_table_test_systemview(a int primary key, b text) on commit PRESERVE rows;
+-- should empty, storage not initialized
+select tablename from pg_gtt_attached_pids where tablename = 'temp_table_test_systemview';
+ tablename
+-----------
+(0 rows)
+
+-- should empty, storage not initialized
+select count(*) from pg_list_gtt_relfrozenxids();
+ count
+-------
+ 2
+(1 row)
+
+insert into temp_table_test_systemview values(generate_series(1,10000),'test');
+select tablename from pg_gtt_attached_pids where tablename = 'temp_table_test_systemview';
+ tablename
+----------------------------
+ temp_table_test_systemview
+(1 row)
+
+select count(*) from pg_list_gtt_relfrozenxids();
+ count
+-------
+ 2
+(1 row)
+
+select schemaname, tablename, relpages, reltuples, relallvisible from pg_gtt_relstats where tablename in('temp_table_test_systemview','temp_table_test_systemview_pkey') order by tablename;
+ schemaname | tablename | relpages | reltuples | relallvisible
+------------------------+---------------------------------+----------+-----------+---------------
+ global_temporary_table | temp_table_test_systemview | 0 | 0 | 0
+ global_temporary_table | temp_table_test_systemview_pkey | 1 | 0 | 0
+(2 rows)
+
+-- should empty
+select * from pg_gtt_stats where tablename = 'temp_table_test_systemview' 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)
+
+analyze temp_table_test_systemview;
+select schemaname, tablename, relpages, reltuples, relallvisible from pg_gtt_relstats where tablename in('temp_table_test_systemview','temp_table_test_systemview_pkey') order by tablename;
+ schemaname | tablename | relpages | reltuples | relallvisible
+------------------------+---------------------------------+----------+-----------+---------------
+ global_temporary_table | temp_table_test_systemview | 55 | 10000 | 0
+ global_temporary_table | temp_table_test_systemview_pkey | 30 | 10000 | 0
+(2 rows)
+
+-- get data after analyze;
+select * from pg_gtt_stats where tablename = 'temp_table_test_systemview' 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
+------------------------+----------------------------+---------+-----------+-----------+-----------+------------+------------------+-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-------------------+------------------------+----------------------
+ global_temporary_table | temp_table_test_systemview | 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 | | |
+ global_temporary_table | temp_table_test_systemview | b | f | 0 | 5 | 1 | {test} | {1} | | 1 | | |
+(2 rows)
+
+-- get all object info in current schema
+select relname ,relkind, relpersistence, reloptions from pg_class c, pg_namespace n where c.relnamespace = n.oid and n.nspname = 'global_temporary_table' order by relkind,relpersistence,relname;
+ relname | relkind | relpersistence | reloptions
+-------------------------------------------------+---------+----------------+-------------------------------
+ global_temp_partition_01_2021_id_seq | S | g | {on_commit_delete_rows=false}
+ global_temp_with_serial_a_seq | S | g | {on_commit_delete_rows=false}
+ regular_partition01_id_seq | S | p |
+ regular_partition_01_2019_id_seq | S | p |
+ seq_1 | S | p |
+ gtt_idx_1 | i | g |
+ gtt_idx_2 | i | g |
+ gtt_idx_3 | i | g |
+ gtt_on_commit_default_pkey | i | g |
+ gtt_on_commit_delete_pkey | i | g |
+ gtt_on_commit_preserve_pkey | i | g |
+ gtt_test_alter1_pkey | i | g |
+ gtt_test_rename_pkey | i | g |
+ idx_b | i | g |
+ idx_gtt_t_kenyon_1 | i | g |
+ idx_gtt_t_kenyon_2 | i | g |
+ idx_gtt_test_alter_b | i | g |
+ idx_test_1 | i | g |
+ idx_test_2 | i | g |
+ products_pkey | i | g |
+ temp_orders_2_pkey | i | g |
+ temp_orders_pkey | i | g |
+ temp_products_pkey | i | g |
+ temp_table_test_systemview_pkey | i | g |
+ temp_table_with_sequence_oncommit_delete_pkey | i | g |
+ temp_table_with_sequence_oncommit_preserve_pkey | i | g |
+ regular_partition01 | p | p |
+ global_temp_partition_01_2021 | r | g | {on_commit_delete_rows=true}
+ global_temp_with_serial | r | g | {on_commit_delete_rows=false}
+ gtt_copytest | r | g | {on_commit_delete_rows=false}
+ gtt_on_commit_default | r | g | {on_commit_delete_rows=false}
+ gtt_on_commit_delete | r | g | {on_commit_delete_rows=true}
+ gtt_on_commit_delete2 | r | g | {on_commit_delete_rows=true}
+ gtt_on_commit_preserve | r | g | {on_commit_delete_rows=false}
+ gtt_t_kenyon | r | g | {on_commit_delete_rows=false}
+ gtt_test_alter | r | g | {on_commit_delete_rows=true}
+ gtt_test_alter1 | r | g | {on_commit_delete_rows=false}
+ gtt_test_createindex | r | g | {on_commit_delete_rows=false}
+ gtt_test_new | r | g | {on_commit_delete_rows=false}
+ inherits_parent_global_temp | r | g | {on_commit_delete_rows=true}
+ products | r | g | {on_commit_delete_rows=false}
+ temp_orders | r | g | {on_commit_delete_rows=true}
+ temp_orders_2 | r | g | {on_commit_delete_rows=false}
+ temp_products | r | g | {on_commit_delete_rows=false}
+ temp_table_test_statistics | r | g | {on_commit_delete_rows=false}
+ temp_table_test_systemview | r | g | {on_commit_delete_rows=false}
+ temp_table_with_sequence_oncommit_delete | r | g | {on_commit_delete_rows=true}
+ temp_table_with_sequence_oncommit_preserve | r | g | {on_commit_delete_rows=false}
+ test_create_table_as | r | g | {on_commit_delete_rows=false}
+ foo | r | p |
+ inherits_parent | r | p |
+ regular_partition_01_2019 | r | p |
+(52 rows)
+
+reset search_path;
+drop schema global_temporary_table cascade;
+NOTICE: drop cascades to 27 other objects
+DETAIL: drop cascades to table global_temporary_table.gtt_on_commit_default
+drop cascades to table global_temporary_table.gtt_on_commit_delete
+drop cascades to table global_temporary_table.gtt_on_commit_delete2
+drop cascades to table global_temporary_table.gtt_on_commit_preserve
+drop cascades to table global_temporary_table.gtt_test_new
+drop cascades to table global_temporary_table.gtt_test_createindex
+drop cascades to table global_temporary_table.gtt_test_alter
+drop cascades to table global_temporary_table.regular_partition_01_2019
+drop cascades to table global_temporary_table.regular_partition01
+drop cascades to table global_temporary_table.global_temp_partition_01_2021
+drop cascades to table global_temporary_table.inherits_parent
+drop cascades to table global_temporary_table.inherits_parent_global_temp
+drop cascades to table global_temporary_table.gtt_test_alter1
+drop cascades to table global_temporary_table.foo
+drop cascades to table global_temporary_table.test_create_table_as
+drop cascades to table global_temporary_table.gtt_copytest
+drop cascades to table global_temporary_table.temp_products
+drop cascades to table global_temporary_table.products
+drop cascades to table global_temporary_table.temp_orders
+drop cascades to table global_temporary_table.temp_orders_2
+drop cascades to table global_temporary_table.global_temp_with_serial
+drop cascades to sequence global_temporary_table.seq_1
+drop cascades to table global_temporary_table.temp_table_with_sequence_oncommit_delete
+drop cascades to table global_temporary_table.temp_table_with_sequence_oncommit_preserve
+drop cascades to table global_temporary_table.temp_table_test_statistics
+drop cascades to table global_temporary_table.gtt_t_kenyon
+drop cascades to table global_temporary_table.temp_table_test_systemview
+-- should empty
+select * from pg_list_gtt_relfrozenxids();
+ pid | relfrozenxid
+-----+--------------
+(0 rows)
+
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index b58b062b10d..8469c345bf4 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 5b0c73d7e37..40f4fc5ca10 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -134,3 +134,6 @@ test: fast_default
# run stats by itself because its delay may be insufficient under heavy load
test: stats
+
+# global temp table test
+test: global_temporary_table
diff --git a/src/test/regress/sql/global_temporary_table.sql b/src/test/regress/sql/global_temporary_table.sql
new file mode 100644
index 00000000000..5185c3b15af
--- /dev/null
+++ b/src/test/regress/sql/global_temporary_table.sql
@@ -0,0 +1,313 @@
+--
+-- GLobal emparary table test case
+--
+
+CREATE SCHEMA IF NOT EXISTS global_temporary_table;
+set search_path=global_temporary_table,sys;
+
+--
+-- test create global temp table basic syntax
+--
+create global temp table gtt_on_commit_default(a int primary key, b text);
+create global temp table gtt_on_commit_delete(a int primary key, b text) on commit delete rows;
+create global temp table gtt_on_commit_delete2(n int) with (on_commit_delete_rows='true');
+create global temp table gtt_on_commit_preserve(a int primary key, b text) on commit PRESERVE rows;
+create global temp table gtt_test_rename(a int primary key, b text);
+create global temp table gtt_test_createindex(c0 tsvector,c1 varchar(100), c2 int);
+create global temp table gtt_test_alter(b text) with(on_commit_delete_rows=true);
+--
+-- test DML on global temp table
+--
+
+-- update empty temp table
+update gtt_on_commit_delete set b ='test';
+begin;
+insert into gtt_on_commit_delete values (1);
+update gtt_on_commit_delete set b ='test';
+-- should 1 row
+select * from gtt_on_commit_delete;
+commit;
+-- data delete after transaction commit
+-- should 0 row
+select * from gtt_on_commit_delete;
+
+-- update empty temp table
+update gtt_on_commit_preserve set b ='test';
+insert into gtt_on_commit_preserve values (2);
+begin;
+insert into gtt_on_commit_preserve values (3);
+update gtt_on_commit_preserve set b ='test';
+-- should 2 row
+select * from gtt_on_commit_preserve order by a;
+delete from gtt_on_commit_preserve where a=2;
+commit;
+-- should 1 row
+select * from gtt_on_commit_preserve order by a;
+
+begin;
+insert into gtt_on_commit_preserve values (4);
+-- temp table support truncate;
+truncate gtt_on_commit_preserve;
+select * from gtt_on_commit_preserve order by a;
+rollback;
+-- should 1 row
+select * from gtt_on_commit_preserve order by a;
+
+--
+-- test unsupported global temp partition table
+--
+
+-- should fail
+CREATE global temp TABLE global_temp_partition_01 (
+id bigserial NOT NULL,
+cre_time timestamp without time zone,
+note varchar(30)
+) PARTITION BY RANGE (cre_time)
+on commit delete rows;
+
+CREATE TABLE regular_partition_01_2019 (
+id bigserial NOT NULL,
+cre_time timestamp without time zone,
+note varchar(30)
+);
+
+CREATE TABLE regular_partition01 (
+id bigserial NOT NULL,
+cre_time timestamp without time zone,
+note varchar(30)
+) PARTITION BY RANGE (cre_time);
+
+-- should fail
+CREATE global temp TABLE temp_partition01_2018
+PARTITION OF regular_partition01
+FOR VALUES FROM ('2018-01-01 00:00:00') TO ('2019-01-01 00:00:00');
+
+CREATE global temp TABLE global_temp_partition_01_2021 (
+id bigserial NOT NULL,
+cre_time timestamp without time zone,
+note varchar(30)
+)on commit delete rows;
+
+-- should fail
+ALTER TABLE regular_partition01 ATTACH PARTITION global_temp_partition_01_2021 FOR VALUES FROM ('2021-01-01 00:00:00') TO ('2022-01-01 00:00:00');
+
+--
+-- test unsupported inherit table
+--
+create table 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 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;
+
+-- should fail
+create global temp table temp_inherit() inherits (inherits_parent);
+-- should fail
+create global temp table temp_inherit() inherits (inherits_parent_global_temp) on commit delete rows;
+
+--
+-- test DDL on global temp table
+--
+create index idx_gtt_test_alter_b on gtt_test_alter (b);
+insert into gtt_test_alter values('test');
+alter table gtt_test_alter alter b type varchar;
+create index gtt_idx_1 on gtt_test_createindex using gin (c0);
+create index gtt_idx_2 on gtt_test_createindex using gist (c0);
+create index gtt_idx_3 on gtt_test_createindex using hash (c2);
+alter table gtt_test_rename rename to gtt_test_new;
+ALTER TABLE gtt_test_new ADD COLUMN address varchar(30);
+create index CONCURRENTLY idx_b on gtt_on_commit_default (b);
+cluster gtt_on_commit_default using gtt_on_commit_default_pkey;
+insert into gtt_on_commit_default values(1,'test');
+create global temp table gtt_test_alter1 (a int primary key,b text);
+alter table gtt_test_alter1 alter a type varchar;
+-- should fail
+alter table gtt_on_commit_default alter a type varchar;
+-- should fail
+cluster gtt_on_commit_default using gtt_on_commit_default_pkey;
+-- should fail
+create table gtt_on_commit_default(a int primary key, b text) on commit delete rows;
+-- should fail
+alter table gtt_on_commit_default SET TABLESPACE pg_default;
+-- should fail
+alter table gtt_on_commit_default set ( on_commit_delete_rows='true');
+-- should fail
+create table gtt_on_commit_default(a int primary key, b text) with(on_commit_delete_rows=true);
+-- should fail
+create or replace global temp view gtt_v as select 5;
+create table foo();
+-- should fail
+alter table foo set (on_commit_delete_rows='true');
+-- should fail
+create global temp table gtt_on_commit_preserve(a int primary key, b text) on commit drop;
+-- should fail
+create global temp table gtt4(a int primary key, b text) with(on_commit_delete_rows=true) on commit delete rows;
+-- should fail
+CREATE MATERIALIZED VIEW mv_gtt_on_commit_default as select * from gtt_on_commit_default;
+-- test create table as select
+CREATE GLOBAL TEMPORARY TABLE test_create_table_as AS SELECT 1 AS a;
+-- test copy stmt
+create global temp table gtt_copytest (
+ c1 int,
+ "col with , comma" text,
+ "col with "" quote" int);
+
+copy gtt_copytest from stdin csv header;
+this is just a line full of junk that would error out if parsed
+1,a,1
+2,b,2
+\.
+select count(*) from gtt_copytest;
+
+--
+-- test foreign key dependencies for global temp table
+--
+CREATE global temp TABLE temp_products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+
+CREATE global temp TABLE products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+
+CREATE global temp TABLE temp_orders (
+ order_id integer PRIMARY KEY,
+ product_no integer REFERENCES temp_products(product_no),
+ quantity integer
+)on commit delete rows;
+
+-- should fail
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ product_no integer REFERENCES temp_products(product_no),
+ quantity integer
+);
+
+CREATE global temp TABLE temp_orders_2 (
+ order_id integer PRIMARY KEY,
+ product_no integer REFERENCES products(product_no),
+ quantity integer
+);
+
+--should fail
+insert into temp_orders values(1,1,1);
+
+insert into temp_products values(1,'test',1.0);
+begin;
+insert into temp_orders values(1,1,1);
+commit;
+-- should 1 row
+select count(*) from temp_products;
+-- should 0 row
+select count(*) from temp_orders;
+
+--
+-- test sequence on global temp table
+--
+create global temp table global_temp_with_serial (a SERIAL,b int);
+begin;
+set transaction_read_only = true;
+-- support insert data to temp table in read only transaction
+insert into global_temp_with_serial (b) values(1);
+select * from global_temp_with_serial;
+commit;
+
+create sequence seq_1;
+CREATE GLOBAL TEMPORARY TABLE temp_table_with_sequence_oncommit_delete(c1 int PRIMARY KEY) ON COMMIT DELETE ROWS;
+CREATE GLOBAL TEMPORARY TABLE temp_table_with_sequence_oncommit_preserve(c1 int PRIMARY KEY) ON COMMIT PRESERVE ROWS;
+alter table temp_table_with_sequence_oncommit_delete add c2 int default nextval('seq_1');
+alter table temp_table_with_sequence_oncommit_preserve add c2 int default nextval('seq_1');
+begin;
+insert into temp_table_with_sequence_oncommit_delete (c1)values(1);
+insert into temp_table_with_sequence_oncommit_preserve (c1)values(2);
+insert into temp_table_with_sequence_oncommit_delete (c1)values(3);
+insert into temp_table_with_sequence_oncommit_preserve (c1)values(4);
+-- should 2 row
+select * from temp_table_with_sequence_oncommit_delete order by c1;
+commit;
+-- should 0 row
+select * from temp_table_with_sequence_oncommit_delete order by c1;
+-- should 2 row
+select * from temp_table_with_sequence_oncommit_preserve order by c1;
+
+--
+-- test statistics on temp table
+--
+create global temp table temp_table_test_statistics(a int);
+insert into temp_table_test_statistics values(generate_series(1,100000));
+create index idx_test_1 on temp_table_test_statistics (a);
+create index idx_test_2 on temp_table_test_statistics((a*10));
+explain (costs off) select * from temp_table_test_statistics where a=200000;
+explain (costs off) select * from temp_table_test_statistics where a*10=3;
+-- test statistic for whole row
+explain (costs off) select count(*) from temp_table_test_statistics group by temp_table_test_statistics;
+-- test statistic for system column
+explain (costs off) select count(*) from temp_table_test_statistics group by tableoid;
+analyze temp_table_test_statistics;
+-- indexscan by idx_test_1
+explain (costs off) select * from temp_table_test_statistics where a=200000;
+-- indexscan by idx_test_2
+explain (costs off) select * from temp_table_test_statistics where a*10=3;
+explain (costs off) select count(*) from temp_table_test_statistics group by temp_table_test_statistics;
+explain (costs off) select count(*) from temp_table_test_statistics group by tableoid;
+
+--
+-- test temp table with toast table
+--
+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);
+insert into gtt_t_kenyon select generate_series(1,2000),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',500);
+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 like '%t_kenyon%' order by relname;
+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 like '%t_kenyon%' order by relname;
+begin;
+truncate gtt_t_kenyon;
+insert into gtt_t_kenyon select generate_series(1,10),repeat('kenyon here'||'^_^',2),repeat('^_^ Kenyon is not God',10);
+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 like '%t_kenyon%' order by relname;
+rollback;
+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 like '%t_kenyon%' order by relname;
+
+-- test analyze/vacuum on global temp table
+ANALYZE gtt_t_kenyon;
+VACUUM gtt_t_kenyon;
+
+--
+-- test global temp table system view
+--
+create global temp table temp_table_test_systemview(a int primary key, b text) on commit PRESERVE rows;
+-- should empty, storage not initialized
+select tablename from pg_gtt_attached_pids where tablename = 'temp_table_test_systemview';
+-- should empty, storage not initialized
+select count(*) from pg_list_gtt_relfrozenxids();
+insert into temp_table_test_systemview values(generate_series(1,10000),'test');
+select tablename from pg_gtt_attached_pids where tablename = 'temp_table_test_systemview';
+select count(*) from pg_list_gtt_relfrozenxids();
+select schemaname, tablename, relpages, reltuples, relallvisible from pg_gtt_relstats where tablename in('temp_table_test_systemview','temp_table_test_systemview_pkey') order by tablename;
+-- should empty
+select * from pg_gtt_stats where tablename = 'temp_table_test_systemview' order by tablename;
+analyze temp_table_test_systemview;
+select schemaname, tablename, relpages, reltuples, relallvisible from pg_gtt_relstats where tablename in('temp_table_test_systemview','temp_table_test_systemview_pkey') order by tablename;
+-- get data after analyze;
+select * from pg_gtt_stats where tablename = 'temp_table_test_systemview' order by tablename;
+
+-- get all object info in current schema
+select relname ,relkind, relpersistence, reloptions from pg_class c, pg_namespace n where c.relnamespace = n.oid and n.nspname = 'global_temporary_table' order by relkind,relpersistence,relname;
+
+reset search_path;
+drop schema global_temporary_table cascade;
+-- should empty
+select * from pg_list_gtt_relfrozenxids();
+
--
2.32.0 (Apple Git-132)