pg_query 0.13.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/ext/pg_query/extconf.rb +1 -1
- data/lib/pg_query/deparse.rb +7 -4
- data/lib/pg_query/filter_columns.rb +3 -1
- data/lib/pg_query/fingerprint.rb +5 -1
- data/lib/pg_query/legacy_parsetree.rb +25 -26
- data/lib/pg_query/node_types.rb +77 -26
- data/lib/pg_query/parse.rb +9 -1
- data/lib/pg_query/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b234a246e532789199b80cfdc118cc44f45f56dc
|
4
|
+
data.tar.gz: 9f1b878a7902bfbce4a86a69d96ecdc8bdd4a659
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 642d3c1c1a325d737da9252e72715a16f25dc6c2138c03ebd4503efb231604a5fd13b0265cf5637c0aa12510837560b70e8f4ad90ca94ecaf937301783bc4673
|
7
|
+
data.tar.gz: 269105c0470ee517a15f6bb613609ed0ff50a915e188b1c43510a98c02304eafee38f5c70a3ecfeefdf4bffdacbbe7331ce0c3d6d13d2336af41d8c314b746bb
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.0.0 2017-10-31
|
4
|
+
|
5
|
+
* IMPORTANT: Major version bump to indicate backwards incompatible parse tree change!
|
6
|
+
* Update to Postgres 10 parser and fingerprint version 2
|
7
|
+
- This is a backwards-incompatible change in parser output format, although it should
|
8
|
+
be relatively easy to update most programs. This can't be avoided since Postgres
|
9
|
+
does not guarantee parse trees stay the same across versions
|
10
|
+
|
11
|
+
|
3
12
|
## 0.13.5 2017-10-26
|
4
13
|
|
5
14
|
* Update to libpg_query 9.5-1.7.1
|
data/ext/pg_query/extconf.rb
CHANGED
data/lib/pg_query/deparse.rb
CHANGED
@@ -116,6 +116,8 @@ class PgQuery
|
|
116
116
|
deparse_rangesubselect(node)
|
117
117
|
when RANGE_VAR
|
118
118
|
deparse_rangevar(node)
|
119
|
+
when RAW_STMT
|
120
|
+
deparse_raw_stmt(node)
|
119
121
|
when RENAME_STMT
|
120
122
|
deparse_renamestmt(node)
|
121
123
|
when RES_TARGET
|
@@ -171,15 +173,16 @@ class PgQuery
|
|
171
173
|
|
172
174
|
def deparse_rangevar(node)
|
173
175
|
output = []
|
174
|
-
|
175
|
-
when 0
|
176
|
-
output << 'ONLY'
|
177
|
-
end
|
176
|
+
output << 'ONLY' unless node['inh']
|
178
177
|
output << '"' + node['relname'] + '"'
|
179
178
|
output << deparse_item(node['alias']) if node['alias']
|
180
179
|
output.join(' ')
|
181
180
|
end
|
182
181
|
|
182
|
+
def deparse_raw_stmt(node)
|
183
|
+
deparse_item(node[STMT_FIELD])
|
184
|
+
end
|
185
|
+
|
183
186
|
def deparse_renamestmt(node)
|
184
187
|
output = []
|
185
188
|
|
@@ -13,7 +13,9 @@ class PgQuery
|
|
13
13
|
loop do
|
14
14
|
statement = statements.shift
|
15
15
|
if statement
|
16
|
-
if statement[
|
16
|
+
if statement[RAW_STMT]
|
17
|
+
statements << statement[RAW_STMT][STMT_FIELD]
|
18
|
+
elsif statement[SELECT_STMT]
|
17
19
|
case statement[SELECT_STMT]['op']
|
18
20
|
when 0
|
19
21
|
if statement[SELECT_STMT][FROM_CLAUSE_FIELD]
|
data/lib/pg_query/fingerprint.rb
CHANGED
@@ -9,7 +9,7 @@ class PgQuery
|
|
9
9
|
|
10
10
|
private
|
11
11
|
|
12
|
-
FINGERPRINT_VERSION =
|
12
|
+
FINGERPRINT_VERSION = 2
|
13
13
|
|
14
14
|
class FingerprintSubHash
|
15
15
|
attr_reader :parts
|
@@ -76,6 +76,10 @@ class PgQuery
|
|
76
76
|
next if [DECLARE_CURSOR_STMT, FETCH_STMT, CLOSE_PORTAL_STMT].include?(node_name)
|
77
77
|
when 'relname'
|
78
78
|
next if node_name == RANGE_VAR && fields[RELPERSISTENCE_FIELD] == 't'
|
79
|
+
when 'stmt_len'
|
80
|
+
next if node_name == RAW_STMT
|
81
|
+
when 'stmt_location'
|
82
|
+
next if node_name == RAW_STMT
|
79
83
|
end
|
80
84
|
|
81
85
|
fingerprint_value(val, hash, node_name, field_name, true)
|
@@ -1,7 +1,9 @@
|
|
1
1
|
class PgQuery
|
2
2
|
# Legacy parsetree from 0.7 and earlier versions - migrate to "tree" format if you can
|
3
3
|
def parsetree # rubocop:disable Metrics/CyclomaticComplexity
|
4
|
-
@parsetree ||= transform_nodes!(@tree) do |
|
4
|
+
@parsetree ||= transform_nodes!(@tree) do |raw_node|
|
5
|
+
node = raw_node.keys[0] == RAW_STMT ? raw_node.delete(RAW_STMT)[STMT_FIELD] : raw_node
|
6
|
+
|
5
7
|
key = node.keys[0]
|
6
8
|
new_key = LEGACY_NODE_NAMES[key] || key.upcase
|
7
9
|
|
@@ -9,34 +11,38 @@ class PgQuery
|
|
9
11
|
when A_CONST
|
10
12
|
transform_parsetree_a_const(node)
|
11
13
|
when A_EXPR
|
12
|
-
transform_string_list(node[A_EXPR]['name'])
|
14
|
+
node[A_EXPR]['name'] = transform_string_list(node[A_EXPR]['name'])
|
13
15
|
node[key].delete('kind')
|
14
16
|
when COLUMN_REF
|
15
|
-
transform_string_list(node[COLUMN_REF]['fields'])
|
17
|
+
node[COLUMN_REF]['fields'] = transform_string_list(node[COLUMN_REF]['fields'])
|
16
18
|
when CREATE_FUNCTION_STMT
|
17
|
-
transform_string_list(node[CREATE_FUNCTION_STMT]['funcname'])
|
19
|
+
node[CREATE_FUNCTION_STMT]['funcname'] = transform_string_list(node[CREATE_FUNCTION_STMT]['funcname'])
|
18
20
|
when CREATE_TRIG_STMT
|
19
|
-
transform_string_list(node[CREATE_TRIG_STMT]['funcname'])
|
21
|
+
node[CREATE_TRIG_STMT]['funcname'] = transform_string_list(node[CREATE_TRIG_STMT]['funcname'])
|
20
22
|
when CONSTRAINT
|
21
23
|
node[CONSTRAINT]['contype'] = LEGACY_CONSTRAINT_TYPES[node[CONSTRAINT]['contype']]
|
22
|
-
transform_string_list(node[CONSTRAINT]['keys'])
|
24
|
+
node[CONSTRAINT]['keys'] = transform_string_list(node[CONSTRAINT]['keys'])
|
23
25
|
when COPY_STMT
|
24
|
-
transform_string_list(node[COPY_STMT]['attlist'])
|
26
|
+
node[COPY_STMT]['attlist'] = transform_string_list(node[COPY_STMT]['attlist'])
|
25
27
|
when DEF_ELEM
|
26
28
|
node[DEF_ELEM]['arg'] = node[DEF_ELEM]['arg'][INTEGER]['ival'] if node[DEF_ELEM]['arg'].is_a?(Hash) && node[DEF_ELEM]['arg'].keys[0] == INTEGER
|
27
29
|
node[DEF_ELEM]['arg'] = node[DEF_ELEM]['arg'][STRING]['str'] if node[DEF_ELEM]['arg'].is_a?(Hash) && node[DEF_ELEM]['arg'].keys[0] == STRING
|
28
|
-
transform_string_list(node[DEF_ELEM]['arg']) if node[DEF_ELEM]['arg'].is_a?(Array)
|
30
|
+
node[DEF_ELEM]['arg'] = transform_string_list(node[DEF_ELEM]['arg']) if node[DEF_ELEM]['arg'].is_a?(Array)
|
29
31
|
when DROP_STMT
|
30
|
-
node[DROP_STMT]['objects'].
|
32
|
+
node[DROP_STMT]['objects'].each_with_index do |obj, idx|
|
33
|
+
node[DROP_STMT]['objects'][idx] = transform_string_list(obj)
|
34
|
+
end
|
31
35
|
when FUNC_CALL
|
32
|
-
transform_string_list(node[FUNC_CALL]['funcname'])
|
36
|
+
node[FUNC_CALL]['funcname'] = transform_string_list(node[FUNC_CALL]['funcname'])
|
33
37
|
when GRANT_ROLE_STMT
|
34
|
-
transform_string_list(node[GRANT_ROLE_STMT]['grantee_roles'])
|
38
|
+
node[GRANT_ROLE_STMT]['grantee_roles'] = transform_string_list(node[GRANT_ROLE_STMT]['grantee_roles'])
|
39
|
+
when RANGE_VAR
|
40
|
+
node[RANGE_VAR]['inhOpt'] = node[RANGE_VAR].delete('inh') ? 2 : 0
|
35
41
|
when TYPE_NAME
|
36
|
-
transform_string_list(node[TYPE_NAME]['names'])
|
42
|
+
node[TYPE_NAME]['names'] = transform_string_list(node[TYPE_NAME]['names'])
|
37
43
|
end
|
38
44
|
|
39
|
-
|
45
|
+
raw_node[new_key] = node.delete(key)
|
40
46
|
end
|
41
47
|
end
|
42
48
|
|
@@ -66,18 +72,7 @@ class PgQuery
|
|
66
72
|
}.freeze
|
67
73
|
|
68
74
|
LEGACY_CONSTRAINT_TYPES = {
|
69
|
-
|
70
|
-
# CONSTR_TYPE_NOTNULL = 1
|
71
|
-
# CONSTR_TYPE_DEFAULT = 2
|
72
|
-
# CONSTR_TYPE_CHECK = 3
|
73
|
-
CONSTR_TYPE_PRIMARY => 'PRIMARY_KEY',
|
74
|
-
# CONSTR_TYPE_UNIQUE = 5
|
75
|
-
# CONSTR_TYPE_EXCLUSION = 6
|
76
|
-
# CONSTR_TYPE_FOREIGN = 7
|
77
|
-
# CONSTR_TYPE_ATTR_DEFERRABLE = 8 # attributes for previous constraint node
|
78
|
-
# CONSTR_TYPE_ATTR_NOT_DEFERRABLE = 9
|
79
|
-
# CONSTR_TYPE_ATTR_DEFERRED = 10
|
80
|
-
# CONSTR_TYPE_ATTR_IMMEDIATE = 11
|
75
|
+
CONSTR_TYPE_PRIMARY => 'PRIMARY_KEY'
|
81
76
|
}.freeze
|
82
77
|
|
83
78
|
def transform_parsetree_a_const(node)
|
@@ -105,6 +100,10 @@ class PgQuery
|
|
105
100
|
def transform_string_list(list)
|
106
101
|
return if list.nil?
|
107
102
|
|
108
|
-
list.
|
103
|
+
if list.is_a?(Array)
|
104
|
+
list.map { |node| node.keys[0] == STRING ? node[STRING]['str'] : node }
|
105
|
+
else
|
106
|
+
[list.keys[0] == STRING ? list[STRING]['str'] : list]
|
107
|
+
end
|
109
108
|
end
|
110
109
|
end
|
data/lib/pg_query/node_types.rb
CHANGED
@@ -60,6 +60,7 @@ class PgQuery
|
|
60
60
|
RANGE_FUNCTION = 'RangeFunction'.freeze
|
61
61
|
RANGE_SUBSELECT = 'RangeSubselect'.freeze
|
62
62
|
RANGE_VAR = 'RangeVar'.freeze
|
63
|
+
RAW_STMT = 'RawStmt'.freeze
|
63
64
|
REFRESH_MAT_VIEW_STMT = 'RefreshMatViewStmt'.freeze
|
64
65
|
RENAME_STMT = 'RenameStmt'.freeze
|
65
66
|
RES_TARGET = 'ResTarget'.freeze
|
@@ -89,6 +90,7 @@ class PgQuery
|
|
89
90
|
FROM_CLAUSE_FIELD = 'fromClause'.freeze
|
90
91
|
RELPERSISTENCE_FIELD = 'relpersistence'.freeze
|
91
92
|
REXPR_FIELD = 'rexpr'.freeze
|
93
|
+
STMT_FIELD = 'stmt'.freeze
|
92
94
|
TARGET_LIST_FIELD = 'targetList'.freeze
|
93
95
|
VALUES_LISTS_FIELD = 'valuesLists'.freeze
|
94
96
|
|
@@ -97,22 +99,65 @@ class PgQuery
|
|
97
99
|
CONSTR_TYPE_NULL = 0 # not standard SQL, but a lot of people expect it
|
98
100
|
CONSTR_TYPE_NOTNULL = 1
|
99
101
|
CONSTR_TYPE_DEFAULT = 2
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
102
|
+
CONSTR_TYPE_IDENTITY = 3
|
103
|
+
CONSTR_TYPE_CHECK = 4
|
104
|
+
CONSTR_TYPE_PRIMARY = 5
|
105
|
+
CONSTR_TYPE_UNIQUE = 6
|
106
|
+
CONSTR_TYPE_EXCLUSION = 7
|
107
|
+
CONSTR_TYPE_FOREIGN = 8
|
108
|
+
CONSTR_TYPE_ATTR_DEFERRABLE = 9 # attributes for previous constraint node
|
109
|
+
CONSTR_TYPE_ATTR_NOT_DEFERRABLE = 10
|
110
|
+
CONSTR_TYPE_ATTR_DEFERRED = 11
|
111
|
+
CONSTR_TYPE_ATTR_IMMEDIATE = 12
|
109
112
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
OBJECT_TYPE_ACCESS_METHOD = 0
|
114
|
+
OBJECT_TYPE_AGGREGATE = 1
|
115
|
+
OBJECT_TYPE_AMOP = 2
|
116
|
+
OBJECT_TYPE_AMPROC = 3
|
117
|
+
OBJECT_TYPE_ATTRIBUTE = 4
|
118
|
+
OBJECT_TYPE_CAST = 5
|
119
|
+
OBJECT_TYPE_COLUMN = 6
|
120
|
+
OBJECT_TYPE_COLLATION = 7
|
121
|
+
OBJECT_TYPE_CONVERSION = 8
|
122
|
+
OBJECT_TYPE_DATABASE = 9
|
123
|
+
OBJECT_TYPE_DEFAULT = 10
|
124
|
+
OBJECT_TYPE_DEFACL = 11
|
125
|
+
OBJECT_TYPE_DOMAIN = 12
|
126
|
+
OBJECT_TYPE_DOMCONSTRAINT = 13
|
127
|
+
OBJECT_TYPE_EVENT_TRIGGER = 14
|
128
|
+
OBJECT_TYPE_EXTENSION = 15
|
129
|
+
OBJECT_TYPE_FDW = 16
|
130
|
+
OBJECT_TYPE_FOREIGN_SERVER = 17
|
131
|
+
OBJECT_TYPE_FOREIGN_TABLE = 18
|
132
|
+
OBJECT_TYPE_FUNCTION = 19
|
133
|
+
OBJECT_TYPE_INDEX = 20
|
134
|
+
OBJECT_TYPE_LANGUAGE = 21
|
135
|
+
OBJECT_TYPE_LARGEOBJECT = 22
|
136
|
+
OBJECT_TYPE_MATVIEW = 23
|
137
|
+
OBJECT_TYPE_OPCLASS = 24
|
138
|
+
OBJECT_TYPE_OPERATOR = 25
|
139
|
+
OBJECT_TYPE_OPFAMILY = 26
|
140
|
+
OBJECT_TYPE_POLICY = 27
|
141
|
+
OBJECT_TYPE_PUBLICATION = 28
|
142
|
+
OBJECT_TYPE_PUBLICATION_REL = 29
|
143
|
+
OBJECT_TYPE_ROLE = 30
|
144
|
+
OBJECT_TYPE_RULE = 31
|
145
|
+
OBJECT_TYPE_SCHEMA = 32
|
146
|
+
OBJECT_TYPE_SEQUENCE = 33
|
147
|
+
OBJECT_TYPE_SUBSCRIPTION = 34
|
148
|
+
OBJECT_TYPE_STATISTIC_EXT = 35
|
149
|
+
OBJECT_TYPE_TABCONSTRAINT = 36
|
150
|
+
OBJECT_TYPE_TABLE = 37
|
151
|
+
OBJECT_TYPE_TABLESPACE = 38
|
152
|
+
OBJECT_TYPE_TRANSFORM = 39
|
153
|
+
OBJECT_TYPE_TRIGGER = 40
|
154
|
+
OBJECT_TYPE_TSCONFIGURATION = 41
|
155
|
+
OBJECT_TYPE_TSDICTIONARY = 42
|
156
|
+
OBJECT_TYPE_TSPARSER = 43
|
157
|
+
OBJECT_TYPE_TSTEMPLATE = 44
|
158
|
+
OBJECT_TYPE_TYPE = 45
|
159
|
+
OBJECT_TYPE_USER_MAPPING = 46
|
160
|
+
OBJECT_TYPE_VIEW = 47
|
116
161
|
|
117
162
|
BOOL_EXPR_AND = 0
|
118
163
|
BOOL_EXPR_OR = 1
|
@@ -129,17 +174,18 @@ class PgQuery
|
|
129
174
|
AEXPR_OP_ANY = 1 # scalar op ANY (array)
|
130
175
|
AEXPR_OP_ALL = 2 # scalar op ALL (array)
|
131
176
|
AEXPR_DISTINCT = 3 # IS DISTINCT FROM - name must be "="
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
177
|
+
AEXPR_NOT_DISTINCT = 4 # IS NOT DISTINCT FROM - name must be "="
|
178
|
+
AEXPR_NULLIF = 5 # NULLIF - name must be "="
|
179
|
+
AEXPR_OF = 6 # IS [NOT] OF - name must be "=" or "<>"
|
180
|
+
AEXPR_IN = 7 # [NOT] IN - name must be "=" or "<>"
|
181
|
+
AEXPR_LIKE = 8 # [NOT] LIKE - name must be "~~" or "!~~"
|
182
|
+
AEXPR_ILIKE = 9 # [NOT] ILIKE - name must be "~~*" or "!~~*"
|
183
|
+
AEXPR_SIMILAR = 10 # [NOT] SIMILAR - name must be "~" or "!~"
|
184
|
+
AEXPR_BETWEEN = 11 # name must be "BETWEEN"
|
185
|
+
AEXPR_NOT_BETWEEN = 12 # name must be "NOT BETWEEN"
|
186
|
+
AEXPR_BETWEEN_SYM = 13 # name must be "BETWEEN SYMMETRIC"
|
187
|
+
AEXPR_NOT_BETWEEN_SYM = 14 # name must be "NOT BETWEEN SYMMETRIC"
|
188
|
+
AEXPR_PAREN = 15 # nameless dummy node for parentheses
|
143
189
|
|
144
190
|
TRANS_STMT_BEGIN = 0
|
145
191
|
TRANS_STMT_START = 1 # semantically identical to BEGIN
|
@@ -228,4 +274,9 @@ class PgQuery
|
|
228
274
|
AT_ForceRowSecurity = 58 # FORCE ROW SECURITY
|
229
275
|
AT_NoForceRowSecurity = 59 # NO FORCE ROW SECURITY
|
230
276
|
AT_GenericOptions = 60 # OPTIONS (...)
|
277
|
+
AT_AttachPartition = 61 # ATTACH PARTITION
|
278
|
+
AT_DetachPartition = 62 # DETACH PARTITION
|
279
|
+
AT_AddIdentity = 63 # ADD IDENTITY
|
280
|
+
AT_SetIdentity = 64 # SET identity column options
|
281
|
+
AT_DropIdentity = 65 # DROP IDENTITY
|
231
282
|
end
|
data/lib/pg_query/parse.rb
CHANGED
@@ -78,6 +78,8 @@ class PgQuery
|
|
78
78
|
statement = statements.shift
|
79
79
|
if statement
|
80
80
|
case statement.keys[0]
|
81
|
+
when RAW_STMT
|
82
|
+
statements << statement[RAW_STMT][STMT_FIELD]
|
81
83
|
# The following statement types do not modify tables and are added to from_clause_items
|
82
84
|
# (and subsequently @tables)
|
83
85
|
when SELECT_STMT
|
@@ -127,7 +129,13 @@ class PgQuery
|
|
127
129
|
when REFRESH_MAT_VIEW_STMT
|
128
130
|
from_clause_items << { item: statement[REFRESH_MAT_VIEW_STMT]['relation'], type: :ddl }
|
129
131
|
when DROP_STMT
|
130
|
-
objects = statement[DROP_STMT]['objects'].map
|
132
|
+
objects = statement[DROP_STMT]['objects'].map do |obj|
|
133
|
+
if obj.is_a?(Array)
|
134
|
+
obj.map { |obj2| obj2['String'] && obj2['String']['str'] }
|
135
|
+
else
|
136
|
+
obj['String'] && obj['String']['str']
|
137
|
+
end
|
138
|
+
end
|
131
139
|
case statement[DROP_STMT]['removeType']
|
132
140
|
when OBJECT_TYPE_TABLE
|
133
141
|
@tables += objects.map { |r| { table: r.join('.'), type: :ddl } }
|
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: 1.0.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-10-
|
11
|
+
date: 2017-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|