Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iKcKg-000167-P5 for pgsql-committers@arkaria.postgresql.org; Wed, 16 Oct 2019 05:58:51 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1iKcKf-0005UU-Je for pgsql-committers@arkaria.postgresql.org; Wed, 16 Oct 2019 05:58:49 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iKcKd-0005Tp-Tl for pgsql-committers@lists.postgresql.org; Wed, 16 Oct 2019 05:58:49 +0000 Received: from [66.111.4.28] (helo=out4-smtp.messagingengine.com) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iKcKa-00055R-89 for pgsql-committers@lists.postgresql.org; Wed, 16 Oct 2019 05:58:47 +0000 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 8376A21B62; Wed, 16 Oct 2019 01:58:22 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Wed, 16 Oct 2019 01:58:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paquier.xyz; h= date:from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm3; bh=vJPpFUyLEdql2cq01yiti2sX+33 1AZ7dw6YeoH/4AkU=; b=O7rFCj061bS0UlwFaE4qRo+RQYu+BP5Y+L6AZWf48Z1 jlzb+WMfzyOKncv/nuRRG190yDSFfp8XIfcG0py1fEwFsAzmq0Ne5ffQ7E8I8lug u2TCkJw/nndnRNDi8sHE7DHaVPHgv8HI1WlO/5eAWrRVsikpO/yOzp82D2kOLIT6 GhAJ2+t9IKaapiUjFRZ+73SUnL67uZTUYmSy3tO8U9cHfs2e1lv8Mwsk0DSLKO5V JUKS38fmAHoFohCo+E3rxGN8qKYMBfQQPLf7Ak/iIc/T55YoxUCr7SuUQxfcKGA6 SprIB+b8Wr3Lxj7dY4dLuv6RUJlWDDn2c98+J2V2B8g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=vJPpFU yLEdql2cq01yiti2sX+331AZ7dw6YeoH/4AkU=; b=aIrhheSFN9NHoWwO2nD+31 F/7LhUm+dabz6TgQyIyePjjZ0x0UgNYV/Bykk7WwCsMZiXA68SIWngz4PvCHTTjv bk4uGnBp/wQFM88VfvW2Wy06fzg5Xg8Tj1NLz3S7q8H7T5ZW+oPnsBvfK6G/ZSKs 82shEqahXSx73K6HFXvcKEh9JWnaVYvSjgQ+kvFMZ/p3xl7hkEYQktJRZfnp0p2q OSRCYiH/bItFwZERZLWJtCw3KP/zmF1M9ol8FwqBIov78+TXJfVfxYfQ81TZPQGu JNYTviub3B3dCbQROTn0bbnA6km7gv/1E7j34CZZuhlNz701DHTwOdWB/kMJXeow == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedufedrjeeggddutdduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne gfrhhlucfvnfffucdlfeehmdenucfjughrpeffhffvuffkfhggtggujgesghdtreertddt vdenucfhrhhomhepofhitghhrggvlhcurfgrqhhuihgvrhcuoehmihgthhgrvghlsehprg hquhhivghrrdighiiiqeenucffohhmrghinhepphhoshhtghhrvghsqhhlrdhorhhgnecu kfhppeduuddurddutddvrddukedtrddukeehnecurfgrrhgrmhepmhgrihhlfhhrohhmpe hmihgthhgrvghlsehprghquhhivghrrdighiiinecuvehluhhsthgvrhfuihiivgeptd X-ME-Proxy: Received: from paquier.xyz (ee0822lan1.rev.em-net.ne.jp [111.102.180.185]) by mail.messagingengine.com (Postfix) with ESMTPA id B153080061; Wed, 16 Oct 2019 01:58:20 -0400 (EDT) Date: Wed, 16 Oct 2019 14:58:17 +0900 From: Michael Paquier To: Tom Lane Cc: Andres Freund , pgsql-committers@lists.postgresql.org Subject: Re: pgsql: Fix table rewrites that include a column without a default. Message-ID: <20191016055817.GE2602@paquier.xyz> References: <3328.1570740683@sss.pgh.pa.us> <20191010205903.tj73q3qcyfft3izz@alap3.anarazel.de> <4541.1570742168@sss.pgh.pa.us> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="XStn23h1fwudRqtG" Content-Disposition: inline In-Reply-To: <4541.1570742168@sss.pgh.pa.us> X-Host-Lookup-Failed: Reverse DNS lookup failed for 66.111.4.28 (deferred) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --XStn23h1fwudRqtG Content-Type: multipart/mixed; boundary="zaRBsRFn0XYhEU69" Content-Disposition: inline --zaRBsRFn0XYhEU69 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Oct 10, 2019 at 05:16:08PM -0400, Tom Lane wrote: > I really really don't want an event trigger running in everything that > runs in parallel with alter_table. That's a debugging nightmare of > monster proportions. +1, that's not stable. elver has just complained about a side effect of this commit: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=elver&dt=2019-10-16%2005%3A04%3A24 -- now change 'name' to an integer to see what happens... ALTER TABLE alter_table_under_transition_tables ALTER COLUMN name TYPE int USING name::integer; +WARNING: rewriting table alter_table_under_transition_tables UPDATE alter_table_under_transition_tables SET name = (name::text || name::text)::integer; WARNING: old table = 1=11,2=22,3=33, new table = 1=1111,2=2222,3=3333 Another method would be to simply store the past relfilenodes into a temporary table with the relation OID, and do a comparison with what's in pg_class post-rewrite as some partition-related tests do in the same file. For one relation the \gset method is more readable anyway. If you really wish to keep an event trigger, you could also apply a filter within the function to only consider rewrite_test as something to report about, still I would recommend avoiding global effects if not necessary. So I would fix the issue as per the attached, as Tom has suggested. Thoughts? -- Michael --zaRBsRFn0XYhEU69 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="alter-table-tests.patch" Content-Transfer-Encoding: quoted-printable diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/e= xpected/alter_table.out index 41a7bcd6d0..b041247476 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -2437,51 +2437,96 @@ drop view at_view_2; drop view at_view_1; drop table at_base_table; -- check adding a column not iself requiring a rewrite, together with --- a column requiring a default (bug #16038) --- ensure that rewrites aren't silently optimized away, removing the --- value of the test -CREATE OR REPLACE FUNCTION evtrig_rewrite_log() RETURNS event_trigger -LANGUAGE plpgsql AS $$ -BEGIN - RAISE WARNING 'rewriting table %', - pg_event_trigger_table_rewrite_oid()::regclass; -END; -$$; -CREATE EVENT TRIGGER evtrig_rewrite_log ON table_rewrite - EXECUTE PROCEDURE evtrig_rewrite_log(); +-- a column requiring a default (bug #16038). This checks +-- pg_class.relfilenode before and after the rewrite for differences +-- to see if a rewrite has been done or not. CREATE TABLE rewrite_test(col text); INSERT INTO rewrite_test VALUES ('something'); INSERT INTO rewrite_test VALUES (NULL); -- empty[12] doesn't need rewrite, but notempty[12]_rewrite will force one +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN empty1 text, ADD COLUMN notempty1_rewrite serial; -WARNING: rewriting table rewrite_test +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; + changed=20 +--------- + t +(1 row) + +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN notempty2_rewrite serial, ADD COLUMN empty2 text; -WARNING: rewriting table rewrite_test +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; + changed=20 +--------- + t +(1 row) + -- also check that fast defaults cause no problem, first without rewrite +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN empty3 text, ADD COLUMN notempty3_norewrite int default 42; +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; + changed=20 +--------- + f +(1 row) + +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN notempty4_norewrite int default 42, ADD COLUMN empty4 text; +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; + changed=20 +--------- + f +(1 row) + -- then with rewrite +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN empty5 text, ADD COLUMN notempty5_norewrite int default 42, ADD COLUMN notempty5_rewrite serial; -WARNING: rewriting table rewrite_test +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; + changed=20 +--------- + t +(1 row) + +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN notempty6_rewrite serial, ADD COLUMN empty6 text, ADD COLUMN notempty6_norewrite int default 42; -WARNING: rewriting table rewrite_test +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; + changed=20 +--------- + t +(1 row) + -- cleanup -drop event trigger evtrig_rewrite_log; -drop function evtrig_rewrite_log(); DROP TABLE rewrite_test; -- -- lock levels diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/al= ter_table.sql index 3fde96b2b9..67672008ff 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -1551,51 +1551,71 @@ drop view at_view_1; drop table at_base_table; =20 -- check adding a column not iself requiring a rewrite, together with --- a column requiring a default (bug #16038) - --- ensure that rewrites aren't silently optimized away, removing the --- value of the test -CREATE OR REPLACE FUNCTION evtrig_rewrite_log() RETURNS event_trigger -LANGUAGE plpgsql AS $$ -BEGIN - RAISE WARNING 'rewriting table %', - pg_event_trigger_table_rewrite_oid()::regclass; -END; -$$; -CREATE EVENT TRIGGER evtrig_rewrite_log ON table_rewrite - EXECUTE PROCEDURE evtrig_rewrite_log(); - +-- a column requiring a default (bug #16038). This checks +-- pg_class.relfilenode before and after the rewrite for differences +-- to see if a rewrite has been done or not. CREATE TABLE rewrite_test(col text); INSERT INTO rewrite_test VALUES ('something'); INSERT INTO rewrite_test VALUES (NULL); =20 -- empty[12] doesn't need rewrite, but notempty[12]_rewrite will force one +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN empty1 text, ADD COLUMN notempty1_rewrite serial; +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; + +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN notempty2_rewrite serial, ADD COLUMN empty2 text; +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; + -- also check that fast defaults cause no problem, first without rewrite +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN empty3 text, ADD COLUMN notempty3_norewrite int default 42; +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN notempty4_norewrite int default 42, ADD COLUMN empty4 text; +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; + -- then with rewrite +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN empty5 text, ADD COLUMN notempty5_norewrite int default 42, ADD COLUMN notempty5_rewrite serial; +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; +SELECT relfilenode AS oldfilenode FROM pg_class + WHERE relname =3D 'rewrite_test' + \gset ALTER TABLE rewrite_test ADD COLUMN notempty6_rewrite serial, ADD COLUMN empty6 text, ADD COLUMN notempty6_norewrite int default 42; +SELECT relfilenode !=3D :oldfilenode AS changed FROM pg_class + WHERE relname =3D 'rewrite_test'; =20 -- cleanup -drop event trigger evtrig_rewrite_log; -drop function evtrig_rewrite_log(); DROP TABLE rewrite_test; =20 -- --zaRBsRFn0XYhEU69-- --XStn23h1fwudRqtG Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEG72nH6vTowiyblFKnvQgOdbyQH0FAl2msXkACgkQnvQgOdby QH05vQ/+JPw439Dd90Maik+LBAxGKfiUvLPA8MOTLVi3TiBpBPKrBPdhb9Gd0ucp zFMZ8RuKGHSAjqcgbFTufL7ieqHhcxB0+yUNY75A8yrqwRRiuoIA27RSSs3Wj8sL dPlvW0wf0hEET4npyo6N3POX+m1tYjtm+wsc6UixWc4f1ywDlwXFzfV0V15yKm3U RjHkq0qWOKJcu6Beycm4upCNDY+oy5dTC5KWZbWYFW6ieos7ETutNBd9Hep9tGKc DfqdwBCNPWYafu59T7ppxF4OGMZRIdfwga2rvq/2lcJSTtKuyeSo6D+gWVtqlmEf CeOW4Dt+nT/XQQTR7LBmOdz5YUCjgDkSIAP/A9BCOAJDKG9OWHeb34kNxTOHxUFL thI9rWQ++F53XHkWhjvNpQH7S5bRuQ82Vjj3yuO+OEv2ge+2Oddir+hUcJi5VECo TGuUILwiN0ibKm3F9oeP36vpNQODDO4M9TkMJBb+I9CpoWpdUt+VXh9jNgNJSjWX l3GIBUIq3tgt+ntkpcyapGBF8ymtxiybhuM57lW2KqQwfZgdaFcNltXwllPX7E+t pDf4eMBZZrGfJbAP+sI1/KknuYkD/aHwv/KiMJX8y1iJbfoyunB0NBO8D0HPwR/U 9rzerv2fIdqHRKzvCfek8IV1eccY3ywkHCkvadkp2oPiipKfht8= =KFrc -----END PGP SIGNATURE----- --XStn23h1fwudRqtG--