From 4a8c563dddf72ef21c3174bc541bcffa9f4722dd Mon Sep 17 00:00:00 2001 From: Tassos Bareiss Date: Thu, 11 Nov 2021 10:02:31 -0700 Subject: [PATCH 1/3] Find tables in using clause of delete statement --- lib/pg_query/parse.rb | 6 ++++++ spec/lib/parse_spec.rb | 42 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/lib/pg_query/parse.rb b/lib/pg_query/parse.rb index 0dd08851..81b8b3b1 100644 --- a/lib/pg_query/parse.rb +++ b/lib/pg_query/parse.rb @@ -149,6 +149,12 @@ def load_objects! # rubocop:disable Metrics/CyclomaticComplexity subselect_items << statement.update_stmt.where_clause if statement.node == :update_stmt && statement.update_stmt.where_clause subselect_items << statement.delete_stmt.where_clause if statement.node == :delete_stmt && statement.delete_stmt.where_clause + if statement.node == :delete_stmt + statement.delete_stmt.using_clause.each do |using_clause| + from_clause_items << { item: using_clause, type: :select } + end + end + if value.with_clause cte_statements, cte_names = statements_and_cte_names_for_with_clause(value.with_clause) @cte_names.concat(cte_names) diff --git a/spec/lib/parse_spec.rb b/spec/lib/parse_spec.rb index 8514818f..df50f9d8 100644 --- a/spec/lib/parse_spec.rb +++ b/spec/lib/parse_spec.rb @@ -1534,16 +1534,52 @@ it 'finds tables referenced in the FROM clause' do query = described_class.parse(<<-SQL) - UPDATE users SET name = users_new.name FROM users_new WHERE users.id = users_new.id + UPDATE users SET name = users_new.name + FROM users_new + INNER JOIN join_table ON join_table.user_id = new_users.id + WHERE users.id = users_new.id SQL expect(query.warnings).to be_empty - expect(query.tables).to eq(['users', 'users_new']) - expect(query.select_tables).to eq(['users_new']) + expect(query.tables).to eq(['users', 'users_new', 'join_table']) + expect(query.select_tables).to eq(['users_new', 'join_table']) expect(query.dml_tables).to eq(['users']) expect(query.ddl_tables).to eq([]) end end + describe 'parsing DELETE' do + it 'finds the deleted table' do + query = described_class.parse(<<-SQL) + delete from users; + SQL + expect(query.warnings).to be_empty + expect(query.tables).to eq(['users']) + expect(query.dml_tables).to eq(['users']) + end + + it 'finds the used table' do + query = described_class.parse(<<-SQL) + delete from users using foo + where foo_id = foo.id and foo.action = 'delete'; + SQL + expect(query.warnings).to be_empty + expect(query.tables).to eq(['users', 'foo']) + expect(query.dml_tables).to eq(['users']) + expect(query.select_tables).to eq(['foo']) + end + + it 'finds the table in the where subquery' do + query = described_class.parse(<<-SQL) + delete from users + where foo_id IN (select id from foo where action = 'delete'); + SQL + expect(query.warnings).to be_empty + expect(query.tables).to eq(['users', 'foo']) + expect(query.dml_tables).to eq(['users']) + expect(query.select_tables).to eq(['foo']) + end + end + it 'handles DROP TYPE' do query = described_class.parse("DROP TYPE IF EXISTS repack.pk_something") expect(query.warnings).to eq [] From ec0f8c0ab687f98201980e54f5ba8b69a9930e49 Mon Sep 17 00:00:00 2001 From: Tassos Bareiss Date: Fri, 12 Nov 2021 10:20:27 -0700 Subject: [PATCH 2/3] Uppercase SQL in spec/lib/parse_spec.rb Co-authored-by: Olle Jonsson --- spec/lib/parse_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/parse_spec.rb b/spec/lib/parse_spec.rb index df50f9d8..72fee6cc 100644 --- a/spec/lib/parse_spec.rb +++ b/spec/lib/parse_spec.rb @@ -1550,7 +1550,7 @@ describe 'parsing DELETE' do it 'finds the deleted table' do query = described_class.parse(<<-SQL) - delete from users; + DELETE FROM users; SQL expect(query.warnings).to be_empty expect(query.tables).to eq(['users']) From 0ba3d979b86a64303cf75e0944abc03a451ab917 Mon Sep 17 00:00:00 2001 From: Tassos Bareiss Date: Fri, 12 Nov 2021 10:21:24 -0700 Subject: [PATCH 3/3] Apply suggestions from code review Uppercase SQL in new specs Co-authored-by: Olle Jonsson --- spec/lib/parse_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/lib/parse_spec.rb b/spec/lib/parse_spec.rb index 72fee6cc..d3114e19 100644 --- a/spec/lib/parse_spec.rb +++ b/spec/lib/parse_spec.rb @@ -1559,8 +1559,8 @@ it 'finds the used table' do query = described_class.parse(<<-SQL) - delete from users using foo - where foo_id = foo.id and foo.action = 'delete'; + DELETE FROM users USING foo + WHERE foo_id = foo.id AND foo.action = 'delete'; SQL expect(query.warnings).to be_empty expect(query.tables).to eq(['users', 'foo']) @@ -1570,8 +1570,8 @@ it 'finds the table in the where subquery' do query = described_class.parse(<<-SQL) - delete from users - where foo_id IN (select id from foo where action = 'delete'); + DELETE FROM users + WHERE foo_id IN (SELECT id FROM foo WHERE action = 'delete'); SQL expect(query.warnings).to be_empty expect(query.tables).to eq(['users', 'foo'])