Skip to content

Commit

Permalink
Handle UNION, UNION ALL and EXCEPT in SELECT queries
Browse files Browse the repository at this point in the history
Author: Mehmet Emin KARAKAŞ (#136)
  • Loading branch information
lfittl committed Jul 1, 2019
1 parent ef5fc6b commit 823155c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
15 changes: 12 additions & 3 deletions lib/pg_query/deparse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ def deparse_columnref(node)
end

def deparse_a_arrayexp(node)
'ARRAY[' + node['elements'].map do |element|
'ARRAY[' + (node['elements'] || []).map do |element|
deparse_item(element)
end.join(', ') + ']'
end
Expand Down Expand Up @@ -954,6 +954,8 @@ def deparse_when(node)
def deparse_sublink(node)
if node['subLinkType'] == SUBLINK_TYPE_ANY
format('%s IN (%s)', deparse_item(node['testexpr']), deparse_item(node['subselect']))
elsif node['subLinkType'] == SUBLINK_TYPE_ALL
format('%s %s ALL (%s)', deparse_item(node['testexpr']), deparse_item(node['operName'][0], :operator), deparse_item(node['subselect']))
elsif node['subLinkType'] == SUBLINK_TYPE_EXISTS
format('EXISTS(%s)', deparse_item(node['subselect']))
else
Expand All @@ -977,15 +979,22 @@ def deparse_row(node)
def deparse_select(node) # rubocop:disable Metrics/CyclomaticComplexity
output = []

output << deparse_item(node['withClause']) if node['withClause']

if node['op'] == 1
output << deparse_item(node['larg'])
output << 'UNION'
output << 'ALL' if node['all']
output << deparse_item(node['rarg'])
return output.join(' ')
output.join(' ')
end

output << deparse_item(node['withClause']) if node['withClause']
if node['op'] == 3
output << deparse_item(node['larg'])
output << 'EXCEPT'
output << deparse_item(node['rarg'])
output.join(' ')
end

if node[TARGET_LIST_FIELD]
output << 'SELECT'
Expand Down
12 changes: 12 additions & 0 deletions spec/lib/pg_query/deparse_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@
it { is_expected.to eq query }
end

context 'UNION or UNION ALL' do
let(:query) { 'WITH kodsis AS (SELECT * FROM "application"), kodsis2 AS (SELECT * FROM "application") SELECT * FROM "kodsis" UNION SELECT * FROM "kodsis" ORDER BY "id" DESC' }

it { is_expected.to eq query }
end

context 'EXCEPT' do
let(:query) { "SELECT \"a\" FROM \"kodsis\" EXCEPT SELECT \"a\" FROM \"application\"" }

it { is_expected.to eq query }
end

context 'with specific column alias' do
let(:query) { "SELECT * FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) names(\"first\", \"last\")" }

Expand Down

0 comments on commit 823155c

Please sign in to comment.