pg_query 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/ext/pg_query/pg_query.c +1 -1
- data/lib/pg_query/parse.rb +6 -157
- data/lib/pg_query/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MDBlYTM5NmYyMDE5MjJiYTgyMjFkZmIwYWU4Y2Y5MzMwMDBkOGU0NA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NmFkMDNkNzBjM2QxZjhmZjQ0NzQwYTZjMDA2YjQ2NjRiMGQ0OTVlZQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDg4YzUyZDZhZDYwZGViNmIzMWFjOWQ3MGRlMGI4MzhmMmNlMWI4YWVhYzFm
|
10
|
+
NjE3NWY5YTczZGMyOWQyYTI0YjJjZDczZjEwZTNjOTkzOTc5ZWE5ZTlkNTI3
|
11
|
+
MDNjZDY1YWI5ZjRiNzJhZGFjMjVjNWUwMzMwODRlNDc4ZjVhYWE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OTJkZjM1NGQzM2M5NGZjZWMyZjM3NTlhOGI2MmU4OWJkOWJiMmM4NDAxMGIw
|
14
|
+
OTQwMTVlZWJhN2EyNGM3ZjA5MmIzZjM3MmNjNjRiOWZjYjE1YWE2MGQwMWM5
|
15
|
+
YmQ0YzIyMWVlZjg2Y2Y5YWRkMGFiODI0NTM2ZTBlYWM4YzI1OTQ=
|
data/ext/pg_query/pg_query.c
CHANGED
@@ -68,7 +68,7 @@ static VALUE pg_query_raw_parse(VALUE self, VALUE input)
|
|
68
68
|
str = StringValueCStr(input);
|
69
69
|
tree = raw_parser(str);
|
70
70
|
|
71
|
-
str =
|
71
|
+
str = nodeToJSONString(tree);
|
72
72
|
|
73
73
|
// Save stderr for result
|
74
74
|
read(stderr_pipe[0], stderr_buffer, STDERR_BUFFER_LEN);
|
data/lib/pg_query/parse.rb
CHANGED
@@ -3,20 +3,19 @@ require 'json'
|
|
3
3
|
class PgQuery
|
4
4
|
def self.parse(query)
|
5
5
|
parsetree, stderr = _raw_parse(query)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
if !parsetree.nil? && !parsetree.empty?
|
10
|
-
parsetree = parsetree_to_json(parsetree)
|
6
|
+
|
7
|
+
begin
|
11
8
|
parsetree = JSON.parse(parsetree, max_nesting: 1000)
|
9
|
+
rescue JSON::ParserError => e
|
10
|
+
raise ParseError.new("Failed to parse JSON", -1)
|
12
11
|
end
|
13
|
-
|
12
|
+
|
14
13
|
warnings = []
|
15
14
|
stderr.each_line do |line|
|
16
15
|
next unless line[/^WARNING/]
|
17
16
|
warnings << line.strip
|
18
17
|
end
|
19
|
-
|
18
|
+
|
20
19
|
PgQuery.new(query, parsetree, warnings)
|
21
20
|
end
|
22
21
|
|
@@ -28,154 +27,4 @@ class PgQuery
|
|
28
27
|
@parsetree = parsetree
|
29
28
|
@warnings = warnings
|
30
29
|
end
|
31
|
-
|
32
|
-
protected
|
33
|
-
def self.parsetree_to_json(str)
|
34
|
-
str.strip!
|
35
|
-
control_chars = '(){}: '
|
36
|
-
location = nil # :hashname, :key, :value
|
37
|
-
structure_stack = [] # :hash, :array (when delimiter opens we push, when delimiter closes we pop)
|
38
|
-
open_string = false
|
39
|
-
escaped_string = false
|
40
|
-
next_char_is_escaped = false
|
41
|
-
double_hash_close_in = 0 # This is used to ask for an additional closing delimiter (added when x = 1 and we reach a closing delimiter)
|
42
|
-
out = ""
|
43
|
-
|
44
|
-
i = 0
|
45
|
-
loop do
|
46
|
-
break if i > str.size-1
|
47
|
-
|
48
|
-
c = str[i]
|
49
|
-
last_location = location
|
50
|
-
char_is_escaped = next_char_is_escaped
|
51
|
-
next_char_is_escaped = false
|
52
|
-
if control_chars.include?(c) && !char_is_escaped && (!open_string || !escaped_string)
|
53
|
-
# Space is not always a control character, skip in those cases
|
54
|
-
if c == ' ' && last_location == :hashname && str[i+1] != ':'
|
55
|
-
out += c
|
56
|
-
i += 1
|
57
|
-
next
|
58
|
-
end
|
59
|
-
|
60
|
-
# Keep empty nodes as empty hashes (e.g. nodes that can't be output)
|
61
|
-
if c == '{' && str[i+1] == '}'
|
62
|
-
out += "{}"
|
63
|
-
out += ", " if i+2 < str.size && !'})'.include?(str[i+2])
|
64
|
-
i += 2 # Skip {}
|
65
|
-
next
|
66
|
-
end
|
67
|
-
|
68
|
-
location = nil # All control characters reset location
|
69
|
-
|
70
|
-
# This should never happen, but if it does, catch it
|
71
|
-
if open_string
|
72
|
-
out += '"' unless escaped_string
|
73
|
-
open_string = false
|
74
|
-
escaped_string = false
|
75
|
-
end
|
76
|
-
|
77
|
-
# Write out JSON control characters
|
78
|
-
if last_location == :hashname
|
79
|
-
out += ': {'
|
80
|
-
elsif last_location == :key
|
81
|
-
out += ': '
|
82
|
-
end
|
83
|
-
|
84
|
-
case c
|
85
|
-
when '('
|
86
|
-
out += '['
|
87
|
-
when ')'
|
88
|
-
out += ']'
|
89
|
-
when '{'
|
90
|
-
out += '{'
|
91
|
-
when '}'
|
92
|
-
out += '}}'
|
93
|
-
when ':'
|
94
|
-
# No JSON equivalent
|
95
|
-
end
|
96
|
-
|
97
|
-
# Handle double hash closes (required for out-of-place nodes like ANY)
|
98
|
-
case c
|
99
|
-
when '{'
|
100
|
-
if double_hash_close_in > 0
|
101
|
-
double_hash_close_in += 1
|
102
|
-
end
|
103
|
-
when '}'
|
104
|
-
if double_hash_close_in == 1
|
105
|
-
out += '}}'
|
106
|
-
double_hash_close_in = 0
|
107
|
-
elsif double_hash_close_in > 1
|
108
|
-
double_hash_close_in -= 1
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Write out delimiter if needed
|
113
|
-
if (last_location == :value || '})'.include?(c)) && i+1 < str.size && !'})'.include?(str[i+1])
|
114
|
-
out += ', '
|
115
|
-
end
|
116
|
-
|
117
|
-
# Determine new location
|
118
|
-
case c
|
119
|
-
when '{'
|
120
|
-
structure_stack << :hash
|
121
|
-
location = :hashname
|
122
|
-
when '('
|
123
|
-
structure_stack << :array
|
124
|
-
location = :value if !control_chars.include?(str[i+1])
|
125
|
-
when '}', ')'
|
126
|
-
structure_stack.pop
|
127
|
-
when ':'
|
128
|
-
location = :key
|
129
|
-
when ' '
|
130
|
-
location = :value if [:value, :key].include?(last_location) && !control_chars.include?(str[i+1])
|
131
|
-
end
|
132
|
-
else
|
133
|
-
if char_is_escaped
|
134
|
-
case c
|
135
|
-
when '"'
|
136
|
-
out += "\\\""
|
137
|
-
when '\\'
|
138
|
-
out += "\\\\"
|
139
|
-
else
|
140
|
-
out += c
|
141
|
-
end
|
142
|
-
elsif str[i] == '<' && str[i+1] == '>' && control_chars.include?(str[i+2])
|
143
|
-
# Make <> into null values
|
144
|
-
i += 1
|
145
|
-
out += "null"
|
146
|
-
elsif c == '\\'
|
147
|
-
next_char_is_escaped = true # For next round
|
148
|
-
# Ignore all other cases
|
149
|
-
elsif c[/[A-Z]/] && !open_string && last_location != :value && last_location != :hashname && structure_stack.last == :hash
|
150
|
-
# We were not expecting a node name here, but this can happen (e.g. with ANY), try to construct into valid expression
|
151
|
-
location = :hashname
|
152
|
-
double_hash_close_in = 1
|
153
|
-
open_string = true
|
154
|
-
out += '"lexpr": {"'
|
155
|
-
out += c
|
156
|
-
elsif control_chars.include?(str[i-1]) && !open_string && !'0123456789'.include?(c)
|
157
|
-
open_string = true
|
158
|
-
escaped_string = true if c == '"'
|
159
|
-
out += '"' unless escaped_string
|
160
|
-
out += c
|
161
|
-
c = nil # To avoid close string taking care of us...
|
162
|
-
else
|
163
|
-
out += c
|
164
|
-
end
|
165
|
-
|
166
|
-
# Close string if next element is control character
|
167
|
-
if open_string && !char_is_escaped && c != '\\' &&
|
168
|
-
((last_location == :hashname && ((str[i+1] == '}') || (str[i+1] == ' ' && str[i+2] == ':') || (str[i+1] == ' ' && str[i+2] == ' ' && str[i+3] == ':'))) ||
|
169
|
-
(last_location != :hashname && !escaped_string && control_chars.include?(str[i+1])) ||
|
170
|
-
(escaped_string && c == '"'))
|
171
|
-
out += '"' unless escaped_string
|
172
|
-
open_string = false
|
173
|
-
escaped_string = false
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
i += 1
|
178
|
-
end
|
179
|
-
out
|
180
|
-
end
|
181
30
|
end
|
data/lib/pg_query/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Fittl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|