mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Improve test coverage for changes to inplace-updated catalogs.
This covers both regular and inplace changes, since bugs arise at their intersection. Where marked, these witness extant bugs. Back-patch to v12 (all supported versions). Reviewed (in an earlier version) by Robert Haas. Discussion: https://postgr.es/m/20240512232923.aa.nmisch@google.com
This commit is contained in:
		@@ -39,6 +39,34 @@ $node->pgbench(
 | 
				
			|||||||
		  "CREATE TYPE pg_temp.e AS ENUM ($labels); DROP TYPE pg_temp.e;"
 | 
							  "CREATE TYPE pg_temp.e AS ENUM ($labels); DROP TYPE pg_temp.e;"
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Test inplace updates from VACUUM concurrent with heap_update from GRANT.
 | 
				
			||||||
 | 
					# The PROC_IN_VACUUM environment can't finish MVCC table scans consistently,
 | 
				
			||||||
 | 
					# so this fails rarely.  To reproduce consistently, add a sleep after
 | 
				
			||||||
 | 
					# GetCatalogSnapshot(non-catalog-rel).
 | 
				
			||||||
 | 
					Test::More->builder->todo_start('PROC_IN_VACUUM scan breakage');
 | 
				
			||||||
 | 
					$node->safe_psql('postgres', 'CREATE TABLE ddl_target ()');
 | 
				
			||||||
 | 
					$node->pgbench(
 | 
				
			||||||
 | 
						'--no-vacuum --client=5 --protocol=prepared --transactions=50',
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						[qr{processed: 250/250}],
 | 
				
			||||||
 | 
						[qr{^$}],
 | 
				
			||||||
 | 
						'concurrent GRANT/VACUUM',
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							'001_pgbench_grant@9' => q(
 | 
				
			||||||
 | 
								DO $$
 | 
				
			||||||
 | 
								BEGIN
 | 
				
			||||||
 | 
									PERFORM pg_advisory_xact_lock(42);
 | 
				
			||||||
 | 
									FOR i IN 1 .. 10 LOOP
 | 
				
			||||||
 | 
										GRANT SELECT ON ddl_target TO PUBLIC;
 | 
				
			||||||
 | 
										REVOKE SELECT ON ddl_target FROM PUBLIC;
 | 
				
			||||||
 | 
									END LOOP;
 | 
				
			||||||
 | 
								END
 | 
				
			||||||
 | 
								$$;
 | 
				
			||||||
 | 
					),
 | 
				
			||||||
 | 
							'001_pgbench_vacuum_ddl_target@1' => "VACUUM ddl_target;",
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					Test::More->builder->todo_end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Trigger various connection errors
 | 
					# Trigger various connection errors
 | 
				
			||||||
$node->pgbench(
 | 
					$node->pgbench(
 | 
				
			||||||
	'no-such-database',
 | 
						'no-such-database',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1307,3 +1307,29 @@ a|b|c|d
 | 
				
			|||||||
2|2|2|4
 | 
					2|2|2|4
 | 
				
			||||||
(2 rows)
 | 
					(2 rows)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: sys1 sysupd2 c1 c2
 | 
				
			||||||
 | 
					step sys1: 
 | 
				
			||||||
 | 
						UPDATE pg_class SET reltuples = 123 WHERE oid = 'accounts'::regclass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step sysupd2: 
 | 
				
			||||||
 | 
						UPDATE pg_class SET reltuples = reltuples * 2
 | 
				
			||||||
 | 
						WHERE oid = 'accounts'::regclass;
 | 
				
			||||||
 | 
					 <waiting ...>
 | 
				
			||||||
 | 
					step c1: COMMIT;
 | 
				
			||||||
 | 
					step sysupd2: <... completed>
 | 
				
			||||||
 | 
					step c2: COMMIT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: sys1 sysmerge2 c1 c2
 | 
				
			||||||
 | 
					step sys1: 
 | 
				
			||||||
 | 
						UPDATE pg_class SET reltuples = 123 WHERE oid = 'accounts'::regclass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step sysmerge2: 
 | 
				
			||||||
 | 
						MERGE INTO pg_class
 | 
				
			||||||
 | 
						USING (SELECT 'accounts'::regclass AS o) j
 | 
				
			||||||
 | 
						ON o = oid
 | 
				
			||||||
 | 
						WHEN MATCHED THEN UPDATE SET reltuples = reltuples * 2;
 | 
				
			||||||
 | 
					 <waiting ...>
 | 
				
			||||||
 | 
					step c1: COMMIT;
 | 
				
			||||||
 | 
					step sysmerge2: <... completed>
 | 
				
			||||||
 | 
					step c2: COMMIT;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								src/test/isolation/expected/inplace-inval.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/test/isolation/expected/inplace-inval.out
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					Parsed test spec with 3 sessions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: cachefill3 cir1 cic2 ddl3 read1
 | 
				
			||||||
 | 
					step cachefill3: TABLE newly_indexed;
 | 
				
			||||||
 | 
					c
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					(0 rows)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step cir1: BEGIN; CREATE INDEX i1 ON newly_indexed (c); ROLLBACK;
 | 
				
			||||||
 | 
					step cic2: CREATE INDEX i2 ON newly_indexed (c);
 | 
				
			||||||
 | 
					step ddl3: ALTER TABLE newly_indexed ADD extra int;
 | 
				
			||||||
 | 
					step read1: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class WHERE oid = 'newly_indexed'::regclass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: cir1 cic2 ddl3 read1
 | 
				
			||||||
 | 
					step cir1: BEGIN; CREATE INDEX i1 ON newly_indexed (c); ROLLBACK;
 | 
				
			||||||
 | 
					step cic2: CREATE INDEX i2 ON newly_indexed (c);
 | 
				
			||||||
 | 
					step ddl3: ALTER TABLE newly_indexed ADD extra int;
 | 
				
			||||||
 | 
					step read1: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class WHERE oid = 'newly_indexed'::regclass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					t          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										28
									
								
								src/test/isolation/expected/intra-grant-inplace-db.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/test/isolation/expected/intra-grant-inplace-db.out
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					Parsed test spec with 3 sessions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: snap3 b1 grant1 vac2 snap3 c1 cmp3
 | 
				
			||||||
 | 
					step snap3: 
 | 
				
			||||||
 | 
						INSERT INTO frozen_witness
 | 
				
			||||||
 | 
						SELECT datfrozenxid FROM pg_database WHERE datname = current_catalog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step b1: BEGIN;
 | 
				
			||||||
 | 
					step grant1: 
 | 
				
			||||||
 | 
						GRANT TEMP ON DATABASE isolation_regression TO regress_temp_grantee;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step vac2: VACUUM (FREEZE);
 | 
				
			||||||
 | 
					step snap3: 
 | 
				
			||||||
 | 
						INSERT INTO frozen_witness
 | 
				
			||||||
 | 
						SELECT datfrozenxid FROM pg_database WHERE datname = current_catalog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step c1: COMMIT;
 | 
				
			||||||
 | 
					step cmp3: 
 | 
				
			||||||
 | 
						SELECT 'datfrozenxid retreated'
 | 
				
			||||||
 | 
						FROM pg_database
 | 
				
			||||||
 | 
						WHERE datname = current_catalog
 | 
				
			||||||
 | 
							AND age(datfrozenxid) > (SELECT min(age(x)) FROM frozen_witness);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					?column?              
 | 
				
			||||||
 | 
					----------------------
 | 
				
			||||||
 | 
					datfrozenxid retreated
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										225
									
								
								src/test/isolation/expected/intra-grant-inplace.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								src/test/isolation/expected/intra-grant-inplace.out
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,225 @@
 | 
				
			|||||||
 | 
					Parsed test spec with 5 sessions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: b1 grant1 read2 addk2 c1 read2
 | 
				
			||||||
 | 
					step b1: BEGIN;
 | 
				
			||||||
 | 
					step grant1: 
 | 
				
			||||||
 | 
						GRANT SELECT ON intra_grant_inplace TO PUBLIC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step read2: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step addk2: ALTER TABLE intra_grant_inplace ADD PRIMARY KEY (c);
 | 
				
			||||||
 | 
					step c1: COMMIT;
 | 
				
			||||||
 | 
					step read2: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: keyshr5 addk2
 | 
				
			||||||
 | 
					step keyshr5: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR KEY SHARE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step addk2: ALTER TABLE intra_grant_inplace ADD PRIMARY KEY (c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: keyshr5 b3 sfnku3 addk2 r3
 | 
				
			||||||
 | 
					step keyshr5: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR KEY SHARE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step b3: BEGIN ISOLATION LEVEL READ COMMITTED;
 | 
				
			||||||
 | 
					step sfnku3: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR NO KEY UPDATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step addk2: ALTER TABLE intra_grant_inplace ADD PRIMARY KEY (c);
 | 
				
			||||||
 | 
					step r3: ROLLBACK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: b2 sfnku2 addk2 c2
 | 
				
			||||||
 | 
					step b2: BEGIN;
 | 
				
			||||||
 | 
					step sfnku2: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR NO KEY UPDATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step addk2: ALTER TABLE intra_grant_inplace ADD PRIMARY KEY (c);
 | 
				
			||||||
 | 
					step c2: COMMIT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: keyshr5 b2 sfnku2 addk2 c2
 | 
				
			||||||
 | 
					step keyshr5: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR KEY SHARE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step b2: BEGIN;
 | 
				
			||||||
 | 
					step sfnku2: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR NO KEY UPDATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step addk2: ALTER TABLE intra_grant_inplace ADD PRIMARY KEY (c);
 | 
				
			||||||
 | 
					step c2: COMMIT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: b3 sfu3 b1 grant1 read2 addk2 r3 c1 read2
 | 
				
			||||||
 | 
					step b3: BEGIN ISOLATION LEVEL READ COMMITTED;
 | 
				
			||||||
 | 
					step sfu3: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR UPDATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step b1: BEGIN;
 | 
				
			||||||
 | 
					step grant1: 
 | 
				
			||||||
 | 
						GRANT SELECT ON intra_grant_inplace TO PUBLIC;
 | 
				
			||||||
 | 
					 <waiting ...>
 | 
				
			||||||
 | 
					step read2: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step addk2: ALTER TABLE intra_grant_inplace ADD PRIMARY KEY (c);
 | 
				
			||||||
 | 
					step r3: ROLLBACK;
 | 
				
			||||||
 | 
					step grant1: <... completed>
 | 
				
			||||||
 | 
					step c1: COMMIT;
 | 
				
			||||||
 | 
					step read2: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: b2 sfnku2 b1 grant1 addk2 c2 c1 read2
 | 
				
			||||||
 | 
					step b2: BEGIN;
 | 
				
			||||||
 | 
					step sfnku2: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR NO KEY UPDATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step b1: BEGIN;
 | 
				
			||||||
 | 
					step grant1: 
 | 
				
			||||||
 | 
						GRANT SELECT ON intra_grant_inplace TO PUBLIC;
 | 
				
			||||||
 | 
					 <waiting ...>
 | 
				
			||||||
 | 
					step addk2: ALTER TABLE intra_grant_inplace ADD PRIMARY KEY (c);
 | 
				
			||||||
 | 
					step c2: COMMIT;
 | 
				
			||||||
 | 
					step grant1: <... completed>
 | 
				
			||||||
 | 
					step c1: COMMIT;
 | 
				
			||||||
 | 
					step read2: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: b1 grant1 b3 sfu3 revoke4 c1 r3
 | 
				
			||||||
 | 
					step b1: BEGIN;
 | 
				
			||||||
 | 
					step grant1: 
 | 
				
			||||||
 | 
						GRANT SELECT ON intra_grant_inplace TO PUBLIC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step b3: BEGIN ISOLATION LEVEL READ COMMITTED;
 | 
				
			||||||
 | 
					step sfu3: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR UPDATE;
 | 
				
			||||||
 | 
					 <waiting ...>
 | 
				
			||||||
 | 
					step revoke4: 
 | 
				
			||||||
 | 
						DO $$
 | 
				
			||||||
 | 
						BEGIN
 | 
				
			||||||
 | 
							REVOKE SELECT ON intra_grant_inplace FROM PUBLIC;
 | 
				
			||||||
 | 
						EXCEPTION WHEN others THEN
 | 
				
			||||||
 | 
							RAISE WARNING 'got: %', regexp_replace(sqlerrm, '[0-9]+', 'REDACTED');
 | 
				
			||||||
 | 
						END
 | 
				
			||||||
 | 
						$$;
 | 
				
			||||||
 | 
					 <waiting ...>
 | 
				
			||||||
 | 
					step c1: COMMIT;
 | 
				
			||||||
 | 
					step sfu3: <... completed>
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					f          
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					s4: WARNING:  got: tuple concurrently updated
 | 
				
			||||||
 | 
					step revoke4: <... completed>
 | 
				
			||||||
 | 
					step r3: ROLLBACK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					starting permutation: b1 drop1 b3 sfu3 revoke4 c1 r3
 | 
				
			||||||
 | 
					step b1: BEGIN;
 | 
				
			||||||
 | 
					step drop1: 
 | 
				
			||||||
 | 
						DROP TABLE intra_grant_inplace;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step b3: BEGIN ISOLATION LEVEL READ COMMITTED;
 | 
				
			||||||
 | 
					step sfu3: 
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR UPDATE;
 | 
				
			||||||
 | 
					 <waiting ...>
 | 
				
			||||||
 | 
					step revoke4: 
 | 
				
			||||||
 | 
						DO $$
 | 
				
			||||||
 | 
						BEGIN
 | 
				
			||||||
 | 
							REVOKE SELECT ON intra_grant_inplace FROM PUBLIC;
 | 
				
			||||||
 | 
						EXCEPTION WHEN others THEN
 | 
				
			||||||
 | 
							RAISE WARNING 'got: %', regexp_replace(sqlerrm, '[0-9]+', 'REDACTED');
 | 
				
			||||||
 | 
						END
 | 
				
			||||||
 | 
						$$;
 | 
				
			||||||
 | 
					 <waiting ...>
 | 
				
			||||||
 | 
					step c1: COMMIT;
 | 
				
			||||||
 | 
					step sfu3: <... completed>
 | 
				
			||||||
 | 
					relhasindex
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					(0 rows)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					s4: WARNING:  got: tuple concurrently deleted
 | 
				
			||||||
 | 
					step revoke4: <... completed>
 | 
				
			||||||
 | 
					step r3: ROLLBACK;
 | 
				
			||||||
@@ -36,6 +36,9 @@ test: fk-partitioned-2
 | 
				
			|||||||
test: fk-snapshot
 | 
					test: fk-snapshot
 | 
				
			||||||
test: eval-plan-qual
 | 
					test: eval-plan-qual
 | 
				
			||||||
test: eval-plan-qual-trigger
 | 
					test: eval-plan-qual-trigger
 | 
				
			||||||
 | 
					test: inplace-inval
 | 
				
			||||||
 | 
					test: intra-grant-inplace
 | 
				
			||||||
 | 
					test: intra-grant-inplace-db
 | 
				
			||||||
test: lock-update-delete
 | 
					test: lock-update-delete
 | 
				
			||||||
test: lock-update-traversal
 | 
					test: lock-update-traversal
 | 
				
			||||||
test: inherit-temp
 | 
					test: inherit-temp
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -190,6 +190,12 @@ step simplepartupdate_noroute {
 | 
				
			|||||||
	update parttbl set b = 2 where c = 1 returning *;
 | 
						update parttbl set b = 2 where c = 1 returning *;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# test system class updates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step sys1	{
 | 
				
			||||||
 | 
						UPDATE pg_class SET reltuples = 123 WHERE oid = 'accounts'::regclass;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
session s2
 | 
					session s2
 | 
				
			||||||
setup		{ BEGIN ISOLATION LEVEL READ COMMITTED; }
 | 
					setup		{ BEGIN ISOLATION LEVEL READ COMMITTED; }
 | 
				
			||||||
@@ -278,6 +284,18 @@ step wnested2 {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step sysupd2	{
 | 
				
			||||||
 | 
						UPDATE pg_class SET reltuples = reltuples * 2
 | 
				
			||||||
 | 
						WHERE oid = 'accounts'::regclass;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					step sysmerge2	{
 | 
				
			||||||
 | 
						MERGE INTO pg_class
 | 
				
			||||||
 | 
						USING (SELECT 'accounts'::regclass AS o) j
 | 
				
			||||||
 | 
						ON o = oid
 | 
				
			||||||
 | 
						WHEN MATCHED THEN UPDATE SET reltuples = reltuples * 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
step c2	{ COMMIT; }
 | 
					step c2	{ COMMIT; }
 | 
				
			||||||
step r2	{ ROLLBACK; }
 | 
					step r2	{ ROLLBACK; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -374,3 +392,6 @@ permutation simplepartupdate complexpartupdate c1 c2 read_part
 | 
				
			|||||||
permutation simplepartupdate_route1to2 complexpartupdate_route_err1 c1 c2 read_part
 | 
					permutation simplepartupdate_route1to2 complexpartupdate_route_err1 c1 c2 read_part
 | 
				
			||||||
permutation simplepartupdate_noroute complexpartupdate_route c1 c2 read_part
 | 
					permutation simplepartupdate_noroute complexpartupdate_route c1 c2 read_part
 | 
				
			||||||
permutation simplepartupdate_noroute complexpartupdate_doesnt_route c1 c2 read_part
 | 
					permutation simplepartupdate_noroute complexpartupdate_doesnt_route c1 c2 read_part
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					permutation sys1 sysupd2 c1 c2
 | 
				
			||||||
 | 
					permutation sys1 sysmerge2 c1 c2
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										38
									
								
								src/test/isolation/specs/inplace-inval.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/test/isolation/specs/inplace-inval.spec
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					# If a heap_update() caller retrieves its oldtup from a cache, it's possible
 | 
				
			||||||
 | 
					# for that cache entry to predate an inplace update, causing loss of that
 | 
				
			||||||
 | 
					# inplace update.  This arises because the transaction may abort before
 | 
				
			||||||
 | 
					# sending the inplace invalidation message to the shared queue.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CREATE TABLE newly_indexed (c int);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					teardown
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DROP TABLE newly_indexed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					session s1
 | 
				
			||||||
 | 
					step cir1	{ BEGIN; CREATE INDEX i1 ON newly_indexed (c); ROLLBACK; }
 | 
				
			||||||
 | 
					step read1	{
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class WHERE oid = 'newly_indexed'::regclass;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					session s2
 | 
				
			||||||
 | 
					step cic2	{ CREATE INDEX i2 ON newly_indexed (c); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					session s3
 | 
				
			||||||
 | 
					step cachefill3	{ TABLE newly_indexed; }
 | 
				
			||||||
 | 
					step ddl3		{ ALTER TABLE newly_indexed ADD extra int; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						cachefill3	# populates the pg_class row in the catcache
 | 
				
			||||||
 | 
						cir1	# sets relhasindex=true; rollback discards cache inval
 | 
				
			||||||
 | 
						cic2	# sees relhasindex=true, skips changing it (so no inval)
 | 
				
			||||||
 | 
						ddl3	# cached row as the oldtup of an update, losing relhasindex
 | 
				
			||||||
 | 
						read1	# observe damage XXX is an extant bug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# without cachefill3, no bug
 | 
				
			||||||
 | 
					permutation cir1 cic2 ddl3 read1
 | 
				
			||||||
							
								
								
									
										46
									
								
								src/test/isolation/specs/intra-grant-inplace-db.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/test/isolation/specs/intra-grant-inplace-db.spec
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					# GRANT's lock is the catalog tuple xmax.  GRANT doesn't acquire a heavyweight
 | 
				
			||||||
 | 
					# lock on the object undergoing an ACL change.  In-place updates, namely
 | 
				
			||||||
 | 
					# datfrozenxid, need special code to cope.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CREATE ROLE regress_temp_grantee;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					teardown
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						REVOKE ALL ON DATABASE isolation_regression FROM regress_temp_grantee;
 | 
				
			||||||
 | 
						DROP ROLE regress_temp_grantee;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# heap_update(pg_database)
 | 
				
			||||||
 | 
					session s1
 | 
				
			||||||
 | 
					step b1	{ BEGIN; }
 | 
				
			||||||
 | 
					step grant1	{
 | 
				
			||||||
 | 
						GRANT TEMP ON DATABASE isolation_regression TO regress_temp_grantee;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					step c1	{ COMMIT; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# inplace update
 | 
				
			||||||
 | 
					session s2
 | 
				
			||||||
 | 
					step vac2	{ VACUUM (FREEZE); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# observe datfrozenxid
 | 
				
			||||||
 | 
					session s3
 | 
				
			||||||
 | 
					setup	{
 | 
				
			||||||
 | 
						CREATE TEMP TABLE frozen_witness (x xid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					step snap3	{
 | 
				
			||||||
 | 
						INSERT INTO frozen_witness
 | 
				
			||||||
 | 
						SELECT datfrozenxid FROM pg_database WHERE datname = current_catalog;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					step cmp3	{
 | 
				
			||||||
 | 
						SELECT 'datfrozenxid retreated'
 | 
				
			||||||
 | 
						FROM pg_database
 | 
				
			||||||
 | 
						WHERE datname = current_catalog
 | 
				
			||||||
 | 
							AND age(datfrozenxid) > (SELECT min(age(x)) FROM frozen_witness);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# XXX extant bug
 | 
				
			||||||
 | 
					permutation snap3 b1 grant1 vac2(c1) snap3 c1 cmp3
 | 
				
			||||||
							
								
								
									
										153
									
								
								src/test/isolation/specs/intra-grant-inplace.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								src/test/isolation/specs/intra-grant-inplace.spec
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,153 @@
 | 
				
			|||||||
 | 
					# GRANT's lock is the catalog tuple xmax.  GRANT doesn't acquire a heavyweight
 | 
				
			||||||
 | 
					# lock on the object undergoing an ACL change.  Inplace updates, such as
 | 
				
			||||||
 | 
					# relhasindex=true, need special code to cope.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CREATE TABLE intra_grant_inplace (c int);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					teardown
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DROP TABLE IF EXISTS intra_grant_inplace;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# heap_update()
 | 
				
			||||||
 | 
					session s1
 | 
				
			||||||
 | 
					step b1	{ BEGIN; }
 | 
				
			||||||
 | 
					step grant1	{
 | 
				
			||||||
 | 
						GRANT SELECT ON intra_grant_inplace TO PUBLIC;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					step drop1	{
 | 
				
			||||||
 | 
						DROP TABLE intra_grant_inplace;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					step c1	{ COMMIT; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# inplace update
 | 
				
			||||||
 | 
					session s2
 | 
				
			||||||
 | 
					step read2	{
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					step b2		{ BEGIN; }
 | 
				
			||||||
 | 
					step addk2	{ ALTER TABLE intra_grant_inplace ADD PRIMARY KEY (c); }
 | 
				
			||||||
 | 
					step sfnku2	{
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR NO KEY UPDATE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					step c2		{ COMMIT; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# rowmarks
 | 
				
			||||||
 | 
					session s3
 | 
				
			||||||
 | 
					step b3		{ BEGIN ISOLATION LEVEL READ COMMITTED; }
 | 
				
			||||||
 | 
					step sfnku3	{
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR NO KEY UPDATE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					step sfu3	{
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR UPDATE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					step r3	{ ROLLBACK; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Additional heap_update()
 | 
				
			||||||
 | 
					session s4
 | 
				
			||||||
 | 
					# swallow error message to keep any OID value out of expected output
 | 
				
			||||||
 | 
					step revoke4	{
 | 
				
			||||||
 | 
						DO $$
 | 
				
			||||||
 | 
						BEGIN
 | 
				
			||||||
 | 
							REVOKE SELECT ON intra_grant_inplace FROM PUBLIC;
 | 
				
			||||||
 | 
						EXCEPTION WHEN others THEN
 | 
				
			||||||
 | 
							RAISE WARNING 'got: %', regexp_replace(sqlerrm, '[0-9]+', 'REDACTED');
 | 
				
			||||||
 | 
						END
 | 
				
			||||||
 | 
						$$;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Additional rowmarks
 | 
				
			||||||
 | 
					session s5
 | 
				
			||||||
 | 
					setup	{ BEGIN; }
 | 
				
			||||||
 | 
					step keyshr5	{
 | 
				
			||||||
 | 
						SELECT relhasindex FROM pg_class
 | 
				
			||||||
 | 
						WHERE oid = 'intra_grant_inplace'::regclass FOR KEY SHARE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					teardown	{ ROLLBACK; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# XXX extant bugs: permutation comments refer to planned post-bugfix behavior
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						b1
 | 
				
			||||||
 | 
						grant1
 | 
				
			||||||
 | 
						read2
 | 
				
			||||||
 | 
						addk2(c1)	# inplace waits
 | 
				
			||||||
 | 
						c1
 | 
				
			||||||
 | 
						read2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# inplace thru KEY SHARE
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						keyshr5
 | 
				
			||||||
 | 
						addk2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# inplace wait NO KEY UPDATE w/ KEY SHARE
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						keyshr5
 | 
				
			||||||
 | 
						b3
 | 
				
			||||||
 | 
						sfnku3
 | 
				
			||||||
 | 
						addk2(r3)
 | 
				
			||||||
 | 
						r3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# same-xact rowmark
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						b2
 | 
				
			||||||
 | 
						sfnku2
 | 
				
			||||||
 | 
						addk2
 | 
				
			||||||
 | 
						c2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# same-xact rowmark in multixact
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						keyshr5
 | 
				
			||||||
 | 
						b2
 | 
				
			||||||
 | 
						sfnku2
 | 
				
			||||||
 | 
						addk2
 | 
				
			||||||
 | 
						c2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						b3
 | 
				
			||||||
 | 
						sfu3
 | 
				
			||||||
 | 
						b1
 | 
				
			||||||
 | 
						grant1(r3)	# acquire LockTuple(), await sfu3 xmax
 | 
				
			||||||
 | 
						read2
 | 
				
			||||||
 | 
						addk2(c1)	# block in LockTuple() behind grant1
 | 
				
			||||||
 | 
						r3			# unblock grant1; addk2 now awaits grant1 xmax
 | 
				
			||||||
 | 
						c1
 | 
				
			||||||
 | 
						read2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						b2
 | 
				
			||||||
 | 
						sfnku2
 | 
				
			||||||
 | 
						b1
 | 
				
			||||||
 | 
						grant1(c2)		# acquire LockTuple(), await sfnku2 xmax
 | 
				
			||||||
 | 
						addk2			# block in LockTuple() behind grant1 = deadlock
 | 
				
			||||||
 | 
						c2
 | 
				
			||||||
 | 
						c1
 | 
				
			||||||
 | 
						read2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# SearchSysCacheLocked1() calling LockRelease()
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						b1
 | 
				
			||||||
 | 
						grant1
 | 
				
			||||||
 | 
						b3
 | 
				
			||||||
 | 
						sfu3(c1)	# acquire LockTuple(), await grant1 xmax
 | 
				
			||||||
 | 
						revoke4(sfu3)	# block in LockTuple() behind sfu3
 | 
				
			||||||
 | 
						c1
 | 
				
			||||||
 | 
						r3			# revoke4 unlocks old tuple and finds new
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# SearchSysCacheLocked1() finding a tuple, then no tuple
 | 
				
			||||||
 | 
					permutation
 | 
				
			||||||
 | 
						b1
 | 
				
			||||||
 | 
						drop1
 | 
				
			||||||
 | 
						b3
 | 
				
			||||||
 | 
						sfu3(c1)		# acquire LockTuple(), await drop1 xmax
 | 
				
			||||||
 | 
						revoke4(sfu3)	# block in LockTuple() behind sfu3
 | 
				
			||||||
 | 
						c1				# sfu3 locks none; revoke4 unlocks old and finds none
 | 
				
			||||||
 | 
						r3
 | 
				
			||||||
@@ -107,6 +107,41 @@ command_ok(
 | 
				
			|||||||
	[ 'diff', $outputdir . '/primary.dump', $outputdir . '/standby.dump' ],
 | 
						[ 'diff', $outputdir . '/primary.dump', $outputdir . '/standby.dump' ],
 | 
				
			||||||
	'compare primary and standby dumps');
 | 
						'compare primary and standby dumps');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Likewise for the catalogs of the regression database, after disabling
 | 
				
			||||||
 | 
					# autovacuum to make fields like relpages stop changing.
 | 
				
			||||||
 | 
					$node_primary->append_conf('postgresql.conf', 'autovacuum = off');
 | 
				
			||||||
 | 
					$node_primary->restart;
 | 
				
			||||||
 | 
					$node_primary->wait_for_catchup($node_standby_1, 'replay',
 | 
				
			||||||
 | 
						$node_primary->lsn('insert'));
 | 
				
			||||||
 | 
					command_ok(
 | 
				
			||||||
 | 
						[
 | 
				
			||||||
 | 
							'pg_dump',
 | 
				
			||||||
 | 
							('--schema', 'pg_catalog'),
 | 
				
			||||||
 | 
							('-f', $outputdir . '/catalogs_primary.dump'),
 | 
				
			||||||
 | 
							'--no-sync',
 | 
				
			||||||
 | 
							('-p', $node_primary->port),
 | 
				
			||||||
 | 
							'--no-unlogged-table-data',
 | 
				
			||||||
 | 
							'regression'
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						'dump catalogs of primary server');
 | 
				
			||||||
 | 
					command_ok(
 | 
				
			||||||
 | 
						[
 | 
				
			||||||
 | 
							'pg_dump',
 | 
				
			||||||
 | 
							('--schema', 'pg_catalog'),
 | 
				
			||||||
 | 
							('-f', $outputdir . '/catalogs_standby.dump'),
 | 
				
			||||||
 | 
							'--no-sync',
 | 
				
			||||||
 | 
							('-p', $node_standby_1->port),
 | 
				
			||||||
 | 
							'regression'
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						'dump catalogs of standby server');
 | 
				
			||||||
 | 
					command_ok(
 | 
				
			||||||
 | 
						[
 | 
				
			||||||
 | 
							'diff',
 | 
				
			||||||
 | 
							$outputdir . '/catalogs_primary.dump',
 | 
				
			||||||
 | 
							$outputdir . '/catalogs_standby.dump'
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						'compare primary and standby catalog dumps');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$node_standby_1->stop;
 | 
					$node_standby_1->stop;
 | 
				
			||||||
$node_primary->stop;
 | 
					$node_primary->stop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								src/test/regress/expected/database.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/test/regress/expected/database.out
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					CREATE DATABASE regression_tbd
 | 
				
			||||||
 | 
						ENCODING utf8 LC_COLLATE "C" LC_CTYPE "C" TEMPLATE template0;
 | 
				
			||||||
 | 
					ALTER DATABASE regression_tbd RENAME TO regression_utf8;
 | 
				
			||||||
 | 
					ALTER DATABASE regression_utf8 RESET TABLESPACE;
 | 
				
			||||||
 | 
					ALTER DATABASE regression_utf8 CONNECTION_LIMIT 123;
 | 
				
			||||||
 | 
					-- Test PgDatabaseToastTable.  Doing this with GRANT would be slow.
 | 
				
			||||||
 | 
					BEGIN;
 | 
				
			||||||
 | 
					UPDATE pg_database
 | 
				
			||||||
 | 
					SET datacl = array_fill(makeaclitem(10, 10, 'USAGE', false), ARRAY[5e5::int])
 | 
				
			||||||
 | 
					WHERE datname = 'regression_utf8';
 | 
				
			||||||
 | 
					-- load catcache entry, if nothing else does
 | 
				
			||||||
 | 
					ALTER DATABASE regression_utf8 RESET TABLESPACE;
 | 
				
			||||||
 | 
					ROLLBACK;
 | 
				
			||||||
 | 
					DROP DATABASE regression_utf8;
 | 
				
			||||||
@@ -2298,6 +2298,17 @@ drop cascades to table measurement_y2007m01
 | 
				
			|||||||
DROP FUNCTION measurement_insert_trigger();
 | 
					DROP FUNCTION measurement_insert_trigger();
 | 
				
			||||||
-- prepare
 | 
					-- prepare
 | 
				
			||||||
RESET SESSION AUTHORIZATION;
 | 
					RESET SESSION AUTHORIZATION;
 | 
				
			||||||
 | 
					-- try a system catalog
 | 
				
			||||||
 | 
					MERGE INTO pg_class c
 | 
				
			||||||
 | 
					USING (SELECT 'pg_depend'::regclass AS oid) AS j
 | 
				
			||||||
 | 
					ON j.oid = c.oid
 | 
				
			||||||
 | 
					WHEN MATCHED THEN
 | 
				
			||||||
 | 
						UPDATE SET reltuples = reltuples + 1;
 | 
				
			||||||
 | 
					MERGE INTO pg_class c
 | 
				
			||||||
 | 
					USING pg_namespace n
 | 
				
			||||||
 | 
					ON n.oid = c.relnamespace
 | 
				
			||||||
 | 
					WHEN MATCHED AND c.oid = 'pg_depend'::regclass THEN
 | 
				
			||||||
 | 
						UPDATE SET reltuples = reltuples - 1;
 | 
				
			||||||
DROP TABLE target, target2;
 | 
					DROP TABLE target, target2;
 | 
				
			||||||
DROP TABLE source, source2;
 | 
					DROP TABLE source, source2;
 | 
				
			||||||
DROP FUNCTION merge_trigfunc();
 | 
					DROP FUNCTION merge_trigfunc();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ test: strings numerology point lseg line box path polygon circle date time timet
 | 
				
			|||||||
# geometry depends on point, lseg, line, box, path, polygon, circle
 | 
					# geometry depends on point, lseg, line, box, path, polygon, circle
 | 
				
			||||||
# horology depends on date, time, timetz, timestamp, timestamptz, interval
 | 
					# horology depends on date, time, timetz, timestamp, timestamptz, interval
 | 
				
			||||||
# ----------
 | 
					# ----------
 | 
				
			||||||
test: geometry horology tstypes regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc
 | 
					test: geometry horology tstypes regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc database
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# ----------
 | 
					# ----------
 | 
				
			||||||
# Load huge amounts of data
 | 
					# Load huge amounts of data
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								src/test/regress/sql/database.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/test/regress/sql/database.sql
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					CREATE DATABASE regression_tbd
 | 
				
			||||||
 | 
						ENCODING utf8 LC_COLLATE "C" LC_CTYPE "C" TEMPLATE template0;
 | 
				
			||||||
 | 
					ALTER DATABASE regression_tbd RENAME TO regression_utf8;
 | 
				
			||||||
 | 
					ALTER DATABASE regression_utf8 RESET TABLESPACE;
 | 
				
			||||||
 | 
					ALTER DATABASE regression_utf8 CONNECTION_LIMIT 123;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Test PgDatabaseToastTable.  Doing this with GRANT would be slow.
 | 
				
			||||||
 | 
					BEGIN;
 | 
				
			||||||
 | 
					UPDATE pg_database
 | 
				
			||||||
 | 
					SET datacl = array_fill(makeaclitem(10, 10, 'USAGE', false), ARRAY[5e5::int])
 | 
				
			||||||
 | 
					WHERE datname = 'regression_utf8';
 | 
				
			||||||
 | 
					-- load catcache entry, if nothing else does
 | 
				
			||||||
 | 
					ALTER DATABASE regression_utf8 RESET TABLESPACE;
 | 
				
			||||||
 | 
					ROLLBACK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DROP DATABASE regression_utf8;
 | 
				
			||||||
@@ -1493,6 +1493,20 @@ DROP FUNCTION measurement_insert_trigger();
 | 
				
			|||||||
-- prepare
 | 
					-- prepare
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RESET SESSION AUTHORIZATION;
 | 
					RESET SESSION AUTHORIZATION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- try a system catalog
 | 
				
			||||||
 | 
					MERGE INTO pg_class c
 | 
				
			||||||
 | 
					USING (SELECT 'pg_depend'::regclass AS oid) AS j
 | 
				
			||||||
 | 
					ON j.oid = c.oid
 | 
				
			||||||
 | 
					WHEN MATCHED THEN
 | 
				
			||||||
 | 
						UPDATE SET reltuples = reltuples + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MERGE INTO pg_class c
 | 
				
			||||||
 | 
					USING pg_namespace n
 | 
				
			||||||
 | 
					ON n.oid = c.relnamespace
 | 
				
			||||||
 | 
					WHEN MATCHED AND c.oid = 'pg_depend'::regclass THEN
 | 
				
			||||||
 | 
						UPDATE SET reltuples = reltuples - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DROP TABLE target, target2;
 | 
					DROP TABLE target, target2;
 | 
				
			||||||
DROP TABLE source, source2;
 | 
					DROP TABLE source, source2;
 | 
				
			||||||
DROP FUNCTION merge_trigfunc();
 | 
					DROP FUNCTION merge_trigfunc();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user