Skip to content

Commit

Permalink
Escape identifiers in more cases, if necessary
Browse files Browse the repository at this point in the history
Based on work done in #136
  • Loading branch information
lfittl committed Jul 1, 2019
1 parent 717380c commit 100a0c5
Show file tree
Hide file tree
Showing 3 changed files with 787 additions and 16 deletions.
21 changes: 16 additions & 5 deletions lib/pg_query/deparse.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
require_relative 'deparse/interval'
require_relative 'deparse/alter_table'
require_relative 'deparse/interval'
require_relative 'deparse/keywords'

class PgQuery
# Reconstruct all of the parsed queries into their original form
def deparse(tree = @tree)
Expand Down Expand Up @@ -194,7 +196,7 @@ def deparse_item(item, context = nil) # rubocop:disable Metrics/CyclomaticComple
elsif [FUNC_CALL, TYPE_NAME, :operator, :defname_as].include?(context)
node['str']
else
format('"%s"', node['str'].gsub('"', '""'))
deparse_identifier(node['str'], escape_always: true)
end
when INTEGER
node['ival'].to_s
Expand All @@ -211,6 +213,15 @@ def deparse_item_list(nodes, context = nil)
nodes.map { |n| deparse_item(n, context) }
end

def deparse_identifier(ident, escape_always: false)
return if ident.nil?
if escape_always || !ident[/^\w+$/] || KEYWORDS.include?(ident.upcase)
format('"%s"', ident.gsub('"', '""'))
else
ident
end
end

def deparse_rangevar(node)
output = []
output << 'ONLY' unless node['inh']
Expand Down Expand Up @@ -283,7 +294,7 @@ def deparse_alias(node)
if node['colnames']
name + '(' + deparse_item_list(node['colnames']).join(', ') + ')'
else
name
deparse_identifier(name)
end
end

Expand Down Expand Up @@ -334,7 +345,7 @@ def deparse_paramref(node)

def deparse_restarget(node, context)
if context == :select
[deparse_item(node['val']), node['name']].compact.join(' AS ')
[deparse_item(node['val']), deparse_identifier(node['name'])].compact.join(' AS ')
elsif context == :update
[node['name'], deparse_item(node['val'])].compact.join(' = ')
elsif node['val'].nil?
Expand Down Expand Up @@ -446,7 +457,7 @@ def deparse_role_spec(node)
return 'CURRENT_USER' if node['roletype'] == 1
return 'SESSION_USER' if node['roletype'] == 2
return 'PUBLIC' if node['roletype'] == 3
format('"%s"', node['rolename'].gsub('"', '""'))
deparse_identifier(node['rolename'], escape_always: true)
end

def deparse_aexpr_in(node)
Expand Down
Loading

0 comments on commit 100a0c5

Please sign in to comment.