pg_query 0.11.5 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Rakefile +1 -1
- data/ext/pg_query/extconf.rb +2 -2
- data/lib/pg_query/deparse.rb +27 -18
- data/lib/pg_query/deparse/alter_table.rb +1 -1
- data/lib/pg_query/deparse/interval.rb +15 -15
- data/lib/pg_query/filter_columns.rb +5 -4
- data/lib/pg_query/param_refs.rb +1 -1
- data/lib/pg_query/parse.rb +7 -6
- data/lib/pg_query/treewalker.rb +6 -6
- data/lib/pg_query/truncate.rb +1 -1
- data/lib/pg_query/version.rb +1 -1
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61359adbe400bc68cb1dc1d922483daf361eb143
|
4
|
+
data.tar.gz: b9af1134fffbcb19935c16ee0ce9c3571a27d6ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe42b2f8e3ccf33bbebca91340f9f1cc22439064a7ada8b8d3fac2ad8ea7e22f3d4ced2afd27c35b730a835b2b18b798c0e12e66a0a246edcd4fe04e661690cf
|
7
|
+
data.tar.gz: 12b4a53a3496c59ff0f275fc6a6e6829035593d360f098ecebf5d276aeb9324360d0f11dd3a836fa80eaa38b8822fa37ea54462b1df54d48204481305dea0b22
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.12.0 2017-07-29
|
4
|
+
|
5
|
+
* Update libpg_query to 9.5-1.6.0
|
6
|
+
* BREAKING CHANGE in PgQuery.normalize(..) output
|
7
|
+
* This matches the change in the upcoming Postgres 10, and makes it easier to
|
8
|
+
migrate applications to the new normalization format using $1..$N instead of ?
|
9
|
+
|
10
|
+
|
3
11
|
## 0.11.5 2017-07-09
|
4
12
|
|
5
13
|
* Deparse coldeflist [#64](https://github.com/lfittl/pg_query/pull/64) [@jcsjcs](https://github.com/jcsjcs)
|
data/Rakefile
CHANGED
data/ext/pg_query/extconf.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'mkmf'
|
4
4
|
require 'open-uri'
|
5
5
|
|
6
|
-
LIB_PG_QUERY_TAG = '9.5-1.
|
6
|
+
LIB_PG_QUERY_TAG = '9.5-1.6.0'.freeze
|
7
7
|
|
8
8
|
workdir = Dir.pwd
|
9
9
|
libdir = File.join(workdir, 'libpg_query-' + LIB_PG_QUERY_TAG)
|
@@ -19,7 +19,7 @@ unless File.exist?("#{workdir}/libpg_query.tar.gz")
|
|
19
19
|
end
|
20
20
|
|
21
21
|
unless Dir.exist?(libdir)
|
22
|
-
system("tar -xf #{workdir}/libpg_query.tar.gz") ||
|
22
|
+
system("tar -xf #{workdir}/libpg_query.tar.gz") || raise('ERROR')
|
23
23
|
end
|
24
24
|
|
25
25
|
unless Dir.exist?(libfile)
|
data/lib/pg_query/deparse.rb
CHANGED
@@ -43,7 +43,7 @@ class PgQuery
|
|
43
43
|
when AEXPR_NULLIF
|
44
44
|
deparse_aexpr_nullif(node)
|
45
45
|
else
|
46
|
-
|
46
|
+
raise format("Can't deparse: %s: %s", type, node.inspect)
|
47
47
|
end
|
48
48
|
when ALIAS
|
49
49
|
deparse_alias(node)
|
@@ -161,7 +161,7 @@ class PgQuery
|
|
161
161
|
when NULL
|
162
162
|
'NULL'
|
163
163
|
else
|
164
|
-
|
164
|
+
raise format("Can't deparse: %s: %s", type, node.inspect)
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
@@ -171,7 +171,10 @@ class PgQuery
|
|
171
171
|
|
172
172
|
def deparse_rangevar(node)
|
173
173
|
output = []
|
174
|
-
|
174
|
+
case node['inhOpt']
|
175
|
+
when 0
|
176
|
+
output << 'ONLY'
|
177
|
+
end
|
175
178
|
output << '"' + node['relname'] + '"'
|
176
179
|
output << deparse_item(node['alias']) if node['alias']
|
177
180
|
output.join(' ')
|
@@ -180,13 +183,14 @@ class PgQuery
|
|
180
183
|
def deparse_renamestmt(node)
|
181
184
|
output = []
|
182
185
|
|
183
|
-
|
186
|
+
case node['renameType']
|
187
|
+
when OBJECT_TYPE_TABLE
|
184
188
|
output << 'ALTER TABLE'
|
185
189
|
output << deparse_item(node['relation'])
|
186
190
|
output << 'RENAME TO'
|
187
191
|
output << node['newname']
|
188
192
|
else
|
189
|
-
|
193
|
+
raise format("Can't deparse: %s", node.inspect)
|
190
194
|
end
|
191
195
|
|
192
196
|
output.join(' ')
|
@@ -276,7 +280,7 @@ class PgQuery
|
|
276
280
|
elsif node['val'].nil?
|
277
281
|
node['name']
|
278
282
|
else
|
279
|
-
|
283
|
+
raise format("Can't deparse %s in context %s", node.inspect, context)
|
280
284
|
end
|
281
285
|
end
|
282
286
|
|
@@ -423,8 +427,12 @@ class PgQuery
|
|
423
427
|
def deparse_joinexpr(node)
|
424
428
|
output = []
|
425
429
|
output << deparse_item(node['larg'])
|
426
|
-
|
427
|
-
|
430
|
+
case node['jointype']
|
431
|
+
when 0
|
432
|
+
output << 'CROSS' if node['quals'].nil?
|
433
|
+
when 1
|
434
|
+
output << 'LEFT'
|
435
|
+
end
|
428
436
|
output << 'JOIN'
|
429
437
|
output << deparse_item(node['rarg'])
|
430
438
|
|
@@ -441,7 +449,7 @@ class PgQuery
|
|
441
449
|
LCS_FORSHARE => 'FOR SHARE',
|
442
450
|
LCS_FORNOKEYUPDATE => 'FOR NO KEY UPDATE',
|
443
451
|
LCS_FORUPDATE => 'FOR UPDATE'
|
444
|
-
}
|
452
|
+
}.freeze
|
445
453
|
def deparse_lockingclause(node)
|
446
454
|
output = []
|
447
455
|
output << LOCK_CLAUSE_STRENGTH[node['strength']]
|
@@ -632,11 +640,11 @@ class PgQuery
|
|
632
640
|
|
633
641
|
def deparse_sublink(node)
|
634
642
|
if node['subLinkType'] == SUBLINK_TYPE_ANY
|
635
|
-
|
643
|
+
format('%s IN (%s)', deparse_item(node['testexpr']), deparse_item(node['subselect']))
|
636
644
|
elsif node['subLinkType'] == SUBLINK_TYPE_EXISTS
|
637
|
-
|
645
|
+
format('EXISTS(%s)', deparse_item(node['subselect']))
|
638
646
|
else
|
639
|
-
|
647
|
+
format('(%s)', deparse_item(node['subselect']))
|
640
648
|
end
|
641
649
|
end
|
642
650
|
|
@@ -791,7 +799,7 @@ class PgQuery
|
|
791
799
|
|
792
800
|
# Intervals are tricky and should be handled in a separate method because
|
793
801
|
# they require performing some bitmask operations.
|
794
|
-
return deparse_interval_type(node) if names == %w
|
802
|
+
return deparse_interval_type(node) if names == %w[pg_catalog interval]
|
795
803
|
|
796
804
|
output = []
|
797
805
|
output << 'SETOF' if node['setof']
|
@@ -844,7 +852,7 @@ class PgQuery
|
|
844
852
|
when 'timestamptz'
|
845
853
|
'timestamp with time zone'
|
846
854
|
else
|
847
|
-
|
855
|
+
raise format("Can't deparse type: %s", type)
|
848
856
|
end
|
849
857
|
end
|
850
858
|
|
@@ -870,9 +878,10 @@ class PgQuery
|
|
870
878
|
|
871
879
|
def deparse_nulltest(node)
|
872
880
|
output = [deparse_item(node['arg'])]
|
873
|
-
|
881
|
+
case node['nulltesttype']
|
882
|
+
when 0
|
874
883
|
output << 'IS NULL'
|
875
|
-
|
884
|
+
when 1
|
876
885
|
output << 'IS NOT NULL'
|
877
886
|
end
|
878
887
|
output.join(' ')
|
@@ -885,10 +894,10 @@ class PgQuery
|
|
885
894
|
TRANS_STMT_SAVEPOINT => 'SAVEPOINT',
|
886
895
|
TRANS_STMT_RELEASE => 'RELEASE',
|
887
896
|
TRANS_STMT_ROLLBACK_TO => 'ROLLBACK TO SAVEPOINT'
|
888
|
-
}
|
897
|
+
}.freeze
|
889
898
|
def deparse_transaction(node)
|
890
899
|
output = []
|
891
|
-
output << TRANSACTION_CMDS[node['kind']] ||
|
900
|
+
output << TRANSACTION_CMDS[node['kind']] || raise(format("Can't deparse TRANSACTION %s", node.inspect))
|
892
901
|
|
893
902
|
if node['options']
|
894
903
|
output += node['options'].map { |item| deparse_item(item) }
|
@@ -15,7 +15,7 @@ class PgQuery
|
|
15
15
|
# ALTER COLUMN {column_name} DROP NOT NULL
|
16
16
|
#
|
17
17
|
def self.commands(node)
|
18
|
-
action = ALTER_TABLE_TYPES_MAPPING[node['subtype']] ||
|
18
|
+
action = ALTER_TABLE_TYPES_MAPPING[node['subtype']] || raise(format("Can't deparse: %s", node.inspect))
|
19
19
|
PgQuery::Deparse.instance_exec(node, &action)
|
20
20
|
end
|
21
21
|
|
@@ -57,7 +57,7 @@ class PgQuery
|
|
57
57
|
26 => 'CENTURY',
|
58
58
|
27 => 'MILLENNIUM',
|
59
59
|
28 => 'DTZMOD'
|
60
|
-
}
|
60
|
+
}.freeze
|
61
61
|
KEYS = MASKS.invert
|
62
62
|
|
63
63
|
# Postgres stores the interval 'day second' as 'day hour minute second' so
|
@@ -75,31 +75,31 @@ class PgQuery
|
|
75
75
|
# { 6 => 'year to month' }
|
76
76
|
#
|
77
77
|
SQL_BY_MASK = {
|
78
|
-
(1 << KEYS['YEAR']) => %w
|
79
|
-
(1 << KEYS['MONTH']) => %w
|
80
|
-
(1 << KEYS['DAY']) => %w
|
81
|
-
(1 << KEYS['HOUR']) => %w
|
82
|
-
(1 << KEYS['MINUTE']) => %w
|
83
|
-
(1 << KEYS['SECOND']) => %w
|
78
|
+
(1 << KEYS['YEAR']) => %w[year],
|
79
|
+
(1 << KEYS['MONTH']) => %w[month],
|
80
|
+
(1 << KEYS['DAY']) => %w[day],
|
81
|
+
(1 << KEYS['HOUR']) => %w[hour],
|
82
|
+
(1 << KEYS['MINUTE']) => %w[minute],
|
83
|
+
(1 << KEYS['SECOND']) => %w[second],
|
84
84
|
(1 << KEYS['YEAR'] |
|
85
|
-
1 << KEYS['MONTH']) => %w
|
85
|
+
1 << KEYS['MONTH']) => %w[year month],
|
86
86
|
(1 << KEYS['DAY'] |
|
87
|
-
1 << KEYS['HOUR']) => %w
|
87
|
+
1 << KEYS['HOUR']) => %w[day hour],
|
88
88
|
(1 << KEYS['DAY'] |
|
89
89
|
1 << KEYS['HOUR'] |
|
90
|
-
1 << KEYS['MINUTE']) => %w
|
90
|
+
1 << KEYS['MINUTE']) => %w[day minute],
|
91
91
|
(1 << KEYS['DAY'] |
|
92
92
|
1 << KEYS['HOUR'] |
|
93
93
|
1 << KEYS['MINUTE'] |
|
94
|
-
1 << KEYS['SECOND']) => %w
|
94
|
+
1 << KEYS['SECOND']) => %w[day second],
|
95
95
|
(1 << KEYS['HOUR'] |
|
96
|
-
1 << KEYS['MINUTE']) => %w
|
96
|
+
1 << KEYS['MINUTE']) => %w[hour minute],
|
97
97
|
(1 << KEYS['HOUR'] |
|
98
98
|
1 << KEYS['MINUTE'] |
|
99
|
-
1 << KEYS['SECOND']) => %w
|
99
|
+
1 << KEYS['SECOND']) => %w[hour second],
|
100
100
|
(1 << KEYS['MINUTE'] |
|
101
|
-
1 << KEYS['SECOND']) => %w
|
102
|
-
}
|
101
|
+
1 << KEYS['SECOND']) => %w[minute second]
|
102
|
+
}.freeze
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -14,7 +14,8 @@ class PgQuery
|
|
14
14
|
statement = statements.shift
|
15
15
|
if statement
|
16
16
|
if statement[SELECT_STMT]
|
17
|
-
|
17
|
+
case statement[SELECT_STMT]['op']
|
18
|
+
when 0
|
18
19
|
if statement[SELECT_STMT][FROM_CLAUSE_FIELD]
|
19
20
|
# FROM subselects
|
20
21
|
statement[SELECT_STMT][FROM_CLAUSE_FIELD].each do |item|
|
@@ -35,7 +36,7 @@ class PgQuery
|
|
35
36
|
statements << item['CommonTableExpr']['ctequery'] if item['CommonTableExpr']
|
36
37
|
end
|
37
38
|
end
|
38
|
-
|
39
|
+
when 1
|
39
40
|
statements << statement[SELECT_STMT]['larg'] if statement[SELECT_STMT]['larg']
|
40
41
|
statements << statement[SELECT_STMT]['rarg'] if statement[SELECT_STMT]['rarg']
|
41
42
|
end
|
@@ -50,7 +51,7 @@ class PgQuery
|
|
50
51
|
next_item = condition_items.shift
|
51
52
|
if next_item
|
52
53
|
if next_item[A_EXPR]
|
53
|
-
%w
|
54
|
+
%w[lexpr rexpr].each do |side|
|
54
55
|
expr = next_item.values[0][side]
|
55
56
|
next unless expr && expr.is_a?(Hash)
|
56
57
|
condition_items << expr
|
@@ -93,7 +94,7 @@ class PgQuery
|
|
93
94
|
next_item = joinexpr_items.shift
|
94
95
|
break unless next_item
|
95
96
|
condition_items << next_item['quals'] if next_item['quals']
|
96
|
-
%w
|
97
|
+
%w[larg rarg].each do |side|
|
97
98
|
next unless next_item[side][JOIN_EXPR]
|
98
99
|
joinexpr_items << next_item[side][JOIN_EXPR]
|
99
100
|
end
|
data/lib/pg_query/param_refs.rb
CHANGED
@@ -36,7 +36,7 @@ class PgQuery
|
|
36
36
|
private
|
37
37
|
|
38
38
|
def param_ref_length(paramref_node)
|
39
|
-
if paramref_node['number'] == 0
|
39
|
+
if paramref_node['number'] == 0 # rubocop:disable Style/NumericPredicate
|
40
40
|
1 # Actually a ? replacement character
|
41
41
|
else
|
42
42
|
('$' + paramref_node['number'].to_s).size
|
data/lib/pg_query/parse.rb
CHANGED
@@ -60,7 +60,8 @@ class PgQuery
|
|
60
60
|
if statement
|
61
61
|
case statement.keys[0]
|
62
62
|
when SELECT_STMT
|
63
|
-
|
63
|
+
case statement[SELECT_STMT]['op']
|
64
|
+
when 0
|
64
65
|
(statement[SELECT_STMT][FROM_CLAUSE_FIELD] || []).each do |item|
|
65
66
|
if item[RANGE_SUBSELECT]
|
66
67
|
statements << item[RANGE_SUBSELECT]['subquery']
|
@@ -78,7 +79,7 @@ class PgQuery
|
|
78
79
|
statements << item[COMMON_TABLE_EXPR]['ctequery']
|
79
80
|
end
|
80
81
|
end
|
81
|
-
|
82
|
+
when 1
|
82
83
|
statements << statement[SELECT_STMT]['larg'] if statement[SELECT_STMT]['larg']
|
83
84
|
statements << statement[SELECT_STMT]['rarg'] if statement[SELECT_STMT]['rarg']
|
84
85
|
end
|
@@ -100,11 +101,11 @@ class PgQuery
|
|
100
101
|
when GRANT_STMT
|
101
102
|
objects = statement[GRANT_STMT]['objects']
|
102
103
|
case statement[GRANT_STMT]['objtype']
|
103
|
-
when 0 # Column
|
104
|
+
when 0 # Column # rubocop:disable Lint/EmptyWhen
|
104
105
|
# FIXME
|
105
106
|
when 1 # Table
|
106
107
|
from_clause_items += objects
|
107
|
-
when 2 # Sequence
|
108
|
+
when 2 # Sequence # rubocop:disable Lint/EmptyWhen
|
108
109
|
# FIXME
|
109
110
|
end
|
110
111
|
when DROP_STMT
|
@@ -131,7 +132,7 @@ class PgQuery
|
|
131
132
|
if next_item
|
132
133
|
case next_item.keys[0]
|
133
134
|
when A_EXPR
|
134
|
-
%w
|
135
|
+
%w[lexpr rexpr].each do |side|
|
135
136
|
elem = next_item.values[0][side]
|
136
137
|
next unless elem
|
137
138
|
if elem.is_a?(Array)
|
@@ -158,7 +159,7 @@ class PgQuery
|
|
158
159
|
|
159
160
|
case next_item.keys[0]
|
160
161
|
when JOIN_EXPR
|
161
|
-
%w
|
162
|
+
%w[larg rarg].each do |side|
|
162
163
|
from_clause_items << next_item[JOIN_EXPR][side]
|
163
164
|
end
|
164
165
|
when ROW_EXPR
|
data/lib/pg_query/treewalker.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class PgQuery
|
2
2
|
private
|
3
3
|
|
4
|
-
def treewalker!(normalized_parsetree
|
4
|
+
def treewalker!(normalized_parsetree)
|
5
5
|
exprs = normalized_parsetree.dup.map { |e| [e, []] }
|
6
6
|
|
7
7
|
loop do
|
@@ -11,7 +11,7 @@ class PgQuery
|
|
11
11
|
expr.each do |k, v|
|
12
12
|
location = parent_location + [k]
|
13
13
|
|
14
|
-
|
14
|
+
yield(expr, k, v, location)
|
15
15
|
|
16
16
|
exprs << [v, location] unless v.nil?
|
17
17
|
end
|
@@ -23,14 +23,14 @@ class PgQuery
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
def find_tree_location(normalized_parsetree, searched_location
|
26
|
+
def find_tree_location(normalized_parsetree, searched_location)
|
27
27
|
treewalker! normalized_parsetree do |expr, k, v, location|
|
28
28
|
next unless location == searched_location
|
29
|
-
|
29
|
+
yield(expr, k, v)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def transform_nodes!(parsetree
|
33
|
+
def transform_nodes!(parsetree)
|
34
34
|
result = deep_dup(parsetree)
|
35
35
|
exprs = result.dup
|
36
36
|
|
@@ -38,7 +38,7 @@ class PgQuery
|
|
38
38
|
expr = exprs.shift
|
39
39
|
|
40
40
|
if expr.is_a?(Hash)
|
41
|
-
|
41
|
+
yield(expr) if expr.size == 1 && expr.keys[0][/^[A-Z]+/]
|
42
42
|
|
43
43
|
exprs += expr.values.compact
|
44
44
|
elsif expr.is_a?(Array)
|
data/lib/pg_query/truncate.rb
CHANGED
@@ -41,7 +41,7 @@ class PgQuery
|
|
41
41
|
treewalker! @tree do |_expr, k, v, location|
|
42
42
|
case k
|
43
43
|
when TARGET_LIST_FIELD
|
44
|
-
length = deparse([{ SELECT_STMT => { k => v } }]).size - 'SELECT '.size
|
44
|
+
length = deparse([{ SELECT_STMT => { k => v } }]).size - 7 # 'SELECT '.size
|
45
45
|
|
46
46
|
truncations << PossibleTruncation.new(location, TARGET_LIST_FIELD, length, true)
|
47
47
|
when 'whereClause'
|
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.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Fittl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -42,30 +42,30 @@ dependencies:
|
|
42
42
|
name: rubocop
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.49.1
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.49.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rubocop-rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.15.1
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 1.15.1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: json
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
142
|
version: '0'
|
143
143
|
requirements: []
|
144
144
|
rubyforge_project:
|
145
|
-
rubygems_version: 2.
|
145
|
+
rubygems_version: 2.6.11
|
146
146
|
signing_key:
|
147
147
|
specification_version: 4
|
148
148
|
summary: PostgreSQL query parsing and normalization library
|