Skip to content

Commit 6a6556f

Browse files
authored
Support null_test and boolean_test node type with parsing (#335)
When the query like `SELECT col1 FROM t1 WHERE ((SELECT col2 FROM t2 LIMIT 1) IS NULL)` is passed, the subselect_items contain the item with the null_test node type. This null_test node type could contain a table name or a function potentially, but that node type is ignored currently, therefore these table names or functions weren't properly extracted as tables/functions of the query. With this change, by adding the argument of null_test node to the subselect_items list, the arg will be evaluated again later on and will be properly handled. Similarly, support the boolean_test node too.
1 parent 24597b2 commit 6a6556f

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

lib/pg_query/parse.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,14 @@ def load_objects! # rubocop:disable Metrics/CyclomaticComplexity
276276
end
277277
when :bool_expr
278278
subselect_items.concat(next_item.bool_expr.args.to_ary)
279+
when :boolean_test
280+
subselect_items << next_item.boolean_test.arg
279281
when :coalesce_expr
280282
subselect_items.concat(next_item.coalesce_expr.args.to_ary)
281283
when :min_max_expr
282284
subselect_items.concat(next_item.min_max_expr.args.to_ary)
285+
when :null_test
286+
subselect_items << next_item.null_test.arg
283287
when :res_target
284288
subselect_items << next_item.res_target.val
285289
when :sub_link

spec/lib/parse_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,6 +1627,26 @@
16271627
expect(query.select_tables).to eq(['films'])
16281628
end
16291629

1630+
it 'finds tables and functions inside subselects in null_test' do
1631+
query = described_class.parse(<<-SQL)
1632+
SELECT col1 FROM t1 WHERE ((SELECT col2 FROM t2 LIMIT 1) IS NULL) AND ((SELECT * FROM f1() LIMIT 1) IS NULL);
1633+
SQL
1634+
expect(query.tables).to eq(['t1', 't2'])
1635+
expect(query.select_tables).to eq(['t1', 't2'])
1636+
expect(query.dml_tables).to eq([])
1637+
expect(query.ddl_tables).to eq([])
1638+
expect(query.ddl_functions).to eq []
1639+
expect(query.call_functions).to eq ['f1']
1640+
end
1641+
1642+
it 'finds the table in boolean_test' do
1643+
query = described_class.parse(<<-SQL)
1644+
SELECT col1 FROM t1 WHERE (SELECT col2 FROM t2 LIMIT 1) IS TRUE;
1645+
SQL
1646+
expect(query.tables).to eq(['t1', 't2'])
1647+
expect(query.select_tables).to eq(['t1', 't2'])
1648+
end
1649+
16301650
describe 'parsing INSERT' do
16311651
it 'finds the table inserted into' do
16321652
query = described_class.parse(<<-SQL)

0 commit comments

Comments
 (0)