From c0439d3d3076b1b3ee8720fb1e1f1d5aff57fcd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20K=C3=A5veland?= Date: Sat, 15 Jun 2024 15:27:35 +0200 Subject: [PATCH 1/4] Include example migrations in build data --- eugene/docs/src/hints/E1/index.md | 7 - eugene/docs/src/hints/E1/safer_lint.md | 3 + eugene/docs/src/hints/E1/safer_trace.md | 3 + eugene/docs/src/hints/E1/unsafe_lint.md | 2 + eugene/docs/src/hints/E1/unsafe_trace.md | 2 + eugene/docs/src/hints/E10/index.md | 7 - eugene/docs/src/hints/E10/safer_lint.md | 3 + eugene/docs/src/hints/E10/safer_trace.md | 3 + eugene/docs/src/hints/E10/unsafe_lint.md | 2 + eugene/docs/src/hints/E10/unsafe_trace.md | 2 + eugene/docs/src/hints/E11/index.md | 3 - eugene/docs/src/hints/E11/unsafe_lint.md | 2 + eugene/docs/src/hints/E11/unsafe_trace.md | 2 + eugene/docs/src/hints/E2/index.md | 8 - eugene/docs/src/hints/E2/safer_lint.md | 4 + eugene/docs/src/hints/E2/safer_trace.md | 4 + eugene/docs/src/hints/E2/unsafe_lint.md | 2 + eugene/docs/src/hints/E2/unsafe_trace.md | 2 + eugene/docs/src/hints/E3/index.md | 4 - eugene/docs/src/hints/E3/safer_lint.md | 1 + eugene/docs/src/hints/E3/safer_trace.md | 1 + eugene/docs/src/hints/E3/unsafe_lint.md | 1 + eugene/docs/src/hints/E3/unsafe_trace.md | 1 + eugene/docs/src/hints/E4/index.md | 7 - eugene/docs/src/hints/E4/safer_lint.md | 3 + eugene/docs/src/hints/E4/safer_trace.md | 3 + eugene/docs/src/hints/E4/unsafe_lint.md | 2 + eugene/docs/src/hints/E4/unsafe_trace.md | 2 + eugene/docs/src/hints/E5/index.md | 8 - eugene/docs/src/hints/E5/safer_lint.md | 4 + eugene/docs/src/hints/E5/safer_trace.md | 4 + eugene/docs/src/hints/E5/unsafe_lint.md | 2 + eugene/docs/src/hints/E5/unsafe_trace.md | 2 + eugene/docs/src/hints/E6/index.md | 6 - eugene/docs/src/hints/E6/safer_lint.md | 2 + eugene/docs/src/hints/E6/safer_trace.md | 2 + eugene/docs/src/hints/E6/unsafe_lint.md | 2 + eugene/docs/src/hints/E6/unsafe_trace.md | 2 + eugene/docs/src/hints/E7/index.md | 8 - eugene/docs/src/hints/E7/safer_lint.md | 3 + eugene/docs/src/hints/E7/safer_trace.md | 3 + eugene/docs/src/hints/E7/unsafe_lint.md | 2 + eugene/docs/src/hints/E7/unsafe_trace.md | 2 + eugene/docs/src/hints/E8/index.md | 3 - eugene/docs/src/hints/E8/unsafe_lint.md | 2 + eugene/docs/src/hints/E8/unsafe_trace.md | 2 + eugene/docs/src/hints/E9/index.md | 6 - eugene/docs/src/hints/E9/safer_lint.md | 2 + eugene/docs/src/hints/E9/safer_trace.md | 2 + eugene/docs/src/hints/E9/unsafe_lint.md | 2 + eugene/docs/src/hints/E9/unsafe_trace.md | 2 + eugene/docs/src/hints/W12/index.md | 6 - eugene/docs/src/hints/W12/safer_lint.md | 2 + eugene/docs/src/hints/W12/safer_trace.md | 2 + eugene/docs/src/hints/W12/unsafe_lint.md | 2 + eugene/docs/src/hints/W12/unsafe_trace.md | 2 + eugene/docs/src/hints/W13/index.md | 4 - eugene/docs/src/hints/W13/safer_lint.md | 1 + eugene/docs/src/hints/W13/safer_trace.md | 1 + eugene/docs/src/hints/W13/unsafe_lint.md | 1 + eugene/docs/src/hints/W13/unsafe_trace.md | 1 + eugene/docs/src/hints/W14/index.md | 9 -- eugene/docs/src/hints/W14/safer_lint.md | 4 + eugene/docs/src/hints/W14/safer_trace.md | 4 + eugene/docs/src/hints/W14/unsafe_lint.md | 3 + eugene/docs/src/hints/W14/unsafe_trace.md | 3 + eugene/examples/E1/bad.sql | 12 ++ eugene/examples/E1/bad/1.sql | 5 - eugene/examples/E1/bad/2.sql | 4 - eugene/examples/E1/good.sql | 17 ++ eugene/examples/E1/good/1.sql | 5 - eugene/examples/E1/good/2.sql | 4 - eugene/examples/E1/good/3.sql | 3 - eugene/examples/E10/bad.sql | 21 +++ eugene/examples/E10/bad/1.sql | 11 -- eugene/examples/E10/bad/2.sql | 7 - eugene/examples/E10/good.sql | 24 +++ eugene/examples/E10/good/1.sql | 11 -- eugene/examples/E10/good/2.sql | 3 - eugene/examples/E10/good/3.sql | 5 - eugene/examples/E11/{bad/2.sql => bad.sql} | 6 + eugene/examples/E11/bad/1.sql | 3 - eugene/examples/E2/bad.sql | 11 ++ eugene/examples/E2/bad/1.sql | 5 - eugene/examples/E2/bad/2.sql | 3 - eugene/examples/E2/good.sql | 24 +++ eugene/examples/E2/good/1.sql | 5 - eugene/examples/E2/good/2.sql | 4 - eugene/examples/E2/good/3.sql | 3 - eugene/examples/E2/good/4.sql | 5 - eugene/examples/E3/{bad/1.sql => bad.sql} | 1 + eugene/examples/E3/{good/1.sql => good.sql} | 1 + eugene/examples/E4/bad.sql | 12 ++ eugene/examples/E4/bad/2.sql | 4 - eugene/examples/E4/good.sql | 14 ++ eugene/examples/E4/good/2.sql | 3 - eugene/examples/E4/good/3.sql | 1 - eugene/examples/E5/{good/1.sql => bad.sql} | 6 + eugene/examples/E5/bad/1.sql | 5 - eugene/examples/E5/bad/2.sql | 3 - eugene/examples/E5/good.sql | 28 ++++ eugene/examples/E5/good/2.sql | 3 - eugene/examples/E5/good/3.sql | 5 - eugene/examples/E5/good/4.sql | 8 - eugene/examples/E6/{good/1.sql => bad.sql} | 6 + eugene/examples/E6/bad/2.sql | 3 - eugene/examples/{E4/bad/1.sql => E6/good.sql} | 5 + eugene/examples/E6/good/2.sql | 2 - eugene/examples/E7/bad.sql | 11 ++ eugene/examples/E7/bad/1.sql | 5 - eugene/examples/E7/bad/2.sql | 3 - eugene/examples/E7/good.sql | 16 ++ eugene/examples/E7/good/1.sql | 5 - eugene/examples/E7/good/2.sql | 3 - eugene/examples/E7/good/3.sql | 4 - eugene/examples/E8/bad.sql | 12 ++ eugene/examples/E8/bad/1.sql | 5 - eugene/examples/E8/bad/2.sql | 4 - eugene/examples/{E6/bad/1.sql => E9/bad.sql} | 4 + eugene/examples/E9/bad/1.sql | 5 - eugene/examples/E9/bad/2.sql | 1 - .../examples/{E4/good/1.sql => E9/good.sql} | 5 + eugene/examples/E9/good/1.sql | 5 - eugene/examples/E9/good/2.sql | 2 - eugene/examples/W12/{bad/2.sql => bad.sql} | 9 ++ eugene/examples/W12/bad/1.sql | 6 - eugene/examples/W12/good.sql | 14 ++ eugene/examples/W12/good/1.sql | 6 - eugene/examples/W12/good/2.sql | 5 - eugene/examples/W13/{bad/1.sql => bad.sql} | 1 + eugene/examples/W13/{good/1.sql => good.sql} | 1 + eugene/examples/W14/bad.sql | 14 ++ eugene/examples/W14/bad/1.sql | 3 - eugene/examples/W14/bad/2.sql | 2 - eugene/examples/W14/bad/3.sql | 4 - eugene/examples/W14/good.sql | 21 +++ eugene/examples/W14/good/1.sql | 3 - eugene/examples/W14/good/2.sql | 2 - eugene/examples/W14/good/3.sql | 6 - eugene/examples/W14/good/4.sql | 3 - eugene/examples/snapshots/extra_locks.md | 2 + eugene/examples/snapshots/summary.md | 2 + .../examples/snapshots/summary_extra_locks.md | 2 + eugene/src/hint_data.rs | 36 ++++- eugene/src/render_doc_snapshots.rs | 153 ++++++++---------- 145 files changed, 526 insertions(+), 374 deletions(-) create mode 100644 eugene/examples/E1/bad.sql delete mode 100644 eugene/examples/E1/bad/1.sql delete mode 100644 eugene/examples/E1/bad/2.sql create mode 100644 eugene/examples/E1/good.sql delete mode 100644 eugene/examples/E1/good/1.sql delete mode 100644 eugene/examples/E1/good/2.sql delete mode 100644 eugene/examples/E1/good/3.sql create mode 100644 eugene/examples/E10/bad.sql delete mode 100644 eugene/examples/E10/bad/1.sql delete mode 100644 eugene/examples/E10/bad/2.sql create mode 100644 eugene/examples/E10/good.sql delete mode 100644 eugene/examples/E10/good/1.sql delete mode 100644 eugene/examples/E10/good/2.sql delete mode 100644 eugene/examples/E10/good/3.sql rename eugene/examples/E11/{bad/2.sql => bad.sql} (53%) delete mode 100644 eugene/examples/E11/bad/1.sql create mode 100644 eugene/examples/E2/bad.sql delete mode 100644 eugene/examples/E2/bad/1.sql delete mode 100644 eugene/examples/E2/bad/2.sql create mode 100644 eugene/examples/E2/good.sql delete mode 100644 eugene/examples/E2/good/1.sql delete mode 100644 eugene/examples/E2/good/2.sql delete mode 100644 eugene/examples/E2/good/3.sql delete mode 100644 eugene/examples/E2/good/4.sql rename eugene/examples/E3/{bad/1.sql => bad.sql} (93%) rename eugene/examples/E3/{good/1.sql => good.sql} (93%) create mode 100644 eugene/examples/E4/bad.sql delete mode 100644 eugene/examples/E4/bad/2.sql create mode 100644 eugene/examples/E4/good.sql delete mode 100644 eugene/examples/E4/good/2.sql delete mode 100644 eugene/examples/E4/good/3.sql rename eugene/examples/E5/{good/1.sql => bad.sql} (51%) delete mode 100644 eugene/examples/E5/bad/1.sql delete mode 100644 eugene/examples/E5/bad/2.sql create mode 100644 eugene/examples/E5/good.sql delete mode 100644 eugene/examples/E5/good/2.sql delete mode 100644 eugene/examples/E5/good/3.sql delete mode 100644 eugene/examples/E5/good/4.sql rename eugene/examples/E6/{good/1.sql => bad.sql} (52%) delete mode 100644 eugene/examples/E6/bad/2.sql rename eugene/examples/{E4/bad/1.sql => E6/good.sql} (57%) delete mode 100644 eugene/examples/E6/good/2.sql create mode 100644 eugene/examples/E7/bad.sql delete mode 100644 eugene/examples/E7/bad/1.sql delete mode 100644 eugene/examples/E7/bad/2.sql create mode 100644 eugene/examples/E7/good.sql delete mode 100644 eugene/examples/E7/good/1.sql delete mode 100644 eugene/examples/E7/good/2.sql delete mode 100644 eugene/examples/E7/good/3.sql create mode 100644 eugene/examples/E8/bad.sql delete mode 100644 eugene/examples/E8/bad/1.sql delete mode 100644 eugene/examples/E8/bad/2.sql rename eugene/examples/{E6/bad/1.sql => E9/bad.sql} (64%) delete mode 100644 eugene/examples/E9/bad/1.sql delete mode 100644 eugene/examples/E9/bad/2.sql rename eugene/examples/{E4/good/1.sql => E9/good.sql} (55%) delete mode 100644 eugene/examples/E9/good/1.sql delete mode 100644 eugene/examples/E9/good/2.sql rename eugene/examples/W12/{bad/2.sql => bad.sql} (53%) delete mode 100644 eugene/examples/W12/bad/1.sql create mode 100644 eugene/examples/W12/good.sql delete mode 100644 eugene/examples/W12/good/1.sql delete mode 100644 eugene/examples/W12/good/2.sql rename eugene/examples/W13/{bad/1.sql => bad.sql} (95%) rename eugene/examples/W13/{good/1.sql => good.sql} (96%) create mode 100644 eugene/examples/W14/bad.sql delete mode 100644 eugene/examples/W14/bad/1.sql delete mode 100644 eugene/examples/W14/bad/2.sql delete mode 100644 eugene/examples/W14/bad/3.sql create mode 100644 eugene/examples/W14/good.sql delete mode 100644 eugene/examples/W14/good/1.sql delete mode 100644 eugene/examples/W14/good/2.sql delete mode 100644 eugene/examples/W14/good/3.sql delete mode 100644 eugene/examples/W14/good/4.sql diff --git a/eugene/docs/src/hints/E1/index.md b/eugene/docs/src/hints/E1/index.md index e8a1a7a..dde45b3 100644 --- a/eugene/docs/src/hints/E1/index.md +++ b/eugene/docs/src/hints/E1/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table authors( id integer generated always as identity primary key, @@ -22,19 +21,16 @@ create table authors( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add constraint name_not_null check (name is not null); - ``` ## Safer migration ```sql -- 1.sql - create table authors( id integer generated always as identity primary key, @@ -42,18 +38,15 @@ create table authors( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add constraint name_not_null check (name is not null) not valid; -- 3.sql - set local lock_timeout = '2s'; alter table authors validate constraint name_not_null; - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/E1/safer_lint.md b/eugene/docs/src/hints/E1/safer_lint.md index d6ae317..0b8bb42 100644 --- a/eugene/docs/src/hints/E1/safer_lint.md +++ b/eugene/docs/src/hints/E1/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ @@ -51,6 +53,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E1/safer_trace.md b/eugene/docs/src/hints/E1/safer_trace.md index 99e40e8..7e99a57 100644 --- a/eugene/docs/src/hints/E1/safer_trace.md +++ b/eugene/docs/src/hints/E1/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` @@ -77,6 +79,7 @@ No locks held at the start of this statement. #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E1/unsafe_lint.md b/eugene/docs/src/hints/E1/unsafe_lint.md index 7a4531f..6dc98a2 100644 --- a/eugene/docs/src/hints/E1/unsafe_lint.md +++ b/eugene/docs/src/hints/E1/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E1/unsafe_trace.md b/eugene/docs/src/hints/E1/unsafe_trace.md index 8f540ea..63bee6e 100644 --- a/eugene/docs/src/hints/E1/unsafe_trace.md +++ b/eugene/docs/src/hints/E1/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E10/index.md b/eugene/docs/src/hints/E10/index.md index d9e72d9..18efd61 100644 --- a/eugene/docs/src/hints/E10/index.md +++ b/eugene/docs/src/hints/E10/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table prices ( id integer generated always as identity primary key, @@ -28,7 +27,6 @@ create table authors ( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add column meta jsonb; @@ -36,14 +34,12 @@ alter table authors add column meta jsonb; -- causes table rewrite, but this example isnt't about that alter table prices alter price set data type bigint; - ``` ## Safer migration ```sql -- 1.sql - create table prices ( id integer generated always as identity primary key, @@ -57,19 +53,16 @@ create table authors ( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add column meta jsonb; -- 3.sql - set local lock_timeout = '2s'; -- eugene: ignore E5, E4 -- causes table rewrite, but this example isnt't about that alter table prices alter price set data type bigint; - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/E10/safer_lint.md b/eugene/docs/src/hints/E10/safer_lint.md index 189f072..5d67ba5 100644 --- a/eugene/docs/src/hints/E10/safer_lint.md +++ b/eugene/docs/src/hints/E10/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -38,6 +39,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ @@ -60,6 +62,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E10/safer_trace.md b/eugene/docs/src/hints/E10/safer_trace.md index 5f49b32..5d39f2f 100644 --- a/eugene/docs/src/hints/E10/safer_trace.md +++ b/eugene/docs/src/hints/E10/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -55,6 +56,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` @@ -98,6 +100,7 @@ No locks held at the start of this statement. #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E10/unsafe_lint.md b/eugene/docs/src/hints/E10/unsafe_lint.md index 1140378..4247078 100644 --- a/eugene/docs/src/hints/E10/unsafe_lint.md +++ b/eugene/docs/src/hints/E10/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -38,6 +39,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E10/unsafe_trace.md b/eugene/docs/src/hints/E10/unsafe_trace.md index 2742f43..d3c1690 100644 --- a/eugene/docs/src/hints/E10/unsafe_trace.md +++ b/eugene/docs/src/hints/E10/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -55,6 +56,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E11/index.md b/eugene/docs/src/hints/E11/index.md index d33de20..ed1a914 100644 --- a/eugene/docs/src/hints/E11/index.md +++ b/eugene/docs/src/hints/E11/index.md @@ -14,17 +14,14 @@ ```sql -- 1.sql - create table prices ( price int not null ); -- 2.sql - set local lock_timeout = '2s'; alter table prices add column id serial; - ``` ## Safer migration diff --git a/eugene/docs/src/hints/E11/unsafe_lint.md b/eugene/docs/src/hints/E11/unsafe_lint.md index 9004236..41ceccf 100644 --- a/eugene/docs/src/hints/E11/unsafe_lint.md +++ b/eugene/docs/src/hints/E11/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table prices ( price int not null ) @@ -26,6 +27,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E11/unsafe_trace.md b/eugene/docs/src/hints/E11/unsafe_trace.md index 493d2b7..48e043b 100644 --- a/eugene/docs/src/hints/E11/unsafe_trace.md +++ b/eugene/docs/src/hints/E11/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table prices ( price int not null ) @@ -31,6 +32,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E2/index.md b/eugene/docs/src/hints/E2/index.md index 3d660d1..12af303 100644 --- a/eugene/docs/src/hints/E2/index.md +++ b/eugene/docs/src/hints/E2/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table authors( id integer generated always as identity primary key, @@ -22,18 +21,15 @@ create table authors( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors alter column name set not null; - ``` ## Safer migration ```sql -- 1.sql - create table authors( id integer generated always as identity primary key, @@ -41,26 +37,22 @@ create table authors( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add constraint check_name_not_null check (name is not null) not valid; -- 3.sql - set local lock_timeout = '2s'; alter table authors validate constraint check_name_not_null; -- 4.sql - set local lock_timeout = '2s'; -- eugene trace knows name has a valid not null check, but eugene lint doesn't -- eugene: ignore E2 alter table authors alter name set not null; - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/E2/safer_lint.md b/eugene/docs/src/hints/E2/safer_lint.md index 679cbd3..3ad4fb0 100644 --- a/eugene/docs/src/hints/E2/safer_lint.md +++ b/eugene/docs/src/hints/E2/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ @@ -51,6 +53,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ @@ -73,6 +76,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 4.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E2/safer_trace.md b/eugene/docs/src/hints/E2/safer_trace.md index 3ed14f2..ee75c58 100644 --- a/eugene/docs/src/hints/E2/safer_trace.md +++ b/eugene/docs/src/hints/E2/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` @@ -77,6 +79,7 @@ No locks held at the start of this statement. #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` @@ -118,6 +121,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 4.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E2/unsafe_lint.md b/eugene/docs/src/hints/E2/unsafe_lint.md index 067478a..95f7a7e 100644 --- a/eugene/docs/src/hints/E2/unsafe_lint.md +++ b/eugene/docs/src/hints/E2/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E2/unsafe_trace.md b/eugene/docs/src/hints/E2/unsafe_trace.md index 067ce09..4766357 100644 --- a/eugene/docs/src/hints/E2/unsafe_trace.md +++ b/eugene/docs/src/hints/E2/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E3/index.md b/eugene/docs/src/hints/E3/index.md index 99154da..1bd2881 100644 --- a/eugene/docs/src/hints/E3/index.md +++ b/eugene/docs/src/hints/E3/index.md @@ -14,28 +14,24 @@ ```sql -- 1.sql - create table authors ( id integer generated always as identity primary key, name text not null, meta json ); - ``` ## Safer migration ```sql -- 1.sql - create table authors ( id integer generated always as identity primary key, name text not null, meta jsonb ); - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/E3/safer_lint.md b/eugene/docs/src/hints/E3/safer_lint.md index 6b9f291..2471738 100644 --- a/eugene/docs/src/hints/E3/safer_lint.md +++ b/eugene/docs/src/hints/E3/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, diff --git a/eugene/docs/src/hints/E3/safer_trace.md b/eugene/docs/src/hints/E3/safer_trace.md index 7e6f5e9..e122b83 100644 --- a/eugene/docs/src/hints/E3/safer_trace.md +++ b/eugene/docs/src/hints/E3/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, diff --git a/eugene/docs/src/hints/E3/unsafe_lint.md b/eugene/docs/src/hints/E3/unsafe_lint.md index 01e5b16..2bac860 100644 --- a/eugene/docs/src/hints/E3/unsafe_lint.md +++ b/eugene/docs/src/hints/E3/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, diff --git a/eugene/docs/src/hints/E3/unsafe_trace.md b/eugene/docs/src/hints/E3/unsafe_trace.md index 11116cc..2d15b78 100644 --- a/eugene/docs/src/hints/E3/unsafe_trace.md +++ b/eugene/docs/src/hints/E3/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, diff --git a/eugene/docs/src/hints/E4/index.md b/eugene/docs/src/hints/E4/index.md index 0f51516..a03a559 100644 --- a/eugene/docs/src/hints/E4/index.md +++ b/eugene/docs/src/hints/E4/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table authors ( id integer generated always as identity primary key, @@ -22,19 +21,16 @@ create table authors ( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add column email text not null; select count(*) from authors; - ``` ## Safer migration ```sql -- 1.sql - create table authors ( id integer generated always as identity primary key, @@ -42,15 +38,12 @@ create table authors ( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add column email text not null; -- 3.sql - select count(*) from authors; - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/E4/safer_lint.md b/eugene/docs/src/hints/E4/safer_lint.md index 07d0ddf..43bcc9d 100644 --- a/eugene/docs/src/hints/E4/safer_lint.md +++ b/eugene/docs/src/hints/E4/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ @@ -50,6 +52,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 3.sql select count(*) from authors ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E4/safer_trace.md b/eugene/docs/src/hints/E4/safer_trace.md index a2a3814..58dbfef 100644 --- a/eugene/docs/src/hints/E4/safer_trace.md +++ b/eugene/docs/src/hints/E4/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` @@ -76,6 +78,7 @@ No locks held at the start of this statement. #### SQL ```sql +-- 3.sql select count(*) from authors ``` diff --git a/eugene/docs/src/hints/E4/unsafe_lint.md b/eugene/docs/src/hints/E4/unsafe_lint.md index 67d38be..0211357 100644 --- a/eugene/docs/src/hints/E4/unsafe_lint.md +++ b/eugene/docs/src/hints/E4/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E4/unsafe_trace.md b/eugene/docs/src/hints/E4/unsafe_trace.md index e52a37b..e83ebf7 100644 --- a/eugene/docs/src/hints/E4/unsafe_trace.md +++ b/eugene/docs/src/hints/E4/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E5/index.md b/eugene/docs/src/hints/E5/index.md index 1151b88..176c2e5 100644 --- a/eugene/docs/src/hints/E5/index.md +++ b/eugene/docs/src/hints/E5/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table prices ( id integer generated always as identity primary key, @@ -22,18 +21,15 @@ create table prices ( ); -- 2.sql - set local lock_timeout = '2s'; alter table prices alter price set data type bigint; - ``` ## Safer migration ```sql -- 1.sql - create table prices ( id integer generated always as identity primary key, @@ -41,13 +37,11 @@ create table prices ( ); -- 2.sql - set local lock_timeout = '2s'; alter table prices add column new_price bigint; -- 3.sql - update prices set new_price = price :: bigint; set local lock_timeout = '2s'; alter table prices @@ -55,7 +49,6 @@ alter table prices check (new_price is not null) not valid; -- 4.sql - set local lock_timeout = '2s'; alter table prices validate constraint check_new_price_not_null, @@ -64,7 +57,6 @@ alter table prices -- this has to run in the same transaction as dropping the old price column alter table prices rename column new_price to price; - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/E5/safer_lint.md b/eugene/docs/src/hints/E5/safer_lint.md index ebf3751..caa509e 100644 --- a/eugene/docs/src/hints/E5/safer_lint.md +++ b/eugene/docs/src/hints/E5/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ @@ -50,6 +52,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 3.sql update prices set new_price = price :: bigint ``` No checks matched for this statement. ✅ @@ -79,6 +82,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 4.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E5/safer_trace.md b/eugene/docs/src/hints/E5/safer_trace.md index ede8a3a..5ddea8d 100644 --- a/eugene/docs/src/hints/E5/safer_trace.md +++ b/eugene/docs/src/hints/E5/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` @@ -76,6 +78,7 @@ No locks held at the start of this statement. #### SQL ```sql +-- 3.sql update prices set new_price = price :: bigint ``` @@ -138,6 +141,7 @@ No locks held at the start of this statement. #### SQL ```sql +-- 4.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E5/unsafe_lint.md b/eugene/docs/src/hints/E5/unsafe_lint.md index e57805b..3c19c96 100644 --- a/eugene/docs/src/hints/E5/unsafe_lint.md +++ b/eugene/docs/src/hints/E5/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E5/unsafe_trace.md b/eugene/docs/src/hints/E5/unsafe_trace.md index 9d88591..015bfe7 100644 --- a/eugene/docs/src/hints/E5/unsafe_trace.md +++ b/eugene/docs/src/hints/E5/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E6/index.md b/eugene/docs/src/hints/E6/index.md index fa723db..b72abdc 100644 --- a/eugene/docs/src/hints/E6/index.md +++ b/eugene/docs/src/hints/E6/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table authors ( id integer generated always as identity primary key, @@ -22,18 +21,15 @@ create table authors ( ); -- 2.sql - set local lock_timeout = '2s'; create index authors_name_idx on authors (name); - ``` ## Safer migration ```sql -- 1.sql - create table authors ( id integer generated always as identity primary key, @@ -41,10 +37,8 @@ create table authors ( ); -- 2.sql - create index concurrently authors_name_idx on authors (name); - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/E6/safer_lint.md b/eugene/docs/src/hints/E6/safer_lint.md index 5fa313b..1fabf68 100644 --- a/eugene/docs/src/hints/E6/safer_lint.md +++ b/eugene/docs/src/hints/E6/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql create index concurrently authors_name_idx on authors (name) ``` diff --git a/eugene/docs/src/hints/E6/safer_trace.md b/eugene/docs/src/hints/E6/safer_trace.md index c93285a..fb82a53 100644 --- a/eugene/docs/src/hints/E6/safer_trace.md +++ b/eugene/docs/src/hints/E6/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql create index concurrently authors_name_idx on authors (name) ``` diff --git a/eugene/docs/src/hints/E6/unsafe_lint.md b/eugene/docs/src/hints/E6/unsafe_lint.md index bad633d..5c6965b 100644 --- a/eugene/docs/src/hints/E6/unsafe_lint.md +++ b/eugene/docs/src/hints/E6/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E6/unsafe_trace.md b/eugene/docs/src/hints/E6/unsafe_trace.md index 14603ad..a07ffc9 100644 --- a/eugene/docs/src/hints/E6/unsafe_trace.md +++ b/eugene/docs/src/hints/E6/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E7/index.md b/eugene/docs/src/hints/E7/index.md index 77e972b..5db9d70 100644 --- a/eugene/docs/src/hints/E7/index.md +++ b/eugene/docs/src/hints/E7/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table authors( id integer generated always as identity primary key, @@ -22,18 +21,15 @@ create table authors( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add constraint unique_name unique(name); - ``` ## Safer migration ```sql -- 1.sql - create table authors( id integer generated always as identity primary key, @@ -41,18 +37,14 @@ create table authors( ); -- 2.sql - create unique index concurrently authors_name_unique on authors(name); - -- 3.sql - set local lock_timeout = '2s'; alter table authors add constraint unique_name unique using index authors_name_unique; - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/E7/safer_lint.md b/eugene/docs/src/hints/E7/safer_lint.md index 2ec0750..3e9f888 100644 --- a/eugene/docs/src/hints/E7/safer_lint.md +++ b/eugene/docs/src/hints/E7/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql create unique index concurrently authors_name_unique on authors(name) ``` @@ -44,6 +46,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E7/safer_trace.md b/eugene/docs/src/hints/E7/safer_trace.md index 269b4c0..e018068 100644 --- a/eugene/docs/src/hints/E7/safer_trace.md +++ b/eugene/docs/src/hints/E7/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql create unique index concurrently authors_name_unique on authors(name) ``` @@ -56,6 +58,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E7/unsafe_lint.md b/eugene/docs/src/hints/E7/unsafe_lint.md index a3e5eaf..3a6a24a 100644 --- a/eugene/docs/src/hints/E7/unsafe_lint.md +++ b/eugene/docs/src/hints/E7/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E7/unsafe_trace.md b/eugene/docs/src/hints/E7/unsafe_trace.md index de85bcd..82c1a6c 100644 --- a/eugene/docs/src/hints/E7/unsafe_trace.md +++ b/eugene/docs/src/hints/E7/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E8/index.md b/eugene/docs/src/hints/E8/index.md index 888fbdb..d0cebf0 100644 --- a/eugene/docs/src/hints/E8/index.md +++ b/eugene/docs/src/hints/E8/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table authors ( id integer generated always as identity primary key, @@ -22,12 +21,10 @@ create table authors ( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add constraint authors_name_excl exclude (name with =); - ``` ## Safer migration diff --git a/eugene/docs/src/hints/E8/unsafe_lint.md b/eugene/docs/src/hints/E8/unsafe_lint.md index 961cbf1..ab6dbd5 100644 --- a/eugene/docs/src/hints/E8/unsafe_lint.md +++ b/eugene/docs/src/hints/E8/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E8/unsafe_trace.md b/eugene/docs/src/hints/E8/unsafe_trace.md index 4d27701..c7ac545 100644 --- a/eugene/docs/src/hints/E8/unsafe_trace.md +++ b/eugene/docs/src/hints/E8/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E9/index.md b/eugene/docs/src/hints/E9/index.md index af00a30..acd8cd7 100644 --- a/eugene/docs/src/hints/E9/index.md +++ b/eugene/docs/src/hints/E9/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table authors ( id integer generated always as identity primary key, @@ -22,16 +21,13 @@ create table authors ( ); -- 2.sql - alter table authors add column email text; - ``` ## Safer migration ```sql -- 1.sql - create table authors ( id integer generated always as identity primary key, @@ -39,10 +35,8 @@ create table authors ( ); -- 2.sql - set local lock_timeout = '2s'; alter table authors add column email text; - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/E9/safer_lint.md b/eugene/docs/src/hints/E9/safer_lint.md index a561c3f..e949dea 100644 --- a/eugene/docs/src/hints/E9/safer_lint.md +++ b/eugene/docs/src/hints/E9/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/E9/safer_trace.md b/eugene/docs/src/hints/E9/safer_trace.md index 6c2ecb4..b145625 100644 --- a/eugene/docs/src/hints/E9/safer_trace.md +++ b/eugene/docs/src/hints/E9/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/E9/unsafe_lint.md b/eugene/docs/src/hints/E9/unsafe_lint.md index e6f2aff..6c85e3b 100644 --- a/eugene/docs/src/hints/E9/unsafe_lint.md +++ b/eugene/docs/src/hints/E9/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -28,6 +29,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql alter table authors add column email text ``` #### Lints diff --git a/eugene/docs/src/hints/E9/unsafe_trace.md b/eugene/docs/src/hints/E9/unsafe_trace.md index 40e6e5c..73e4a2f 100644 --- a/eugene/docs/src/hints/E9/unsafe_trace.md +++ b/eugene/docs/src/hints/E9/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors ( id integer generated always as identity primary key, @@ -33,6 +34,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql alter table authors add column email text ``` diff --git a/eugene/docs/src/hints/W12/index.md b/eugene/docs/src/hints/W12/index.md index db08f0d..bd8efaf 100644 --- a/eugene/docs/src/hints/W12/index.md +++ b/eugene/docs/src/hints/W12/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create table authors( id integer generated always as identity primary key, @@ -23,21 +22,18 @@ create table authors( ); -- 2.sql - set lock_timeout = '2s'; alter table authors alter column name set not null; -- eugene: ignore E2, E4 alter table authors alter column email set not null; - ``` ## Safer migration ```sql -- 1.sql - create table authors( id integer generated always as identity primary key, @@ -46,13 +42,11 @@ create table authors( ); -- 2.sql - set lock_timeout = '2s'; -- eugene: ignore E2 alter table authors alter column name set not null, alter column email set not null; - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/W12/safer_lint.md b/eugene/docs/src/hints/W12/safer_lint.md index f73477b..166e288 100644 --- a/eugene/docs/src/hints/W12/safer_lint.md +++ b/eugene/docs/src/hints/W12/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -29,6 +30,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql set lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/W12/safer_trace.md b/eugene/docs/src/hints/W12/safer_trace.md index 87368a5..1237dc7 100644 --- a/eugene/docs/src/hints/W12/safer_trace.md +++ b/eugene/docs/src/hints/W12/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -34,6 +35,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/W12/unsafe_lint.md b/eugene/docs/src/hints/W12/unsafe_lint.md index ae73ae1..3bd0553 100644 --- a/eugene/docs/src/hints/W12/unsafe_lint.md +++ b/eugene/docs/src/hints/W12/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -29,6 +30,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 2.sql set lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/W12/unsafe_trace.md b/eugene/docs/src/hints/W12/unsafe_trace.md index 9f9778e..fd2a617 100644 --- a/eugene/docs/src/hints/W12/unsafe_trace.md +++ b/eugene/docs/src/hints/W12/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( id integer generated always as identity primary key, @@ -34,6 +35,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set lock_timeout = '2s' ``` diff --git a/eugene/docs/src/hints/W13/index.md b/eugene/docs/src/hints/W13/index.md index 939c90a..6980bb8 100644 --- a/eugene/docs/src/hints/W13/index.md +++ b/eugene/docs/src/hints/W13/index.md @@ -14,7 +14,6 @@ ```sql -- 1.sql - create type document_type as enum ('invoice', 'receipt', 'other'); create table document ( @@ -22,14 +21,12 @@ create table document ( primary key, type document_type ); - ``` ## Safer migration ```sql -- 1.sql - create table document_type( type_name text primary key ); @@ -41,7 +38,6 @@ create table document ( type text references document_type(type_name) ); - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/W13/safer_lint.md b/eugene/docs/src/hints/W13/safer_lint.md index ae19cd5..5292ad7 100644 --- a/eugene/docs/src/hints/W13/safer_lint.md +++ b/eugene/docs/src/hints/W13/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table document_type( type_name text primary key ) diff --git a/eugene/docs/src/hints/W13/safer_trace.md b/eugene/docs/src/hints/W13/safer_trace.md index 038f9fb..e4c393c 100644 --- a/eugene/docs/src/hints/W13/safer_trace.md +++ b/eugene/docs/src/hints/W13/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table document_type( type_name text primary key ) diff --git a/eugene/docs/src/hints/W13/unsafe_lint.md b/eugene/docs/src/hints/W13/unsafe_lint.md index 0a6d9ab..9d04ebf 100644 --- a/eugene/docs/src/hints/W13/unsafe_lint.md +++ b/eugene/docs/src/hints/W13/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 1.sql create type document_type as enum ('invoice', 'receipt', 'other') ``` diff --git a/eugene/docs/src/hints/W13/unsafe_trace.md b/eugene/docs/src/hints/W13/unsafe_trace.md index 0f998b0..99c99f7 100644 --- a/eugene/docs/src/hints/W13/unsafe_trace.md +++ b/eugene/docs/src/hints/W13/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create type document_type as enum ('invoice', 'receipt', 'other') ``` diff --git a/eugene/docs/src/hints/W14/index.md b/eugene/docs/src/hints/W14/index.md index ebfb1d0..de4c098 100644 --- a/eugene/docs/src/hints/W14/index.md +++ b/eugene/docs/src/hints/W14/index.md @@ -14,41 +14,34 @@ ```sql -- 1.sql - create table authors( name text ); -- 2.sql - create unique index concurrently authors_name_key on authors(name); -- 3.sql - set local lock_timeout = '2s'; alter table authors add constraint authors_name_pkey primary key using index authors_name_key; - ``` ## Safer migration ```sql -- 1.sql - create table authors( name text ); -- 2.sql - create unique index concurrently authors_name_key on authors(name); -- 3.sql - set local lock_timeout = '2s'; -- eugene: ignore E2 -- This is a demo of W14, so we can ignore E2 instead of the @@ -57,11 +50,9 @@ alter table authors alter column name set not null; -- 4.sql - alter table authors add constraint authors_name_pkey primary key using index authors_name_key; - ``` ## Eugene report examples diff --git a/eugene/docs/src/hints/W14/safer_lint.md b/eugene/docs/src/hints/W14/safer_lint.md index 8e264de..0c4b8b5 100644 --- a/eugene/docs/src/hints/W14/safer_lint.md +++ b/eugene/docs/src/hints/W14/safer_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( name text ) @@ -26,6 +27,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql create unique index concurrently authors_name_key on authors(name) ``` @@ -42,6 +44,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ @@ -67,6 +70,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 4.sql alter table authors add constraint authors_name_pkey primary key using index authors_name_key diff --git a/eugene/docs/src/hints/W14/safer_trace.md b/eugene/docs/src/hints/W14/safer_trace.md index 0db381e..e41bb45 100644 --- a/eugene/docs/src/hints/W14/safer_trace.md +++ b/eugene/docs/src/hints/W14/safer_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( name text ) @@ -31,6 +32,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql create unique index concurrently authors_name_key on authors(name) ``` @@ -54,6 +56,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` @@ -100,6 +103,7 @@ No locks held at the start of this statement. #### SQL ```sql +-- 4.sql alter table authors add constraint authors_name_pkey primary key using index authors_name_key diff --git a/eugene/docs/src/hints/W14/unsafe_lint.md b/eugene/docs/src/hints/W14/unsafe_lint.md index d408b5f..12d2d51 100644 --- a/eugene/docs/src/hints/W14/unsafe_lint.md +++ b/eugene/docs/src/hints/W14/unsafe_lint.md @@ -9,6 +9,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 1.sql create table authors( name text ) @@ -26,6 +27,7 @@ The migration script passed all the checks ✅ ### Statement number 1 #### SQL ```sql +-- 2.sql create unique index concurrently authors_name_key on authors(name) ``` @@ -42,6 +44,7 @@ The migration script did not pass all the checks ❌ ### Statement number 1 #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` No checks matched for this statement. ✅ diff --git a/eugene/docs/src/hints/W14/unsafe_trace.md b/eugene/docs/src/hints/W14/unsafe_trace.md index 0b358c8..bab6617 100644 --- a/eugene/docs/src/hints/W14/unsafe_trace.md +++ b/eugene/docs/src/hints/W14/unsafe_trace.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table authors( name text ) @@ -31,6 +32,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql create unique index concurrently authors_name_key on authors(name) ``` @@ -54,6 +56,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 3.sql set local lock_timeout = '2s' ``` diff --git a/eugene/examples/E1/bad.sql b/eugene/examples/E1/bad.sql new file mode 100644 index 0000000..4720e5c --- /dev/null +++ b/eugene/examples/E1/bad.sql @@ -0,0 +1,12 @@ +-- 1.sql +create table authors( + id integer generated always as identity + primary key, + name text +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors + add constraint name_not_null + check (name is not null); diff --git a/eugene/examples/E1/bad/1.sql b/eugene/examples/E1/bad/1.sql deleted file mode 100644 index fce08f8..0000000 --- a/eugene/examples/E1/bad/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table authors( - id integer generated always as identity - primary key, - name text -); diff --git a/eugene/examples/E1/bad/2.sql b/eugene/examples/E1/bad/2.sql deleted file mode 100644 index 16a27d3..0000000 --- a/eugene/examples/E1/bad/2.sql +++ /dev/null @@ -1,4 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add constraint name_not_null - check (name is not null); diff --git a/eugene/examples/E1/good.sql b/eugene/examples/E1/good.sql new file mode 100644 index 0000000..64cb36b --- /dev/null +++ b/eugene/examples/E1/good.sql @@ -0,0 +1,17 @@ +-- 1.sql +create table authors( + id integer generated always as identity + primary key, + name text +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors + add constraint name_not_null + check (name is not null) not valid; + +-- 3.sql +set local lock_timeout = '2s'; +alter table authors + validate constraint name_not_null; diff --git a/eugene/examples/E1/good/1.sql b/eugene/examples/E1/good/1.sql deleted file mode 100644 index fce08f8..0000000 --- a/eugene/examples/E1/good/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table authors( - id integer generated always as identity - primary key, - name text -); diff --git a/eugene/examples/E1/good/2.sql b/eugene/examples/E1/good/2.sql deleted file mode 100644 index 0199e4e..0000000 --- a/eugene/examples/E1/good/2.sql +++ /dev/null @@ -1,4 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add constraint name_not_null - check (name is not null) not valid; diff --git a/eugene/examples/E1/good/3.sql b/eugene/examples/E1/good/3.sql deleted file mode 100644 index 4eabebd..0000000 --- a/eugene/examples/E1/good/3.sql +++ /dev/null @@ -1,3 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - validate constraint name_not_null; diff --git a/eugene/examples/E10/bad.sql b/eugene/examples/E10/bad.sql new file mode 100644 index 0000000..aebfafd --- /dev/null +++ b/eugene/examples/E10/bad.sql @@ -0,0 +1,21 @@ +-- 1.sql +create table prices ( + id integer generated always as identity + primary key, + price int not null +); + +create table authors ( + id integer generated always as identity + primary key, + name text not null +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors add column meta jsonb; + +-- eugene: ignore E5, E4 +-- causes table rewrite, but this example isnt't about that +alter table prices + alter price set data type bigint; diff --git a/eugene/examples/E10/bad/1.sql b/eugene/examples/E10/bad/1.sql deleted file mode 100644 index 16a7927..0000000 --- a/eugene/examples/E10/bad/1.sql +++ /dev/null @@ -1,11 +0,0 @@ -create table prices ( - id integer generated always as identity - primary key, - price int not null -); - -create table authors ( - id integer generated always as identity - primary key, - name text not null -); diff --git a/eugene/examples/E10/bad/2.sql b/eugene/examples/E10/bad/2.sql deleted file mode 100644 index 42030c2..0000000 --- a/eugene/examples/E10/bad/2.sql +++ /dev/null @@ -1,7 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors add column meta jsonb; - --- eugene: ignore E5, E4 --- causes table rewrite, but this example isnt't about that -alter table prices - alter price set data type bigint; diff --git a/eugene/examples/E10/good.sql b/eugene/examples/E10/good.sql new file mode 100644 index 0000000..6db6e95 --- /dev/null +++ b/eugene/examples/E10/good.sql @@ -0,0 +1,24 @@ +-- 1.sql +create table prices ( + id integer generated always as identity + primary key, + price int not null +); + +create table authors ( + id integer generated always as identity + primary key, + name text not null +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors + add column meta jsonb; + +-- 3.sql +set local lock_timeout = '2s'; +-- eugene: ignore E5, E4 +-- causes table rewrite, but this example isnt't about that +alter table prices + alter price set data type bigint; diff --git a/eugene/examples/E10/good/1.sql b/eugene/examples/E10/good/1.sql deleted file mode 100644 index 16a7927..0000000 --- a/eugene/examples/E10/good/1.sql +++ /dev/null @@ -1,11 +0,0 @@ -create table prices ( - id integer generated always as identity - primary key, - price int not null -); - -create table authors ( - id integer generated always as identity - primary key, - name text not null -); diff --git a/eugene/examples/E10/good/2.sql b/eugene/examples/E10/good/2.sql deleted file mode 100644 index 4fc18b2..0000000 --- a/eugene/examples/E10/good/2.sql +++ /dev/null @@ -1,3 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add column meta jsonb; diff --git a/eugene/examples/E10/good/3.sql b/eugene/examples/E10/good/3.sql deleted file mode 100644 index 6dabb27..0000000 --- a/eugene/examples/E10/good/3.sql +++ /dev/null @@ -1,5 +0,0 @@ -set local lock_timeout = '2s'; --- eugene: ignore E5, E4 --- causes table rewrite, but this example isnt't about that -alter table prices - alter price set data type bigint; diff --git a/eugene/examples/E11/bad/2.sql b/eugene/examples/E11/bad.sql similarity index 53% rename from eugene/examples/E11/bad/2.sql rename to eugene/examples/E11/bad.sql index d36537d..f7cb08e 100644 --- a/eugene/examples/E11/bad/2.sql +++ b/eugene/examples/E11/bad.sql @@ -1,3 +1,9 @@ +-- 1.sql +create table prices ( + price int not null +); + +-- 2.sql set local lock_timeout = '2s'; alter table prices add column id serial; diff --git a/eugene/examples/E11/bad/1.sql b/eugene/examples/E11/bad/1.sql deleted file mode 100644 index a055e38..0000000 --- a/eugene/examples/E11/bad/1.sql +++ /dev/null @@ -1,3 +0,0 @@ -create table prices ( - price int not null -); diff --git a/eugene/examples/E2/bad.sql b/eugene/examples/E2/bad.sql new file mode 100644 index 0000000..1f69590 --- /dev/null +++ b/eugene/examples/E2/bad.sql @@ -0,0 +1,11 @@ +-- 1.sql +create table authors( + id integer generated always as identity + primary key, + name text +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors + alter column name set not null; diff --git a/eugene/examples/E2/bad/1.sql b/eugene/examples/E2/bad/1.sql deleted file mode 100644 index fce08f8..0000000 --- a/eugene/examples/E2/bad/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table authors( - id integer generated always as identity - primary key, - name text -); diff --git a/eugene/examples/E2/bad/2.sql b/eugene/examples/E2/bad/2.sql deleted file mode 100644 index 8663e4e..0000000 --- a/eugene/examples/E2/bad/2.sql +++ /dev/null @@ -1,3 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - alter column name set not null; diff --git a/eugene/examples/E2/good.sql b/eugene/examples/E2/good.sql new file mode 100644 index 0000000..5ba37f4 --- /dev/null +++ b/eugene/examples/E2/good.sql @@ -0,0 +1,24 @@ +-- 1.sql +create table authors( + id integer generated always as identity + primary key, + name text +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors + add constraint check_name_not_null + check (name is not null) not valid; + +-- 3.sql +set local lock_timeout = '2s'; +alter table authors + validate constraint check_name_not_null; + +-- 4.sql +set local lock_timeout = '2s'; +-- eugene trace knows name has a valid not null check, but eugene lint doesn't +-- eugene: ignore E2 +alter table authors + alter name set not null; diff --git a/eugene/examples/E2/good/1.sql b/eugene/examples/E2/good/1.sql deleted file mode 100644 index fce08f8..0000000 --- a/eugene/examples/E2/good/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table authors( - id integer generated always as identity - primary key, - name text -); diff --git a/eugene/examples/E2/good/2.sql b/eugene/examples/E2/good/2.sql deleted file mode 100644 index 2acdd0c..0000000 --- a/eugene/examples/E2/good/2.sql +++ /dev/null @@ -1,4 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add constraint check_name_not_null - check (name is not null) not valid; diff --git a/eugene/examples/E2/good/3.sql b/eugene/examples/E2/good/3.sql deleted file mode 100644 index 1531148..0000000 --- a/eugene/examples/E2/good/3.sql +++ /dev/null @@ -1,3 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - validate constraint check_name_not_null; diff --git a/eugene/examples/E2/good/4.sql b/eugene/examples/E2/good/4.sql deleted file mode 100644 index 567f368..0000000 --- a/eugene/examples/E2/good/4.sql +++ /dev/null @@ -1,5 +0,0 @@ -set local lock_timeout = '2s'; --- eugene trace knows name has a valid not null check, but eugene lint doesn't --- eugene: ignore E2 -alter table authors - alter name set not null; diff --git a/eugene/examples/E3/bad/1.sql b/eugene/examples/E3/bad.sql similarity index 93% rename from eugene/examples/E3/bad/1.sql rename to eugene/examples/E3/bad.sql index 8172e04..2861545 100644 --- a/eugene/examples/E3/bad/1.sql +++ b/eugene/examples/E3/bad.sql @@ -1,3 +1,4 @@ +-- 1.sql create table authors ( id integer generated always as identity primary key, diff --git a/eugene/examples/E3/good/1.sql b/eugene/examples/E3/good.sql similarity index 93% rename from eugene/examples/E3/good/1.sql rename to eugene/examples/E3/good.sql index 787259a..7a9e096 100644 --- a/eugene/examples/E3/good/1.sql +++ b/eugene/examples/E3/good.sql @@ -1,3 +1,4 @@ +-- 1.sql create table authors ( id integer generated always as identity primary key, diff --git a/eugene/examples/E4/bad.sql b/eugene/examples/E4/bad.sql new file mode 100644 index 0000000..80ca6d0 --- /dev/null +++ b/eugene/examples/E4/bad.sql @@ -0,0 +1,12 @@ +-- 1.sql +create table authors ( + id integer generated always as identity + primary key, + name text not null +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors + add column email text not null; +select count(*) from authors; diff --git a/eugene/examples/E4/bad/2.sql b/eugene/examples/E4/bad/2.sql deleted file mode 100644 index 9d7f34a..0000000 --- a/eugene/examples/E4/bad/2.sql +++ /dev/null @@ -1,4 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add column email text not null; -select count(*) from authors; diff --git a/eugene/examples/E4/good.sql b/eugene/examples/E4/good.sql new file mode 100644 index 0000000..3e939e3 --- /dev/null +++ b/eugene/examples/E4/good.sql @@ -0,0 +1,14 @@ +-- 1.sql +create table authors ( + id integer generated always as identity + primary key, + name text not null +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors + add column email text not null; + +-- 3.sql +select count(*) from authors; diff --git a/eugene/examples/E4/good/2.sql b/eugene/examples/E4/good/2.sql deleted file mode 100644 index 766da16..0000000 --- a/eugene/examples/E4/good/2.sql +++ /dev/null @@ -1,3 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add column email text not null; diff --git a/eugene/examples/E4/good/3.sql b/eugene/examples/E4/good/3.sql deleted file mode 100644 index 7390f98..0000000 --- a/eugene/examples/E4/good/3.sql +++ /dev/null @@ -1 +0,0 @@ -select count(*) from authors; diff --git a/eugene/examples/E5/good/1.sql b/eugene/examples/E5/bad.sql similarity index 51% rename from eugene/examples/E5/good/1.sql rename to eugene/examples/E5/bad.sql index 7098c82..82565cc 100644 --- a/eugene/examples/E5/good/1.sql +++ b/eugene/examples/E5/bad.sql @@ -1,5 +1,11 @@ +-- 1.sql create table prices ( id integer generated always as identity primary key, price int not null ); + +-- 2.sql +set local lock_timeout = '2s'; +alter table prices + alter price set data type bigint; diff --git a/eugene/examples/E5/bad/1.sql b/eugene/examples/E5/bad/1.sql deleted file mode 100644 index 7098c82..0000000 --- a/eugene/examples/E5/bad/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table prices ( - id integer generated always as identity - primary key, - price int not null -); diff --git a/eugene/examples/E5/bad/2.sql b/eugene/examples/E5/bad/2.sql deleted file mode 100644 index c8d014d..0000000 --- a/eugene/examples/E5/bad/2.sql +++ /dev/null @@ -1,3 +0,0 @@ -set local lock_timeout = '2s'; -alter table prices - alter price set data type bigint; diff --git a/eugene/examples/E5/good.sql b/eugene/examples/E5/good.sql new file mode 100644 index 0000000..8212d2f --- /dev/null +++ b/eugene/examples/E5/good.sql @@ -0,0 +1,28 @@ +-- 1.sql +create table prices ( + id integer generated always as identity + primary key, + price int not null +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table prices + add column new_price bigint; + +-- 3.sql +update prices set new_price = price :: bigint; +set local lock_timeout = '2s'; +alter table prices + add constraint check_new_price_not_null + check (new_price is not null) not valid; + +-- 4.sql +set local lock_timeout = '2s'; +alter table prices + validate constraint check_new_price_not_null, + drop column price; +-- eugene: ignore E4 +-- this has to run in the same transaction as dropping the old price column +alter table prices + rename column new_price to price; diff --git a/eugene/examples/E5/good/2.sql b/eugene/examples/E5/good/2.sql deleted file mode 100644 index 8ebc47a..0000000 --- a/eugene/examples/E5/good/2.sql +++ /dev/null @@ -1,3 +0,0 @@ -set local lock_timeout = '2s'; -alter table prices - add column new_price bigint; diff --git a/eugene/examples/E5/good/3.sql b/eugene/examples/E5/good/3.sql deleted file mode 100644 index 3775ca7..0000000 --- a/eugene/examples/E5/good/3.sql +++ /dev/null @@ -1,5 +0,0 @@ -update prices set new_price = price :: bigint; -set local lock_timeout = '2s'; -alter table prices - add constraint check_new_price_not_null - check (new_price is not null) not valid; diff --git a/eugene/examples/E5/good/4.sql b/eugene/examples/E5/good/4.sql deleted file mode 100644 index 0ef60db..0000000 --- a/eugene/examples/E5/good/4.sql +++ /dev/null @@ -1,8 +0,0 @@ -set local lock_timeout = '2s'; -alter table prices - validate constraint check_new_price_not_null, - drop column price; --- eugene: ignore E4 --- this has to run in the same transaction as dropping the old price column -alter table prices - rename column new_price to price; diff --git a/eugene/examples/E6/good/1.sql b/eugene/examples/E6/bad.sql similarity index 52% rename from eugene/examples/E6/good/1.sql rename to eugene/examples/E6/bad.sql index 83b4576..5ff2103 100644 --- a/eugene/examples/E6/good/1.sql +++ b/eugene/examples/E6/bad.sql @@ -1,5 +1,11 @@ +-- 1.sql create table authors ( id integer generated always as identity primary key, name text not null ); + +-- 2.sql +set local lock_timeout = '2s'; +create index + authors_name_idx on authors (name); diff --git a/eugene/examples/E6/bad/2.sql b/eugene/examples/E6/bad/2.sql deleted file mode 100644 index b2f1817..0000000 --- a/eugene/examples/E6/bad/2.sql +++ /dev/null @@ -1,3 +0,0 @@ -set local lock_timeout = '2s'; -create index - authors_name_idx on authors (name); diff --git a/eugene/examples/E4/bad/1.sql b/eugene/examples/E6/good.sql similarity index 57% rename from eugene/examples/E4/bad/1.sql rename to eugene/examples/E6/good.sql index 83b4576..2ad3d72 100644 --- a/eugene/examples/E4/bad/1.sql +++ b/eugene/examples/E6/good.sql @@ -1,5 +1,10 @@ +-- 1.sql create table authors ( id integer generated always as identity primary key, name text not null ); + +-- 2.sql +create index concurrently + authors_name_idx on authors (name); diff --git a/eugene/examples/E6/good/2.sql b/eugene/examples/E6/good/2.sql deleted file mode 100644 index 7915277..0000000 --- a/eugene/examples/E6/good/2.sql +++ /dev/null @@ -1,2 +0,0 @@ -create index concurrently - authors_name_idx on authors (name); diff --git a/eugene/examples/E7/bad.sql b/eugene/examples/E7/bad.sql new file mode 100644 index 0000000..fb0bfa9 --- /dev/null +++ b/eugene/examples/E7/bad.sql @@ -0,0 +1,11 @@ +-- 1.sql +create table authors( + id integer generated always as identity + primary key, + name text not null +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors + add constraint unique_name unique(name); diff --git a/eugene/examples/E7/bad/1.sql b/eugene/examples/E7/bad/1.sql deleted file mode 100644 index 81ffd3c..0000000 --- a/eugene/examples/E7/bad/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table authors( - id integer generated always as identity - primary key, - name text not null -); diff --git a/eugene/examples/E7/bad/2.sql b/eugene/examples/E7/bad/2.sql deleted file mode 100644 index 496d62e..0000000 --- a/eugene/examples/E7/bad/2.sql +++ /dev/null @@ -1,3 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add constraint unique_name unique(name); diff --git a/eugene/examples/E7/good.sql b/eugene/examples/E7/good.sql new file mode 100644 index 0000000..86bebe4 --- /dev/null +++ b/eugene/examples/E7/good.sql @@ -0,0 +1,16 @@ +-- 1.sql +create table authors( + id integer generated always as identity + primary key, + name text not null +); + +-- 2.sql +create unique index concurrently + authors_name_unique on authors(name); + +-- 3.sql +set local lock_timeout = '2s'; +alter table authors + add constraint unique_name + unique using index authors_name_unique; diff --git a/eugene/examples/E7/good/1.sql b/eugene/examples/E7/good/1.sql deleted file mode 100644 index 81ffd3c..0000000 --- a/eugene/examples/E7/good/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table authors( - id integer generated always as identity - primary key, - name text not null -); diff --git a/eugene/examples/E7/good/2.sql b/eugene/examples/E7/good/2.sql deleted file mode 100644 index 1bc13c7..0000000 --- a/eugene/examples/E7/good/2.sql +++ /dev/null @@ -1,3 +0,0 @@ -create unique index concurrently - authors_name_unique on authors(name); - diff --git a/eugene/examples/E7/good/3.sql b/eugene/examples/E7/good/3.sql deleted file mode 100644 index 378968f..0000000 --- a/eugene/examples/E7/good/3.sql +++ /dev/null @@ -1,4 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add constraint unique_name - unique using index authors_name_unique; diff --git a/eugene/examples/E8/bad.sql b/eugene/examples/E8/bad.sql new file mode 100644 index 0000000..3e95f2d --- /dev/null +++ b/eugene/examples/E8/bad.sql @@ -0,0 +1,12 @@ +-- 1.sql +create table authors ( + id integer generated always as identity + primary key, + name text not null +); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors + add constraint authors_name_excl + exclude (name with =); diff --git a/eugene/examples/E8/bad/1.sql b/eugene/examples/E8/bad/1.sql deleted file mode 100644 index 83b4576..0000000 --- a/eugene/examples/E8/bad/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table authors ( - id integer generated always as identity - primary key, - name text not null -); diff --git a/eugene/examples/E8/bad/2.sql b/eugene/examples/E8/bad/2.sql deleted file mode 100644 index 90482bc..0000000 --- a/eugene/examples/E8/bad/2.sql +++ /dev/null @@ -1,4 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add constraint authors_name_excl - exclude (name with =); diff --git a/eugene/examples/E6/bad/1.sql b/eugene/examples/E9/bad.sql similarity index 64% rename from eugene/examples/E6/bad/1.sql rename to eugene/examples/E9/bad.sql index 83b4576..36733f5 100644 --- a/eugene/examples/E6/bad/1.sql +++ b/eugene/examples/E9/bad.sql @@ -1,5 +1,9 @@ +-- 1.sql create table authors ( id integer generated always as identity primary key, name text not null ); + +-- 2.sql +alter table authors add column email text; diff --git a/eugene/examples/E9/bad/1.sql b/eugene/examples/E9/bad/1.sql deleted file mode 100644 index 83b4576..0000000 --- a/eugene/examples/E9/bad/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table authors ( - id integer generated always as identity - primary key, - name text not null -); diff --git a/eugene/examples/E9/bad/2.sql b/eugene/examples/E9/bad/2.sql deleted file mode 100644 index 9886f25..0000000 --- a/eugene/examples/E9/bad/2.sql +++ /dev/null @@ -1 +0,0 @@ -alter table authors add column email text; diff --git a/eugene/examples/E4/good/1.sql b/eugene/examples/E9/good.sql similarity index 55% rename from eugene/examples/E4/good/1.sql rename to eugene/examples/E9/good.sql index 83b4576..62c875e 100644 --- a/eugene/examples/E4/good/1.sql +++ b/eugene/examples/E9/good.sql @@ -1,5 +1,10 @@ +-- 1.sql create table authors ( id integer generated always as identity primary key, name text not null ); + +-- 2.sql +set local lock_timeout = '2s'; +alter table authors add column email text; diff --git a/eugene/examples/E9/good/1.sql b/eugene/examples/E9/good/1.sql deleted file mode 100644 index 83b4576..0000000 --- a/eugene/examples/E9/good/1.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table authors ( - id integer generated always as identity - primary key, - name text not null -); diff --git a/eugene/examples/E9/good/2.sql b/eugene/examples/E9/good/2.sql deleted file mode 100644 index 0d86076..0000000 --- a/eugene/examples/E9/good/2.sql +++ /dev/null @@ -1,2 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors add column email text; diff --git a/eugene/examples/W12/bad/2.sql b/eugene/examples/W12/bad.sql similarity index 53% rename from eugene/examples/W12/bad/2.sql rename to eugene/examples/W12/bad.sql index 0f20b49..45abfe0 100644 --- a/eugene/examples/W12/bad/2.sql +++ b/eugene/examples/W12/bad.sql @@ -1,3 +1,12 @@ +-- 1.sql +create table authors( + id integer generated always as identity + primary key, + name text, + email text +); + +-- 2.sql set lock_timeout = '2s'; alter table authors alter column name set not null; diff --git a/eugene/examples/W12/bad/1.sql b/eugene/examples/W12/bad/1.sql deleted file mode 100644 index d2de8ba..0000000 --- a/eugene/examples/W12/bad/1.sql +++ /dev/null @@ -1,6 +0,0 @@ -create table authors( - id integer generated always as identity - primary key, - name text, - email text -); diff --git a/eugene/examples/W12/good.sql b/eugene/examples/W12/good.sql new file mode 100644 index 0000000..4c2c55f --- /dev/null +++ b/eugene/examples/W12/good.sql @@ -0,0 +1,14 @@ +-- 1.sql +create table authors( + id integer generated always as identity + primary key, + name text, + email text +); + +-- 2.sql +set lock_timeout = '2s'; +-- eugene: ignore E2 +alter table authors + alter column name set not null, + alter column email set not null; diff --git a/eugene/examples/W12/good/1.sql b/eugene/examples/W12/good/1.sql deleted file mode 100644 index d2de8ba..0000000 --- a/eugene/examples/W12/good/1.sql +++ /dev/null @@ -1,6 +0,0 @@ -create table authors( - id integer generated always as identity - primary key, - name text, - email text -); diff --git a/eugene/examples/W12/good/2.sql b/eugene/examples/W12/good/2.sql deleted file mode 100644 index df1faf1..0000000 --- a/eugene/examples/W12/good/2.sql +++ /dev/null @@ -1,5 +0,0 @@ -set lock_timeout = '2s'; --- eugene: ignore E2 -alter table authors - alter column name set not null, - alter column email set not null; diff --git a/eugene/examples/W13/bad/1.sql b/eugene/examples/W13/bad.sql similarity index 95% rename from eugene/examples/W13/bad/1.sql rename to eugene/examples/W13/bad.sql index 1a2170f..989b3ca 100644 --- a/eugene/examples/W13/bad/1.sql +++ b/eugene/examples/W13/bad.sql @@ -1,3 +1,4 @@ +-- 1.sql create type document_type as enum ('invoice', 'receipt', 'other'); create table document ( diff --git a/eugene/examples/W13/good/1.sql b/eugene/examples/W13/good.sql similarity index 96% rename from eugene/examples/W13/good/1.sql rename to eugene/examples/W13/good.sql index 5d35d1b..6fce398 100644 --- a/eugene/examples/W13/good/1.sql +++ b/eugene/examples/W13/good.sql @@ -1,3 +1,4 @@ +-- 1.sql create table document_type( type_name text primary key ); diff --git a/eugene/examples/W14/bad.sql b/eugene/examples/W14/bad.sql new file mode 100644 index 0000000..704a07e --- /dev/null +++ b/eugene/examples/W14/bad.sql @@ -0,0 +1,14 @@ +-- 1.sql +create table authors( + name text +); + +-- 2.sql +create unique index concurrently + authors_name_key on authors(name); + +-- 3.sql +set local lock_timeout = '2s'; +alter table authors + add constraint authors_name_pkey + primary key using index authors_name_key; diff --git a/eugene/examples/W14/bad/1.sql b/eugene/examples/W14/bad/1.sql deleted file mode 100644 index dae4f10..0000000 --- a/eugene/examples/W14/bad/1.sql +++ /dev/null @@ -1,3 +0,0 @@ -create table authors( - name text -); diff --git a/eugene/examples/W14/bad/2.sql b/eugene/examples/W14/bad/2.sql deleted file mode 100644 index fd731cb..0000000 --- a/eugene/examples/W14/bad/2.sql +++ /dev/null @@ -1,2 +0,0 @@ -create unique index concurrently - authors_name_key on authors(name); diff --git a/eugene/examples/W14/bad/3.sql b/eugene/examples/W14/bad/3.sql deleted file mode 100644 index 22b3f3c..0000000 --- a/eugene/examples/W14/bad/3.sql +++ /dev/null @@ -1,4 +0,0 @@ -set local lock_timeout = '2s'; -alter table authors - add constraint authors_name_pkey - primary key using index authors_name_key; diff --git a/eugene/examples/W14/good.sql b/eugene/examples/W14/good.sql new file mode 100644 index 0000000..4969f0d --- /dev/null +++ b/eugene/examples/W14/good.sql @@ -0,0 +1,21 @@ +-- 1.sql +create table authors( + name text +); + +-- 2.sql +create unique index concurrently + authors_name_key on authors(name); + +-- 3.sql +set local lock_timeout = '2s'; +-- eugene: ignore E2 +-- This is a demo of W14, so we can ignore E2 instead of the +-- multi-step migration to make the column NOT NULL safely +alter table authors + alter column name set not null; + +-- 4.sql +alter table authors + add constraint authors_name_pkey + primary key using index authors_name_key; diff --git a/eugene/examples/W14/good/1.sql b/eugene/examples/W14/good/1.sql deleted file mode 100644 index dae4f10..0000000 --- a/eugene/examples/W14/good/1.sql +++ /dev/null @@ -1,3 +0,0 @@ -create table authors( - name text -); diff --git a/eugene/examples/W14/good/2.sql b/eugene/examples/W14/good/2.sql deleted file mode 100644 index fd731cb..0000000 --- a/eugene/examples/W14/good/2.sql +++ /dev/null @@ -1,2 +0,0 @@ -create unique index concurrently - authors_name_key on authors(name); diff --git a/eugene/examples/W14/good/3.sql b/eugene/examples/W14/good/3.sql deleted file mode 100644 index 986d09b..0000000 --- a/eugene/examples/W14/good/3.sql +++ /dev/null @@ -1,6 +0,0 @@ -set local lock_timeout = '2s'; --- eugene: ignore E2 --- This is a demo of W14, so we can ignore E2 instead of the --- multi-step migration to make the column NOT NULL safely -alter table authors - alter column name set not null; diff --git a/eugene/examples/W14/good/4.sql b/eugene/examples/W14/good/4.sql deleted file mode 100644 index b27d43a..0000000 --- a/eugene/examples/W14/good/4.sql +++ /dev/null @@ -1,3 +0,0 @@ -alter table authors - add constraint authors_name_pkey - primary key using index authors_name_key; diff --git a/eugene/examples/snapshots/extra_locks.md b/eugene/examples/snapshots/extra_locks.md index 2742f43..d3c1690 100644 --- a/eugene/examples/snapshots/extra_locks.md +++ b/eugene/examples/snapshots/extra_locks.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -55,6 +56,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/examples/snapshots/summary.md b/eugene/examples/snapshots/summary.md index 6786d4d..343db7c 100644 --- a/eugene/examples/snapshots/summary.md +++ b/eugene/examples/snapshots/summary.md @@ -33,6 +33,7 @@ No locks acquired on database objects that already exist. #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -149,6 +150,7 @@ statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/examples/snapshots/summary_extra_locks.md b/eugene/examples/snapshots/summary_extra_locks.md index 2742f43..d3c1690 100644 --- a/eugene/examples/snapshots/summary_extra_locks.md +++ b/eugene/examples/snapshots/summary_extra_locks.md @@ -7,6 +7,7 @@ #### SQL ```sql +-- 1.sql create table prices ( id integer generated always as identity primary key, @@ -55,6 +56,7 @@ No new locks taken by this statement. #### SQL ```sql +-- 2.sql set local lock_timeout = '2s' ``` diff --git a/eugene/src/hint_data.rs b/eugene/src/hint_data.rs index 71a199c..9c53835 100644 --- a/eugene/src/hint_data.rs +++ b/eugene/src/hint_data.rs @@ -15,6 +15,8 @@ pub struct StaticHintData { pub condition: &'static str, pub effect: &'static str, pub workaround: &'static str, + pub bad_example: &'static str, + pub good_example: Option<&'static str>, } impl HintId for StaticHintData { @@ -22,12 +24,15 @@ impl HintId for StaticHintData { self.id } } + pub const VALIDATE_CONSTRAINT_WITH_LOCK: StaticHintData = StaticHintData { id: "E1", name: "Validating table with a new constraint", condition: "A new constraint was added and it is already `VALID`", effect: "This blocks all table access until all rows are validated", workaround: "Add the constraint as `NOT VALID` and validate it with `ALTER TABLE ... VALIDATE CONSTRAINT` later", + bad_example: include_str!("../examples/E1/bad.sql"), + good_example: Some(include_str!("../examples/E1/good.sql")), }; pub const MAKE_COLUMN_NOT_NULLABLE_WITH_LOCK: StaticHintData = StaticHintData { id: "E2", @@ -35,6 +40,8 @@ pub const MAKE_COLUMN_NOT_NULLABLE_WITH_LOCK: StaticHintData = StaticHintData { condition: "A column was changed from `NULL` to `NOT NULL`", workaround: "Add a `CHECK` constraint as `NOT VALID`, validate it later, then make the column `NOT NULL`", effect: "This blocks all table access until all rows are validated", + bad_example: include_str!("../examples/E2/bad.sql"), + good_example: Some(include_str!("../examples/E2/good.sql")), }; pub const ADD_JSON_COLUMN: StaticHintData = StaticHintData { id: "E3", @@ -42,6 +49,8 @@ pub const ADD_JSON_COLUMN: StaticHintData = StaticHintData { condition: "A new column of type `json` was added to a table", workaround: "Use the `jsonb` type instead, it supports all use-cases of `json` and is more robust and compact", effect: "This breaks `SELECT DISTINCT` queries or other operations that need equality checks on the column", + bad_example: include_str!("../examples/E3/bad.sql"), + good_example: Some(include_str!("../examples/E3/good.sql")), }; pub const RUNNING_STATEMENT_WHILE_HOLDING_ACCESS_EXCLUSIVE: StaticHintData = StaticHintData { id: "E4", @@ -49,6 +58,8 @@ pub const RUNNING_STATEMENT_WHILE_HOLDING_ACCESS_EXCLUSIVE: StaticHintData = Sta condition: "A transaction that holds an `AccessExclusiveLock` started a new statement", workaround: "Run this statement in a new transaction", effect: "This blocks all access to the table for the duration of this statement", + bad_example: include_str!("../examples/E4/bad.sql"), + good_example: Some(include_str!("../examples/E4/good.sql")), }; pub const TYPE_CHANGE_REQUIRES_TABLE_REWRITE: StaticHintData = StaticHintData { id: "E5", @@ -56,6 +67,8 @@ pub const TYPE_CHANGE_REQUIRES_TABLE_REWRITE: StaticHintData = StaticHintData { condition: "A column was changed to a data type that isn't binary compatible", workaround: "Add a new column, update it in batches, and drop the old column", effect: "This causes a full table rewrite while holding a lock that prevents all other use of the table", + bad_example: include_str!("../examples/E5/bad.sql"), + good_example: Some(include_str!("../examples/E5/good.sql")), }; pub const NEW_INDEX_ON_EXISTING_TABLE_IS_NONCONCURRENT: StaticHintData = StaticHintData { id: "E6", @@ -63,6 +76,8 @@ pub const NEW_INDEX_ON_EXISTING_TABLE_IS_NONCONCURRENT: StaticHintData = StaticH condition: "A new index was created on an existing table without the `CONCURRENTLY` keyword", workaround: "Run `CREATE INDEX CONCURRENTLY` instead of `CREATE INDEX`", effect: "This blocks all writes to the table while the index is being created", + bad_example: include_str!("../examples/E6/bad.sql"), + good_example: Some(include_str!("../examples/E6/good.sql")), }; pub const NEW_UNIQUE_CONSTRAINT_CREATED_INDEX: StaticHintData = StaticHintData { id: "E7", @@ -70,6 +85,8 @@ pub const NEW_UNIQUE_CONSTRAINT_CREATED_INDEX: StaticHintData = StaticHintData { condition: "Adding a new unique constraint implicitly creates index", workaround: "`CREATE UNIQUE INDEX CONCURRENTLY`, then add the constraint using the index", effect: "This blocks all writes to the table while the index is being created and validated", + bad_example: include_str!("../examples/E7/bad.sql"), + good_example: Some(include_str!("../examples/E7/good.sql")), }; pub const NEW_EXCLUSION_CONSTRAINT_FOUND: StaticHintData = StaticHintData { id: "E8", @@ -78,6 +95,8 @@ pub const NEW_EXCLUSION_CONSTRAINT_FOUND: StaticHintData = StaticHintData { workaround: "There is no safe way to add an exclusion constraint to an existing table", effect: "This blocks all reads and writes to the table while the constraint index is being created", + bad_example: include_str!("../examples/E8/bad.sql"), + good_example: None, }; pub const TOOK_DANGEROUS_LOCK_WITHOUT_TIMEOUT: StaticHintData = StaticHintData { id: "E9", @@ -86,7 +105,8 @@ pub const TOOK_DANGEROUS_LOCK_WITHOUT_TIMEOUT: StaticHintData = StaticHintData { workaround: "Run `SET LOCAL lock_timeout = '2s';` before the statement and retry the migration if necessary", effect: "This can block all other operations on the table indefinitely if any other transaction \ holds a conflicting lock while `idle in transaction` or `active`", - + bad_example: include_str!("../examples/E9/bad.sql"), + good_example: Some(include_str!("../examples/E9/good.sql")), }; pub const REWROTE_TABLE_WHILE_HOLDING_DANGEROUS_LOCK: StaticHintData = StaticHintData { id: "E10", @@ -94,6 +114,8 @@ pub const REWROTE_TABLE_WHILE_HOLDING_DANGEROUS_LOCK: StaticHintData = StaticHin condition: "A table or index was rewritten while holding a lock that blocks many operations", workaround: "Build a new table or index, write to both, then swap them", effect: "This blocks many operations on the table or index while the rewrite is in progress", + bad_example: include_str!("../examples/E10/bad.sql"), + good_example: Some(include_str!("../examples/E10/good.sql")), }; pub const ADDED_SERIAL_OR_STORED_GENERATED_COLUMN: StaticHintData = StaticHintData { id: "E11", @@ -101,6 +123,8 @@ pub const ADDED_SERIAL_OR_STORED_GENERATED_COLUMN: StaticHintData = StaticHintDa condition: "A new column was added with a `SERIAL` or `GENERATED` type", workaround: "Can not be done without a table rewrite", effect: "This blocks all table access until the table is rewritten", + bad_example: include_str!("../examples/E11/bad.sql"), + good_example: None, }; pub const MULTIPLE_ALTER_TABLES_WHERE_ONE_WILL_DO: StaticHintData = StaticHintData { id: "W12", @@ -108,6 +132,8 @@ pub const MULTIPLE_ALTER_TABLES_WHERE_ONE_WILL_DO: StaticHintData = StaticHintDa condition: "Multiple `ALTER TABLE` statements targets the same table", workaround: "Combine the statements into one, separating the action with commas", effect: "If the statements require table scans, there will be more scans than necessary", + bad_example: include_str!("../examples/W12/bad.sql"), + good_example: Some(include_str!("../examples/W12/good.sql")), }; pub const CREATING_ENUM: StaticHintData = StaticHintData { id: "W13", @@ -115,6 +141,8 @@ pub const CREATING_ENUM: StaticHintData = StaticHintData { condition: "A new enum was created", workaround: "Use a foreign key to a lookup table instead", effect: "Removing values from an enum requires difficult migrations, and associating more data with an enum value is difficult", + bad_example: include_str!("../examples/W13/bad.sql"), + good_example: Some(include_str!("../examples/W13/good.sql")), }; pub const ADD_PRIMARY_KEY_USING_INDEX: StaticHintData = StaticHintData { id: "W14", @@ -122,6 +150,8 @@ pub const ADD_PRIMARY_KEY_USING_INDEX: StaticHintData = StaticHintData { condition: "A primary key was added using an index on the table", workaround: "Make sure that all the columns in the index are already `NOT NULL`", effect: "This can cause postgres to alter the index columns to be `NOT NULL`", + bad_example: include_str!("../examples/W14/bad.sql"), + good_example: Some(include_str!("../examples/W14/good.sql")), }; pub const ALL: &[&StaticHintData] = &[ @@ -141,6 +171,10 @@ pub const ALL: &[&StaticHintData] = &[ &ADD_PRIMARY_KEY_USING_INDEX, ]; +pub fn data_by_id>(id: S) -> Option<&'static StaticHintData> { + ALL.iter().find(|hint| hint.id == id.as_ref()).copied() +} + #[cfg(test)] mod tests { #[test] diff --git a/eugene/src/render_doc_snapshots.rs b/eugene/src/render_doc_snapshots.rs index aa9c104..b719121 100644 --- a/eugene/src/render_doc_snapshots.rs +++ b/eugene/src/render_doc_snapshots.rs @@ -1,6 +1,5 @@ use std::ffi::OsString; use std::fs; -use std::path::PathBuf; use chrono::{DateTime, Utc}; use handlebars::Handlebars; @@ -11,9 +10,10 @@ use rayon::prelude::*; use serde::Serialize; use crate::error::{ContextualError, InnerError}; +use crate::hint_data::{data_by_id, HintId}; use crate::lints::lint; use crate::output::{full_trace_data, GenericHint, Settings}; -use crate::script_discovery::{discover_scripts, script_filters, SortMode}; +use crate::parse_scripts::break_into_files; use crate::{generate_new_test_db, hint_data, output, perform_trace, ClientSource, SqlScript}; static DEFAULT_SETTINGS: Lazy = Lazy::new(|| Settings::new(true, true)); @@ -52,49 +52,47 @@ fn every_lint_has_an_example_migration() -> crate::Result<()> { "No example migration for {}", hint.id ); - let bad_example_path = format!("examples/{}/bad", hint.id); - let entry = fs::read_dir(bad_example_path)?; - assert!( - entry.count() > 0, - "No example of bad migration for {}", + let bad_example_path = format!("examples/{}/bad.sql", hint.id); + let script = fs::read_to_string(bad_example_path)?; + assert!(!script.is_empty(), "Missing example for {}", hint.id); + // In case we put the wrong path into the static hint data + assert_eq!( + script, hint.bad_example, + "Mismatched example for {}", hint.id ); + // Same thing + if let Some(good) = hint.good_example { + assert_eq!( + good, + fs::read_to_string(format!("examples/{}/good.sql", hint.id))? + ); + } } Ok(()) } -fn sorted_dir_files(path: &str) -> crate::Result> { - let dir = fs::read_dir(path)?; - let mut entries = vec![]; - for entry in dir { - let path = entry?.path(); - if path.is_file() { - entries.push(path); - } - } - entries.sort(); - Ok(entries) -} - -fn snapshot_lint(id: &str, subfolder: &str) -> crate::Result { - let example_path = format!("examples/{}/{}", id, subfolder); +fn snapshot_lint(id: &str, kind: &str, script: &str) -> crate::Result { let mut reports = vec![]; - for script in sorted_dir_files(example_path.as_str())? { - let path = script - .to_str() - .expect("Path is not a valid UTF-8 string") - // This isn't very nice, but the snapshots must generate the path text on Windows - .replace('\\', "/"); - let sql = fs::read_to_string(&script)?; - let report = lint(Some(path), sql, &[], false)?; + for (name, sql) in break_into_files(script)? { + let report = lint( + name.map(|n| format!("examples/{id}/{kind}/{n}")), + sql, + &[], + false, + )?; reports.push(output::templates::lint_report_to_markdown(&report)?); } Ok(reports.join("\n")) } -fn snapshot_trace(id: &str, subfolder: &str, output_settings: &Settings) -> crate::Result { - let example_path = format!("examples/{}/{}", id, subfolder); +fn snapshot_trace( + id: &str, + kind: &str, + output_settings: &Settings, + script: &str, +) -> crate::Result { let mut reports = vec![]; let db = generate_new_test_db(); let mut connection_settings = ClientSource::new( @@ -104,12 +102,14 @@ fn snapshot_trace(id: &str, subfolder: &str, output_settings: &Settings) -> crat 5432, "postgres".to_string(), ); - let sources = discover_scripts(&example_path, script_filters::never, SortMode::Auto)?; - for script in sources { - let path = script.name().replace('\\', "/"); - let sql = script.read()?; - let sql_script = SqlScript { name: path, sql }; + for (name, script) in break_into_files(script)? { + let path = format!("examples/{}/{kind}/{}", id, name.unwrap()); + let sql = script.into(); + let sql_script = SqlScript { + name: path.into(), + sql, + }; let trace = perform_trace(&sql_script, &mut connection_settings, &[], true)?; let mut report = full_trace_data(&trace, *output_settings); @@ -147,19 +147,19 @@ fn hint_folder>(id: S) -> String { fn write_lints(id: &str) -> crate::Result { let mut changed = false; + let data = data_by_id(id).expect("Hint not found"); let hint_folder = hint_folder(id); fs::create_dir_all(hint_folder.as_str())?; - if is_migration_set_up(id, "bad") { - let bad = snapshot_lint(id, "bad")?; - let bad_path = format!("{hint_folder}/unsafe_lint.md"); - let prior = fs::read_to_string(&bad_path).unwrap_or_default(); - if prior != bad { - changed = true; - } - fs::write(bad_path, bad)?; + let bad = snapshot_lint(id, "bad", data.bad_example)?; + let bad_path = format!("{hint_folder}/unsafe_lint.md"); + let prior = fs::read_to_string(&bad_path).unwrap_or_default(); + if prior != bad { + changed = true; } - if is_migration_set_up(id, "good") { - let good = snapshot_lint(id, "good")?; + fs::write(bad_path, bad)?; + + if let Some(script) = data.good_example { + let good = snapshot_lint(id, "good", script)?; let good_path = format!("{hint_folder}/safer_lint.md"); let prior = fs::read_to_string(&good_path).unwrap_or_default(); if prior != good { @@ -167,33 +167,31 @@ fn write_lints(id: &str) -> crate::Result { } fs::write(good_path, good)?; } + Ok(changed) } -fn is_migration_set_up(id: &str, subfolder: &str) -> bool { - let example_path = format!("examples/{}/{}/1.sql", id, subfolder); +fn is_migration_set_up(id: &str, kind: &str) -> bool { + let example_path = format!("examples/{}/{}.sql", id, kind); fs::metadata(example_path).is_ok() } fn write_traces(id: &str) -> crate::Result { let mut out = false; - hint_data::ALL - .iter() - .find(|hint| hint.id == id) - .expect("Hint not found"); + let data = data_by_id(id).expect("Hint not found"); let hint_folder = hint_folder(id); fs::create_dir_all(hint_folder.as_str())?; - if is_migration_set_up(id, "bad") { - let bad = snapshot_trace(id, "bad", &DEFAULT_SETTINGS)?; - let bad_path = format!("{hint_folder}/unsafe_trace.md"); - let prior = fs::read_to_string(&bad_path).unwrap_or_default(); - if prior != bad { - out = true; - } - fs::write(bad_path, bad)?; + + let bad = snapshot_trace(id, "bad", &DEFAULT_SETTINGS, data.bad_example)?; + let bad_path = format!("{hint_folder}/unsafe_trace.md"); + let prior = fs::read_to_string(&bad_path).unwrap_or_default(); + if prior != bad { + out = true; } - if is_migration_set_up(id, "good") { - let good = snapshot_trace(id, "good", &DEFAULT_SETTINGS)?; + fs::write(bad_path, bad)?; + + if let Some(script) = data.good_example { + let good = snapshot_trace(id, "good", &DEFAULT_SETTINGS, script)?; let good_path = format!("{hint_folder}/safer_trace.md"); let prior = fs::read_to_string(&good_path).unwrap_or_default(); if prior != good { @@ -201,6 +199,7 @@ fn write_traces(id: &str) -> crate::Result { } fs::write(good_path, good)?; } + Ok(out) } @@ -244,7 +243,8 @@ fn snapshot_traces() -> crate::Result<()> { #[test] fn test_trace_with_extra_locks() { let output_settings = Settings::new(false, true); - let r = snapshot_trace("E10", "bad", &output_settings).unwrap(); + let data = data_by_id("E10").unwrap(); + let r = snapshot_trace(data.id(), "bad", &output_settings, data.bad_example).unwrap(); let path = "examples/snapshots/extra_locks.md"; let prior = fs::read_to_string(path).unwrap_or_default(); fs::write(path, &r).unwrap(); @@ -257,7 +257,8 @@ fn test_trace_with_extra_locks() { #[test] fn test_trace_with_summary() { let output_settings = Settings::new(true, false); - let r = snapshot_trace("E10", "bad", &output_settings).unwrap(); + let data = data_by_id("E10").unwrap(); + let r = snapshot_trace(data.id(), "bad", &output_settings, data.bad_example).unwrap(); let path = "examples/snapshots/summary.md"; let prior = fs::read_to_string(path).unwrap_or_default(); fs::write(path, &r).unwrap(); @@ -270,7 +271,8 @@ fn test_trace_with_summary() { #[test] fn test_trace_with_summary_and_extra_locks() { let output_settings = Settings::new(true, true); - let r = snapshot_trace("E10", "bad", &output_settings).unwrap(); + let data = data_by_id("E10").unwrap(); + let r = snapshot_trace(data.id(), "bad", &output_settings, data.bad_example).unwrap(); let path = "examples/snapshots/summary_extra_locks.md"; let prior = fs::read_to_string(path).unwrap_or_default(); fs::write(path, &r).unwrap(); @@ -288,22 +290,9 @@ struct HintPage<'a> { supported_by: &'a str, } -fn read_script(id: &str, subfolder: &str) -> crate::Result { - let mut script = String::new(); - let example_path = format!("examples/{}/{}", id, subfolder); - let scripts = sorted_dir_files(example_path.as_str())?; - for sql_script in scripts { - let sql = fs::read_to_string(&sql_script)?; - let name = sql_script - .iter() - .last() - .expect("No file name") - .to_str() - .expect("Path is not a valid UTF-8 string"); - script.push_str(&format!("-- {}\n\n", name)); - script.push_str(&sql); - script.push('\n'); - } +fn read_script(id: &str, kind: &str) -> crate::Result { + let example_path = format!("examples/{}/{}.sql", id, kind); + let mut script = fs::read_to_string(&example_path)?; if script.ends_with('\n') { script.pop(); } From 033112c068fd40910ea95a5df780825af8053a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20K=C3=A5veland?= Date: Sat, 15 Jun 2024 15:52:04 +0200 Subject: [PATCH 2/4] Make the demo capable of drawing random examples --- .github/workflows/run_tests.yml | 1 + eugene-web/src/webapp.rs | 9 +++++ eugene/docs/src/introduction.md | 16 ++++++++ eugene/src/git.rs | 60 ++++++++++++++++-------------- eugene/src/render_doc_snapshots.rs | 7 +--- eugene/src/tempserver.rs | 4 +- 6 files changed, 63 insertions(+), 34 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 997353a..aa53506 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -10,6 +10,7 @@ on: env: CARGO_TERM_COLOR: always + RUST_BACKTRACE: "1" jobs: run_tests_ubuntu: runs-on: ubuntu-latest diff --git a/eugene-web/src/webapp.rs b/eugene-web/src/webapp.rs index 3bb5a6e..c9cb503 100644 --- a/eugene-web/src/webapp.rs +++ b/eugene-web/src/webapp.rs @@ -1,5 +1,7 @@ +use crate::webapp; use axum::routing::{get, post}; use axum::Router; +use eugene::hint_data::ALL; pub mod error; pub mod index; @@ -9,10 +11,17 @@ pub mod lint_raw; pub mod requestlog; pub mod templates; +async fn random_sql() -> Result { + let n: usize = rand::random(); + let choice = n % ALL.len(); + Ok(ALL[choice].bad_example) +} + pub fn routes() -> Router { Router::new() .route("/", get(index::render_index)) .route("/lint.html", post(lint_html::lint_html)) .route("/lint.json", post(lint_json::json_lint_handler)) .route("/lint.raw", post(lint_raw::raw_lint_handler)) + .route("/random.sql", get(random_sql)) } diff --git a/eugene/docs/src/introduction.md b/eugene/docs/src/introduction.md index ef65769..96a51bd 100644 --- a/eugene/docs/src/introduction.md +++ b/eugene/docs/src/introduction.md @@ -61,7 +61,23 @@ function check_for_413(event) { } } +
+ + +
diff --git a/eugene/src/git.rs b/eugene/src/git.rs index 633aacf..e3e2646 100644 --- a/eugene/src/git.rs +++ b/eugene/src/git.rs @@ -241,9 +241,8 @@ impl GitFilter { #[cfg(test)] mod tests { - use pretty_assertions::assert_eq; - use tempfile::TempDir; + use tempfile::{Builder, TempDir}; use super::*; @@ -321,17 +320,19 @@ mod tests { #[test] fn test_unstaged() { - let tmp = TempDir::new().unwrap(); + let tmp = Builder::new() + .prefix("eugene-test-unstaged") + .tempdir() + .unwrap(); + let p = tmp.path(); Command::new("git") .arg("init") - .current_dir(tmp.path()) + .current_dir(p) .output() .unwrap(); - assert!(unstaged_children(tmp.path().to_str().unwrap()) - .unwrap() - .is_empty()); - assert!(unstaged_children(tmp.path().join("foo").to_str().unwrap()).is_err()); - let fp = tmp.path().join("foo"); + assert!(unstaged_children(p.to_str().unwrap()).unwrap().is_empty()); + assert!(unstaged_children(p.join("foo").to_str().unwrap()).is_err()); + let fp = p.join("foo"); std::fs::write(&fp, "hei").unwrap(); assert_eq!( unstaged_children(fp.to_str().unwrap()).unwrap(), @@ -341,15 +342,19 @@ mod tests { #[test] fn test_gitref_exists() { - let tmp = TempDir::new().unwrap(); - configure_git(tmp.path()); - assert!(git_ref_exists("main", tmp.path()).is_err()); - let fp = tmp.path().join("foo"); + let tmp = Builder::new() + .prefix("eugene-test-gitref-exists") + .tempdir() + .unwrap(); + let p = tmp.path(); + configure_git(p); + assert!(git_ref_exists("main", p).is_err()); + let fp = p.join("foo"); std::fs::write(fp, "hei").unwrap(); let o = Command::new("git") .arg("add") .arg("foo") - .current_dir(tmp.path()) + .current_dir(p) .output() .unwrap(); eprintln!("{o:?}"); @@ -357,31 +362,32 @@ mod tests { .arg("commit") .arg("-m") .arg("initial") - .current_dir(tmp.path()) + .current_dir(p) .output() .unwrap(); eprintln!("{o:?}"); - assert!(git_ref_exists("main", tmp.path()).is_ok()); - assert!(git_ref_exists("nonono", tmp.path()).is_err()); + assert!(git_ref_exists("main", p).is_ok()); + assert!(git_ref_exists("nonono", p).is_err()); } #[test] fn test_diff() { - let tmp = TempDir::new().unwrap(); - configure_git(tmp.path()); - let fp = tmp.path().join("foo"); + let tmp = Builder::new().prefix("eugene-test-diff").tempdir().unwrap(); + let p = tmp.path(); + configure_git(p); + let fp = p.join("foo"); std::fs::write(&fp, "hei").unwrap(); Command::new("git") .arg("add") .arg("foo") - .current_dir(tmp.path()) + .current_dir(p) .output() .unwrap(); Command::new("git") .arg("commit") .arg("-m") .arg("initial") - .current_dir(tmp.path()) + .current_dir(p) .output() .unwrap(); assert!(diff_files_since_ref(&fp, "main").unwrap().is_empty(),); @@ -389,22 +395,22 @@ mod tests { .arg("checkout") .arg("-b") .arg("newbranch") - .current_dir(tmp.path()) + .current_dir(p) .output() .unwrap(); - let fp2 = tmp.path().join("bar"); + let fp2 = p.join("bar"); std::fs::write(&fp2, "hei").unwrap(); Command::new("git") .arg("add") .arg("bar") - .current_dir(tmp.path()) + .current_dir(p) .output() .unwrap(); Command::new("git") .arg("commit") .arg("-m") .arg("new file") - .current_dir(tmp.path()) + .current_dir(p) .output() .unwrap(); // The new file is contained in the diff with main @@ -413,7 +419,7 @@ mod tests { vec![fp2.to_str().unwrap()] ); assert_eq!( - diff_files_since_ref(tmp.path(), "main").unwrap(), + diff_files_since_ref(p, "main").unwrap(), vec![fp2.to_str().unwrap()] ); diff --git a/eugene/src/render_doc_snapshots.rs b/eugene/src/render_doc_snapshots.rs index b719121..3eb7b48 100644 --- a/eugene/src/render_doc_snapshots.rs +++ b/eugene/src/render_doc_snapshots.rs @@ -106,10 +106,7 @@ fn snapshot_trace( for (name, script) in break_into_files(script)? { let path = format!("examples/{}/{kind}/{}", id, name.unwrap()); let sql = script.into(); - let sql_script = SqlScript { - name: path.into(), - sql, - }; + let sql_script = SqlScript { name: path, sql }; let trace = perform_trace(&sql_script, &mut connection_settings, &[], true)?; let mut report = full_trace_data(&trace, *output_settings); @@ -292,7 +289,7 @@ struct HintPage<'a> { fn read_script(id: &str, kind: &str) -> crate::Result { let example_path = format!("examples/{}/{}.sql", id, kind); - let mut script = fs::read_to_string(&example_path)?; + let mut script = fs::read_to_string(example_path)?; if script.ends_with('\n') { script.pop(); } diff --git a/eugene/src/tempserver.rs b/eugene/src/tempserver.rs index 64c21f4..2c84464 100644 --- a/eugene/src/tempserver.rs +++ b/eugene/src/tempserver.rs @@ -8,7 +8,7 @@ use crate::error::{ContextualError, InnerError}; use crate::{ClientSource, WithClient}; use log::{debug, error, info, warn}; use postgres::Client; -use tempfile::TempDir; +use tempfile::{Builder, TempDir}; pub struct TempServer { dbpath: Option, @@ -22,7 +22,7 @@ impl TempServer { pub fn new(postgres_options: &str, initdb_options: &[String]) -> crate::Result { let port = find_free_port_on_localhost()?; check_required_postgres_commands()?; - let dbpath = TempDir::new()?; + let dbpath = Builder::new().prefix("eugene-temp-postgres").tempdir()?; let mut superuser_password = String::new(); while superuser_password.len() < 20 { let rand_byte: u8 = rand::random(); From 4068c5f6b0372144eb4fed01e8c2d78ec1cba136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20K=C3=A5veland?= Date: Sat, 15 Jun 2024 17:01:31 +0200 Subject: [PATCH 3/4] Try fsyncing tempdirs --- eugene/src/git.rs | 13 ++++++++++++- eugene/src/lib.rs | 15 +++++++++++++++ eugene/src/tempserver.rs | 2 ++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/eugene/src/git.rs b/eugene/src/git.rs index e3e2646..cd55498 100644 --- a/eugene/src/git.rs +++ b/eugene/src/git.rs @@ -241,7 +241,10 @@ impl GitFilter { #[cfg(test)] mod tests { + use crate::utils::FsyncDir; + use anyhow::Context; use pretty_assertions::assert_eq; + use std::fs; use tempfile::{Builder, TempDir}; use super::*; @@ -280,6 +283,7 @@ mod tests { .arg("main") .current_dir(path) .output() + .context(format!("Failed to configure git in {path:?}")) .unwrap(); Command::new("git") .arg("config") @@ -287,6 +291,7 @@ mod tests { .arg("ci@example.com") .current_dir(path) .output() + .context(format!("Failed to configure git in {path:?}")) .unwrap(); Command::new("git") .arg("config") @@ -294,6 +299,7 @@ mod tests { .arg("ci@example.com") .current_dir(path) .output() + .context(format!("Failed to configure git in {path:?}")) .unwrap(); } @@ -301,7 +307,7 @@ mod tests { fn test_nearest_dir() { let tmp = TempDir::new().unwrap(); let fp = tmp.path().join("foo"); - std::fs::write(&fp, "").unwrap(); + fs::write(&fp, "").unwrap(); assert_eq!(nearest_directory(fp).unwrap(), tmp.path()); assert_eq!(nearest_directory(tmp.path()).unwrap(), tmp.path()); let subdir = tmp.path().join("subdir"); @@ -324,11 +330,13 @@ mod tests { .prefix("eugene-test-unstaged") .tempdir() .unwrap(); + tmp.fsync().unwrap(); let p = tmp.path(); Command::new("git") .arg("init") .current_dir(p) .output() + .context(format!("Failed to git init in {p:?}")) .unwrap(); assert!(unstaged_children(p.to_str().unwrap()).unwrap().is_empty()); assert!(unstaged_children(p.join("foo").to_str().unwrap()).is_err()); @@ -346,7 +354,9 @@ mod tests { .prefix("eugene-test-gitref-exists") .tempdir() .unwrap(); + tmp.fsync().unwrap(); let p = tmp.path(); + configure_git(p); assert!(git_ref_exists("main", p).is_err()); let fp = p.join("foo"); @@ -373,6 +383,7 @@ mod tests { #[test] fn test_diff() { let tmp = Builder::new().prefix("eugene-test-diff").tempdir().unwrap(); + tmp.fsync().unwrap(); let p = tmp.path(); configure_git(p); let fp = p.join("foo"); diff --git a/eugene/src/lib.rs b/eugene/src/lib.rs index e6deab1..361a7c4 100644 --- a/eugene/src/lib.rs +++ b/eugene/src/lib.rs @@ -59,6 +59,21 @@ pub mod error; /// Utilities for invoking git pub mod git; +pub mod utils { + use std::path::Path; + + pub trait FsyncDir { + fn fsync(&self) -> Result<(), std::io::Error>; + } + + impl> FsyncDir for P { + fn fsync(&self) -> Result<(), std::io::Error> { + let dir = std::fs::File::open(self)?; + dir.sync_all() + } + } +} + pub struct SqlScript { pub name: String, pub sql: String, diff --git a/eugene/src/tempserver.rs b/eugene/src/tempserver.rs index 2c84464..c172b1a 100644 --- a/eugene/src/tempserver.rs +++ b/eugene/src/tempserver.rs @@ -5,6 +5,7 @@ use std::thread::{spawn, JoinHandle}; use crate::error::InnerError::UnableToInitDb; use crate::error::{ContextualError, InnerError}; +use crate::utils::FsyncDir; use crate::{ClientSource, WithClient}; use log::{debug, error, info, warn}; use postgres::Client; @@ -23,6 +24,7 @@ impl TempServer { let port = find_free_port_on_localhost()?; check_required_postgres_commands()?; let dbpath = Builder::new().prefix("eugene-temp-postgres").tempdir()?; + dbpath.fsync()?; let mut superuser_password = String::new(); while superuser_password.len() < 20 { let rand_byte: u8 = rand::random(); From 040d6d1c48a44a5e98cbb93b3efc3609e941e963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20K=C3=A5veland?= Date: Sat, 15 Jun 2024 17:13:22 +0200 Subject: [PATCH 4/4] Add retries to git configuration for integration tests --- eugene/src/git.rs | 73 ++++++++++++++++++++++++++--------------------- eugene/src/lib.rs | 11 +++++-- 2 files changed, 49 insertions(+), 35 deletions(-) diff --git a/eugene/src/git.rs b/eugene/src/git.rs index cd55498..235ecf8 100644 --- a/eugene/src/git.rs +++ b/eugene/src/git.rs @@ -242,9 +242,10 @@ impl GitFilter { #[cfg(test)] mod tests { use crate::utils::FsyncDir; - use anyhow::Context; use pretty_assertions::assert_eq; use std::fs; + use std::thread::sleep; + use std::time::Duration; use tempfile::{Builder, TempDir}; use super::*; @@ -277,30 +278,41 @@ mod tests { } fn configure_git(path: &Path) { - Command::new("git") - .arg("init") - .arg("-b") - .arg("main") - .current_dir(path) - .output() - .context(format!("Failed to configure git in {path:?}")) - .unwrap(); - Command::new("git") - .arg("config") - .arg("user.email") - .arg("ci@example.com") - .current_dir(path) - .output() - .context(format!("Failed to configure git in {path:?}")) - .unwrap(); - Command::new("git") - .arg("config") - .arg("user.name") - .arg("ci@example.com") - .current_dir(path) - .output() - .context(format!("Failed to configure git in {path:?}")) - .unwrap(); + fn inner(path: &Path) -> std::io::Result<()> { + Command::new("git") + .arg("init") + .arg("-b") + .arg("main") + .current_dir(path) + .output()?; + Command::new("git") + .arg("config") + .arg("user.email") + .arg("ci@example.com") + .current_dir(path) + .output()?; + Command::new("git") + .arg("config") + .arg("user.name") + .arg("ci@example.com") + .current_dir(path) + .output()?; + path.fsync()?; + Ok(()) + } + let mut attempt = 0; + loop { + match inner(path) { + Ok(_) => break, + Err(e) => { + attempt += 1; + sleep(Duration::from_millis(100)); + if attempt > 5 { + panic!("Failed to configure git in {path:?} after 3 attempts: {e}"); + } + } + } + } } #[test] @@ -332,16 +344,11 @@ mod tests { .unwrap(); tmp.fsync().unwrap(); let p = tmp.path(); - Command::new("git") - .arg("init") - .current_dir(p) - .output() - .context(format!("Failed to git init in {p:?}")) - .unwrap(); + configure_git(p); assert!(unstaged_children(p.to_str().unwrap()).unwrap().is_empty()); assert!(unstaged_children(p.join("foo").to_str().unwrap()).is_err()); let fp = p.join("foo"); - std::fs::write(&fp, "hei").unwrap(); + fs::write(&fp, "hei").unwrap(); assert_eq!( unstaged_children(fp.to_str().unwrap()).unwrap(), vec![fp.to_str().unwrap()] @@ -387,7 +394,7 @@ mod tests { let p = tmp.path(); configure_git(p); let fp = p.join("foo"); - std::fs::write(&fp, "hei").unwrap(); + fs::write(&fp, "hei").unwrap(); Command::new("git") .arg("add") .arg("foo") diff --git a/eugene/src/lib.rs b/eugene/src/lib.rs index 361a7c4..71e1c4c 100644 --- a/eugene/src/lib.rs +++ b/eugene/src/lib.rs @@ -68,8 +68,15 @@ pub mod utils { impl> FsyncDir for P { fn fsync(&self) -> Result<(), std::io::Error> { - let dir = std::fs::File::open(self)?; - dir.sync_all() + #[cfg(not(windows))] + { + let dir = std::fs::File::open(self)?; + dir.sync_all() + } + #[cfg(windows)] + { + Ok(()) + } } } }