gitlab-pg_query 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +321 -0
- data/LICENSE +28 -0
- data/README.md +180 -0
- data/Rakefile +23 -0
- data/ext/pg_query/extconf.rb +46 -0
- data/ext/pg_query/pg_query_ruby.c +129 -0
- data/ext/pg_query/pg_query_ruby.h +10 -0
- data/ext/pg_query/pg_query_ruby.sym +1 -0
- data/lib/pg_query.rb +16 -0
- data/lib/pg_query/deep_dup.rb +16 -0
- data/lib/pg_query/deparse.rb +1588 -0
- data/lib/pg_query/deparse/alter_table.rb +42 -0
- data/lib/pg_query/deparse/interval.rb +105 -0
- data/lib/pg_query/deparse/keywords.rb +159 -0
- data/lib/pg_query/deparse/rename.rb +41 -0
- data/lib/pg_query/filter_columns.rb +107 -0
- data/lib/pg_query/fingerprint.rb +115 -0
- data/lib/pg_query/legacy_parsetree.rb +109 -0
- data/lib/pg_query/node_types.rb +296 -0
- data/lib/pg_query/param_refs.rb +45 -0
- data/lib/pg_query/parse.rb +247 -0
- data/lib/pg_query/parse_error.rb +9 -0
- data/lib/pg_query/treewalker.rb +53 -0
- data/lib/pg_query/truncate.rb +60 -0
- data/lib/pg_query/version.rb +3 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 63b274aaefc1eec6e7ad15ad500eefa3b9a164c9cee968a7d2934e195fc6dfd0
|
4
|
+
data.tar.gz: '01179c42bbfd0f7895fd23540e270585f92157fb8bf22849fa48bf40c81f1c44'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 98940ca0598bd2f7ebc1b1e33bfbb9d84a0bdb6aeb26ed69d15f1d365f9e2b8ab710162a621998e24156c200cf59a1043c5ee4098fdfaca572f9ac64fa82f886
|
7
|
+
data.tar.gz: bc2a7193cd0021e56abba21e6e78eb209852cd9aa0ebff3971c26e15d4cbfdcd78dce44333580a03b39a9aa3e56034af4a3e8233131f05e3a5b43b17a2296fa9
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,321 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 1.2.0 2019-11-10
|
4
|
+
|
5
|
+
* Reduce escaped keywords to Postgres-specific keywords, and ignore unreserved keywords
|
6
|
+
* This matches the behaviour of Postgres' quote_identifier function, and avoids problems
|
7
|
+
when doing text comparisons with output involving that function
|
8
|
+
* Note that this will lead to different output than in earlier pg_query versions,
|
9
|
+
in some cases
|
10
|
+
|
11
|
+
## 1.1.1 2019-11-10
|
12
|
+
|
13
|
+
* Deparsing improvements by [@emin100](https://github.com/emin100)
|
14
|
+
* Deparse ILIKE, COLLATE and DISCARD (#133)
|
15
|
+
* CREATE CAST (#136)
|
16
|
+
* CREATE SCHEMA (#136)
|
17
|
+
* UNION, UNION ALL and EXCEPT in SELECT queries (#136)
|
18
|
+
* CREATE DOMAIN (#145)
|
19
|
+
* Subquery indirection (#157)
|
20
|
+
* Fix Type Cast Parentheses Problem (#152)
|
21
|
+
* SELECT INTO (#151)
|
22
|
+
* SET DEFAULT in INSERT INTO (#154)
|
23
|
+
* REVOKE (#155)
|
24
|
+
* PREPARE and EXECUTE (#148)
|
25
|
+
* INSERT INTO ... RETURNING (#153)
|
26
|
+
* Fix Alter .. RENAME SQL (#146)
|
27
|
+
* Deparsing improvements by [@herwinw](https://github.com/herwinw)
|
28
|
+
* Fix subquery in COPY in deparse (#112)
|
29
|
+
* Function call indirection (#116)
|
30
|
+
* Function without parameters (#117)
|
31
|
+
* CREATE AGGREGATE
|
32
|
+
* CREATE OPERATOR
|
33
|
+
* CREATE TYPE
|
34
|
+
* GRANT statements
|
35
|
+
* DROP SCHEMA
|
36
|
+
* Deparsing improvements by [@akiellor](https://github.com/akiellor)
|
37
|
+
* Named window functions (#150)
|
38
|
+
* Deparsing improvements by [@himanshu](https://github.com/himanshu)
|
39
|
+
* Arguments in custom types (#143)
|
40
|
+
* Use "double precision" instead of "double" type name (#139)
|
41
|
+
* Use explicit -z flag to support OpenBSD tar (#134) [@sirn](https://github.com/sirn)
|
42
|
+
* Add Ruby 2.6 to Travis tests
|
43
|
+
* Escape identifiers in more cases, if necessary
|
44
|
+
|
45
|
+
|
46
|
+
## 1.1.0 2018-10-04
|
47
|
+
|
48
|
+
* Deparsing improvements by [@herwinw](https://github.com/herwinw)
|
49
|
+
* Add NULLS FIRST/LAST to ORDER BY [#95](https://github.com/lfittl/pg_query/pull/95)
|
50
|
+
* VACUUM [#97](https://github.com/lfittl/pg_query/pull/97)
|
51
|
+
* UPDATE with multiple columns [#99](https://github.com/lfittl/pg_query/pull/99)
|
52
|
+
* DISTINCT ON [#101](https://github.com/lfittl/pg_query/pull/101)
|
53
|
+
* CREATE TABLE AS [#102](https://github.com/lfittl/pg_query/pull/102)
|
54
|
+
* SQL value functions [#103](https://github.com/lfittl/pg_query/pull/103)
|
55
|
+
* LOCK [#105](https://github.com/lfittl/pg_query/pull/105)
|
56
|
+
* EXPLAIN [#107](https://github.com/lfittl/pg_query/pull/107)
|
57
|
+
* COPY [#108](https://github.com/lfittl/pg_query/pull/108)
|
58
|
+
* DO [#109](https://github.com/lfittl/pg_query/pull/109)
|
59
|
+
* Ignore pg_query.so in git checkout [#110](https://github.com/lfittl/pg_query/pull/110) [@herwinw](https://github.com/herwinw)
|
60
|
+
* Prefer __dir__ over File.dirname(__FILE__) [#110](https://github.com/lfittl/pg_query/pull/104) [@herwinw](https://github.com/herwinw)
|
61
|
+
|
62
|
+
|
63
|
+
## 1.0.2 2018-04-11
|
64
|
+
|
65
|
+
* Deparsing improvements
|
66
|
+
* SELECT DISTINCT clause [#77](https://github.com/lfittl/pg_query/pull/77) [@Papierkorb](https://github.com/Papierkorb)
|
67
|
+
* "CASE expr WHEN ... END" clause [#78](https://github.com/lfittl/pg_query/pull/78) [@Papierkorb](https://github.com/Papierkorb)
|
68
|
+
* LEFT/RIGHT/FULL/NATURAL JOIN [#79](https://github.com/lfittl/pg_query/pull/79) [@Papierkorb](https://github.com/Papierkorb)
|
69
|
+
* SELECT that includes schema name [#80](https://github.com/lfittl/pg_query/pull/80) [@jcsjcs](https://github.com/jcsjcs)
|
70
|
+
|
71
|
+
|
72
|
+
## 1.0.1 2018-02-02
|
73
|
+
|
74
|
+
* Parse CTEs and nested selects in INSERT/UPDATE [#76](https://github.com/lfittl/pg_query/pull/76) [@jcoleman](https://github.com/jcoleman)
|
75
|
+
* Drop explicit json dependency [#74](https://github.com/lfittl/pg_query/pull/74) [@yuki24](https://github.com/yuki24)
|
76
|
+
|
77
|
+
|
78
|
+
## 1.0.0 2017-10-31
|
79
|
+
|
80
|
+
* IMPORTANT: Major version bump to indicate backwards incompatible parse tree change!
|
81
|
+
* Update to Postgres 10 parser and fingerprint version 2
|
82
|
+
- This is a backwards-incompatible change in parser output format, although it should
|
83
|
+
be relatively easy to update most programs. This can't be avoided since Postgres
|
84
|
+
does not guarantee parse trees stay the same across versions
|
85
|
+
|
86
|
+
|
87
|
+
## 0.13.5 2017-10-26
|
88
|
+
|
89
|
+
* Update to libpg_query 9.5-1.7.1
|
90
|
+
- Allow "$1 FROM $2" to be parsed (new with pg_stat_statements in Postgres 10)
|
91
|
+
|
92
|
+
|
93
|
+
## 0.13.4 2017-10-20
|
94
|
+
|
95
|
+
* Update to libpg_query 9.5-1.7.0
|
96
|
+
- Fixes compilation old gcc before 4.6.0 [#73](https://github.com/lfittl/pg_query/issues/73)
|
97
|
+
|
98
|
+
|
99
|
+
## 0.13.3 2017-09-04
|
100
|
+
|
101
|
+
* Fix table detection for SELECTs that have sub-SELECTs without FROM clause [#69](https://github.com/lfittl/pg_query/issues/69)
|
102
|
+
|
103
|
+
|
104
|
+
## 0.13.2 2017-08-10
|
105
|
+
|
106
|
+
* Support table detection in sub-SELECTs in JOINs [#68](https://github.com/lfittl/pg_query/pull/65) [@seanmdick](https://github.com/seanmdick)
|
107
|
+
* Legacy ".parsetree" helper: Fix "Between" and "In" operator does not have "AEXPR" [#66](https://github.com/lfittl/pg_query/issues/66)
|
108
|
+
* For new applications please use ".tree" method which uses the native structure
|
109
|
+
returned from libpg_query which resembles Postgres node names more closely
|
110
|
+
|
111
|
+
|
112
|
+
## 0.13.1 2017-08-03
|
113
|
+
|
114
|
+
* Fix regression in 0.13.1 that broke ".tables" logic for COPY statements that
|
115
|
+
don't have a target table (i.e. are reading out data vs copying in)
|
116
|
+
|
117
|
+
|
118
|
+
## 0.13.0 2017-07-30
|
119
|
+
|
120
|
+
* Introduce split between SELECT/DML/DDL for tables method [#65](https://github.com/lfittl/pg_query/pull/65) [@chrisfrommann](https://github.com/chrisfrommann)
|
121
|
+
* Backwards compatible, use the new select_tables/dml_tables/ddl_tables to
|
122
|
+
access the categorized table references
|
123
|
+
* Update libpg_query to 9.5-1.6.2
|
124
|
+
* Update to Fingerprinting Version 1.3
|
125
|
+
* Attributes to be ignored:
|
126
|
+
* RangeVar.relname (if node also has RangeVar.relpersistence = "t")
|
127
|
+
* Special cases: List nodes where parent field name is valuesLists
|
128
|
+
* Follow same logic described for fromClause/targetList/cols/rexpr
|
129
|
+
|
130
|
+
|
131
|
+
## 0.12.1 2017-07-29
|
132
|
+
|
133
|
+
* Update libpg_query to 9.5-1.6.1
|
134
|
+
* Update to Fingerprinting Version 1.2
|
135
|
+
* Ignore portalname in DeclareCursorStmt, FetchStmt and ClosePortalStmt
|
136
|
+
|
137
|
+
|
138
|
+
## 0.12.0 2017-07-29
|
139
|
+
|
140
|
+
* Update libpg_query to 9.5-1.6.0
|
141
|
+
* BREAKING CHANGE in PgQuery.normalize(..) output
|
142
|
+
* This matches the change in the upcoming Postgres 10, and makes it easier to
|
143
|
+
migrate applications to the new normalization format using $1..$N instead of ?
|
144
|
+
|
145
|
+
|
146
|
+
## 0.11.5 2017-07-09
|
147
|
+
|
148
|
+
* Deparse coldeflist [#64](https://github.com/lfittl/pg_query/pull/64) [@jcsjcs](https://github.com/jcsjcs)
|
149
|
+
* Use Integer class for checking integer instead of Fixnum [#62](https://github.com/lfittl/pg_query/pull/62) [@makimoto](https://github.com/makimoto)
|
150
|
+
|
151
|
+
|
152
|
+
## 0.11.4 2017-01-18
|
153
|
+
|
154
|
+
* Compatibility with Ruby 2.4 [#59](https://github.com/lfittl/pg_query/pull/59) [@merqlove](https://github.com/merqlove)
|
155
|
+
* Deparse varchar and numeric casts without arguments [#61](https://github.com/lfittl/pg_query/pull/61) [@jcsjcs](https://github.com/jcsjcs)
|
156
|
+
|
157
|
+
|
158
|
+
## 0.11.3 2016-12-06
|
159
|
+
|
160
|
+
* Update to newest libpg_query version (9.5-1.4.2)
|
161
|
+
* Cut off fingerprints at 100 nodes deep to avoid excessive runtimes/memory
|
162
|
+
* Fix warning on Linux due to missing asprintf include
|
163
|
+
* Improved deparsing [@jcsjcs](https://github.com/jcsjcs)
|
164
|
+
* Float [#54](https://github.com/lfittl/pg_query/pull/54)
|
165
|
+
* BETWEEN [#55](https://github.com/lfittl/pg_query/pull/55)
|
166
|
+
* NULLIF [#56](https://github.com/lfittl/pg_query/pull/56)
|
167
|
+
* SELECT NULL and BooleanTest [#57](https://github.com/lfittl/pg_query/pull/57)
|
168
|
+
* Fix build on BSD systems [#58](https://github.com/lfittl/pg_query/pull/58) [@myfreeweb](https://github.com/myfreeweb)
|
169
|
+
|
170
|
+
|
171
|
+
## 0.11.2 2016-06-27
|
172
|
+
|
173
|
+
* Update to newest libpg_query version (9.5-1.4.1)
|
174
|
+
* This release makes sure we work correctly in threaded environments
|
175
|
+
|
176
|
+
|
177
|
+
## 0.11.1 2016-06-26
|
178
|
+
|
179
|
+
* Updated fingerprinting logic to version 1.1
|
180
|
+
* Fixes an issue with UpdateStmt target lists being ignored
|
181
|
+
* Update to newest libpg_query version (9.5-1.4.0)
|
182
|
+
|
183
|
+
|
184
|
+
## 0.11.0 2016-06-22
|
185
|
+
|
186
|
+
* Improved table name analysis (#tables method)
|
187
|
+
* Don't include CTE names, make them accessible as #cte_names instead [#52](https://github.com/lfittl/pg_query/issues/52)
|
188
|
+
* Include table names in target list sub selects [#38](https://github.com/lfittl/pg_query/issues/38)
|
189
|
+
* Add support for ORDER/GROUP BY, HAVING, and booleans in WHERE [#53](https://github.com/lfittl/pg_query/pull/53) [@jcoleman](https://github.com/jcoleman)
|
190
|
+
* Fix parsing of DROP TYPE statements
|
191
|
+
|
192
|
+
|
193
|
+
## 0.10.0 2016-05-31
|
194
|
+
|
195
|
+
* Based on PostgreSQL 9.5.3
|
196
|
+
* Use LLVM extracted parser for significantly improved build times (via libpg_query)
|
197
|
+
* Deparsing Improvements
|
198
|
+
* SET statements [#48](https://github.com/lfittl/pg_query/pull/48) [@Winslett](https://github.com/Winslett)
|
199
|
+
* LIKE/NOT LIKE [#49](https://github.com/lfittl/pg_query/pull/49) [@Winslett](https://github.com/Winslett)
|
200
|
+
* CREATE FUNCTION improvements [#50](https://github.com/lfittl/pg_query/pull/50) [@Winslett](https://github.com/Winslett)
|
201
|
+
|
202
|
+
|
203
|
+
## 0.9.2 2016-05-03
|
204
|
+
|
205
|
+
* Fix issue with A_CONST string values in `.parsetree` compatibility layer (Fixes [#47](https://github.com/lfittl/pg_query/issues/47))
|
206
|
+
|
207
|
+
|
208
|
+
## 0.9.1 2016-04-20
|
209
|
+
|
210
|
+
* Add support for Ruby 1.9 (Fixes [#44](https://github.com/lfittl/pg_query/issues/44))
|
211
|
+
|
212
|
+
|
213
|
+
## 0.9.0 2016-04-17
|
214
|
+
|
215
|
+
* Based on PostgreSQL 9.5.2
|
216
|
+
* NOTE: Output format for the parse tree has changed (backwards incompatible!),
|
217
|
+
it is recommended you extensively test any direct reading/modification of
|
218
|
+
the tree data in your own code
|
219
|
+
* You can use the `.parsetree` translator method to ease the transition, note
|
220
|
+
however that there are still a few incompatible changes
|
221
|
+
* New `.fingerprint` method (backwards incompatible as well), see https://github.com/lfittl/libpg_query/wiki/Fingerprinting
|
222
|
+
* Removes PostgreSQL source and tarball after build process has finished, to reduce
|
223
|
+
diskspace requirements of the installed gem
|
224
|
+
|
225
|
+
|
226
|
+
## 0.8.0 2016-03-06
|
227
|
+
|
228
|
+
* Use fixed git version for libpg_query (PostgreSQL 9.4 based)
|
229
|
+
* NOTE: 0.8 will be the last series with the initial parse tree format, 0.9 will
|
230
|
+
introduce a newer, more stable, but backwards incompatible parse tree format
|
231
|
+
|
232
|
+
|
233
|
+
## 0.7.2 2015-12-20
|
234
|
+
|
235
|
+
* Deparsing
|
236
|
+
* Quote all column refs [#40](https://github.com/lfittl/pg_query/pull/40) [@avinoamr](https://github.com/avinoamr)
|
237
|
+
* Quote all range vars [#43](https://github.com/lfittl/pg_query/pull/43) [@avinoamr](https://github.com/avinoamr)
|
238
|
+
* Support for COUNT(DISTINCT ...) [#42](https://github.com/lfittl/pg_query/pull/42) [@avinoamr](https://github.com/avinoamr)
|
239
|
+
|
240
|
+
|
241
|
+
## 0.7.1 2015-11-17
|
242
|
+
|
243
|
+
* Abstracted parser access into libpg_query [#24](https://github.com/lfittl/pg_query/pull/35)
|
244
|
+
* libpg_query
|
245
|
+
* Use UTF-8 encoding for parsing [#4](https://github.com/lfittl/libpg_query/pull/4) [@zhm](https://github.com/zhm)
|
246
|
+
* Add type to A_CONST nodes[#5](https://github.com/lfittl/libpg_query/pull/5) [@zhm](https://github.com/zhm)
|
247
|
+
|
248
|
+
|
249
|
+
## 0.7.0 2015-10-17
|
250
|
+
|
251
|
+
* Restructure build process to use upstream tarballs [#35](https://github.com/lfittl/pg_query/pull/35)
|
252
|
+
* Avoid bison/flex dependency to make deployment easier [#31](https://github.com/lfittl/pg_query/issues/31)
|
253
|
+
* Solve issues with deployments to Heroku [#32](https://github.com/lfittl/pg_query/issues/32)
|
254
|
+
* Deparsing
|
255
|
+
* HAVING and FOR UPDATE [#36](https://github.com/lfittl/pg_query/pull/36) [@JackDanger](https://github.com/JackDanger)
|
256
|
+
|
257
|
+
|
258
|
+
## 0.6.4 2015-10-01
|
259
|
+
|
260
|
+
* Deparsing
|
261
|
+
* Constraints & Interval Types [#28](https://github.com/lfittl/pg_query/pull/28) [@JackDanger](https://github.com/JackDanger)
|
262
|
+
* Cross joins [#29](https://github.com/lfittl/pg_query/pull/29) [@mme](https://github.com/mme)
|
263
|
+
* ALTER TABLE [#30](https://github.com/lfittl/pg_query/pull/30) [@JackDanger](https://github.com/JackDanger)
|
264
|
+
* LIMIT and OFFSET [#33](https://github.com/lfittl/pg_query/pull/33) [@jcsjcs](https://github.com/jcsjcs)
|
265
|
+
|
266
|
+
|
267
|
+
## 0.6.3 2015-08-20
|
268
|
+
|
269
|
+
* Deparsing
|
270
|
+
* COUNT(*) [@JackDanger](https://github.com/JackDanger)
|
271
|
+
* Window clauses [Chris Martin](https://github.com/cmrtn)
|
272
|
+
* CREATE TABLE/VIEW/FUNCTION [@JackDanger](https://github.com/JackDanger)
|
273
|
+
* Return exact location for parser errors [@JackDanger](https://github.com/JackDanger)
|
274
|
+
|
275
|
+
|
276
|
+
## 0.6.2 2015-08-06
|
277
|
+
|
278
|
+
* Speed up gem install by not generating rdoc/ri for the Postgres source
|
279
|
+
|
280
|
+
|
281
|
+
## 0.6.1 2015-08-06
|
282
|
+
|
283
|
+
* Deparsing: Support WITH clauses in INSERT/UPDATE/DELETE [@JackDanger](https://github.com/JackDanger)
|
284
|
+
* Make sure gemspec includes all necessary files
|
285
|
+
|
286
|
+
|
287
|
+
## 0.6.0 2015-08-05
|
288
|
+
|
289
|
+
* Deparsing (experimental)
|
290
|
+
* Turns parse trees into SQL again
|
291
|
+
* New truncate method to smartly truncate based on less important query parts
|
292
|
+
* Thanks to [@mme](https://github.com/mme) & [@JackDanger](https://github.com/JackDanger) for their contributions
|
293
|
+
* Restructure extension C code
|
294
|
+
* Add table/filter columns support for CTEs
|
295
|
+
* Extract views as tables from CREATE/REFRESH VIEW
|
296
|
+
* Refactor code using generic treewalker
|
297
|
+
* fingerprint: Normalize IN lists
|
298
|
+
* param_refs: Fix length attribute in result
|
299
|
+
|
300
|
+
|
301
|
+
## 0.5.0 2015-03-26
|
302
|
+
|
303
|
+
* Query fingerprinting
|
304
|
+
* Filter columns (aka columns referenced in a query's WHERE clause)
|
305
|
+
* Parameter references: Returns all $1/$2/etc like references in the query with their location
|
306
|
+
* Remove dependency on active_support
|
307
|
+
|
308
|
+
|
309
|
+
## 0.4.1 2014-12-18
|
310
|
+
|
311
|
+
* Fix compilation of C extension
|
312
|
+
* Fix gemspec
|
313
|
+
|
314
|
+
|
315
|
+
## 0.4.0 2014-12-18
|
316
|
+
|
317
|
+
* Speed up build time by only building necessary objects
|
318
|
+
* PostgreSQL 9.4 parser
|
319
|
+
|
320
|
+
|
321
|
+
See git commit log for previous releases.
|
data/LICENSE
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Copyright (c) 2014, pganalyze Team <team@pganalyze.com>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
12
|
+
and/or other materials provided with the distribution.
|
13
|
+
|
14
|
+
* Neither the name of pganalyze nor the names of its contributors may be used
|
15
|
+
to endorse or promote products derived from this software without specific
|
16
|
+
prior written permission.
|
17
|
+
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
22
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
# pg_query [ ![](https://img.shields.io/gem/v/pg_query.svg)](https://rubygems.org/gems/pg_query) [ ![](https://img.shields.io/gem/dt/pg_query.svg)](https://rubygems.org/gems/pg_query) [ ![](https://travis-ci.org/lfittl/pg_query.svg?branch=master)](https://travis-ci.org/lfittl/pg_query)
|
2
|
+
|
3
|
+
This Ruby extension uses the actual PostgreSQL server source to parse SQL queries and return the internal PostgreSQL parsetree.
|
4
|
+
|
5
|
+
In addition the extension allows you to normalize queries (replacing constant values with ?) and parse these normalized queries into a parsetree again.
|
6
|
+
|
7
|
+
When you build this extension, it builds parts of the PostgreSQL server source (see [libpg_query](https://github.com/lfittl/libpg_query)), and then statically links it into this extension.
|
8
|
+
|
9
|
+
This is slightly crazy, but is the only reliable way of parsing all valid PostgreSQL queries.
|
10
|
+
|
11
|
+
You can find further examples and a longer rationale here: https://pganalyze.com/blog/parse-postgresql-queries-in-ruby.html
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
```
|
16
|
+
gem install pg_query
|
17
|
+
```
|
18
|
+
|
19
|
+
Due to compiling parts of PostgreSQL, installation might take a while on slower systems. Expect up to 5 minutes.
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### Parsing a query
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
PgQuery.parse("SELECT 1")
|
27
|
+
|
28
|
+
=> #<PgQuery:0x007fe92b27ea18
|
29
|
+
@tree=
|
30
|
+
[{"SelectStmt"=>
|
31
|
+
{"targetList"=>
|
32
|
+
[{"ResTarget"=>
|
33
|
+
{"val"=>{"A_Const"=>{"val"=>{"Integer"=>{"ival"=>1}}, "location"=>7}},
|
34
|
+
"location"=>7}}],
|
35
|
+
"op"=>0,
|
36
|
+
}}],
|
37
|
+
@query="SELECT 1",
|
38
|
+
@warnings=[]>
|
39
|
+
```
|
40
|
+
|
41
|
+
### Modifying a parsed query and turning it into SQL again
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
parsed_query = PgQuery.parse("SELECT * FROM users")
|
45
|
+
|
46
|
+
=> #<PgQuery:0x007ff3e956c8b0
|
47
|
+
@tree=
|
48
|
+
[{"SelectStmt"=>
|
49
|
+
{"targetList"=>
|
50
|
+
[{"ResTarget"=>
|
51
|
+
{"val"=>
|
52
|
+
{"ColumnRef"=> {"fields"=>[{"A_Star"=>{}}], "location"=>7}},
|
53
|
+
"location"=>7}
|
54
|
+
}],
|
55
|
+
"fromClause"=>
|
56
|
+
[{"RangeVar"=>
|
57
|
+
{"relname"=>"users",
|
58
|
+
"inhOpt"=>2,
|
59
|
+
"relpersistence"=>"p",
|
60
|
+
"location"=>14}}],
|
61
|
+
}}],
|
62
|
+
@query="SELECT * FROM users",
|
63
|
+
@warnings=[]>
|
64
|
+
|
65
|
+
# Modify the parse tree in some way
|
66
|
+
parsed_query.tree[0]['SelectStmt']['fromClause'][0]['RangeVar']['relname'] = 'other_users'
|
67
|
+
|
68
|
+
# Turn it into SQL again
|
69
|
+
parsed_query.deparse
|
70
|
+
=> "SELECT * FROM \"other_users\""
|
71
|
+
```
|
72
|
+
|
73
|
+
Note: The deparsing feature is experimental and does not support outputting all SQL yet.
|
74
|
+
|
75
|
+
### Parsing a normalized query
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
# Normalizing a query (like pg_stat_statements in Postgres 10+)
|
79
|
+
PgQuery.normalize("SELECT 1 FROM x WHERE y = 'foo'")
|
80
|
+
|
81
|
+
=> "SELECT $1 FROM x WHERE y = $2"
|
82
|
+
|
83
|
+
# Parsing a normalized query (pre-Postgres 10 style)
|
84
|
+
PgQuery.parse("SELECT ? FROM x WHERE y = ?")
|
85
|
+
|
86
|
+
=> #<PgQuery:0x007fb99455a438
|
87
|
+
@tree=
|
88
|
+
[{"SelectStmt"=>
|
89
|
+
{"targetList"=>
|
90
|
+
[{"ResTarget"=>
|
91
|
+
{"val"=>{"ParamRef"=>{"location"=>7}},
|
92
|
+
"location"=>7}}],
|
93
|
+
"fromClause"=>
|
94
|
+
[{"RangeVar"=>
|
95
|
+
{"relname"=>"x",
|
96
|
+
"inhOpt"=>2,
|
97
|
+
"relpersistence"=>"p",
|
98
|
+
"location"=>14}}],
|
99
|
+
"whereClause"=>
|
100
|
+
{"A_Expr"=>
|
101
|
+
{"kind"=>0,
|
102
|
+
"name"=>[{"String"=>{"str"=>"="}}],
|
103
|
+
"lexpr"=>{"ColumnRef"=>{"fields"=>[{"String"=>{"str"=>"y"}}], "location"=>22}},
|
104
|
+
"rexpr"=>{"ParamRef"=>{"location"=>26}},
|
105
|
+
"location"=>24}},
|
106
|
+
}}],
|
107
|
+
@query="SELECT ? FROM x WHERE y = ?",
|
108
|
+
@warnings=[]>
|
109
|
+
```
|
110
|
+
|
111
|
+
### Extracting tables from a query
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
PgQuery.parse("SELECT ? FROM x JOIN y USING (id) WHERE z = ?").tables
|
115
|
+
|
116
|
+
=> ["x", "y"]
|
117
|
+
```
|
118
|
+
|
119
|
+
### Extracting columns from a query
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
PgQuery.parse("SELECT ? FROM x WHERE x.y = ? AND z = ?").filter_columns
|
123
|
+
|
124
|
+
=> [["x", "y"], [nil, "z"]]
|
125
|
+
```
|
126
|
+
|
127
|
+
### Fingerprinting a query
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
PgQuery.parse("SELECT 1").fingerprint
|
131
|
+
|
132
|
+
=> "8e1acac181c6d28f4a923392cf1c4eda49ee4cd2"
|
133
|
+
|
134
|
+
PgQuery.parse("SELECT 2; --- comment").fingerprint
|
135
|
+
|
136
|
+
=> "8e1acac181c6d28f4a923392cf1c4eda49ee4cd2"
|
137
|
+
|
138
|
+
# Faster fingerprint method that is implemented inside the native library
|
139
|
+
PgQuery.fingerprint("SELECT ?")
|
140
|
+
|
141
|
+
=> "8e1acac181c6d28f4a923392cf1c4eda49ee4cd2"
|
142
|
+
```
|
143
|
+
|
144
|
+
## Differences from Upstream PostgreSQL
|
145
|
+
|
146
|
+
This gem is based on [libpg_query](https://github.com/lfittl/libpg_query),
|
147
|
+
which uses the latest stable PostgreSQL version, but with a patch applied
|
148
|
+
to support parsing normalized queries containing `?` replacement characters.
|
149
|
+
|
150
|
+
## Supported Ruby Versions
|
151
|
+
|
152
|
+
Currently tested and officially supported Ruby versions:
|
153
|
+
|
154
|
+
* MRI 2.1
|
155
|
+
* MRI 2.2
|
156
|
+
* MRI 2.3
|
157
|
+
* MRI 2.4
|
158
|
+
|
159
|
+
|
160
|
+
## Resources
|
161
|
+
|
162
|
+
See [libpg_query](https://github.com/lfittl/libpg_query/blob/10-latest/README.md#resources) for pg_query in other languages, as well as products/tools built on pg_query.
|
163
|
+
|
164
|
+
## Original Author
|
165
|
+
|
166
|
+
- [Lukas Fittl](mailto:lukas@fittl.com)
|
167
|
+
|
168
|
+
|
169
|
+
## Special Thanks to
|
170
|
+
|
171
|
+
- [Jack Danger Canty](https://github.com/JackDanger), for significantly improving deparsing
|
172
|
+
|
173
|
+
|
174
|
+
## License
|
175
|
+
|
176
|
+
Copyright (c) 2015, pganalyze Team <team@pganalyze.com><br>
|
177
|
+
pg_query is licensed under the 3-clause BSD license, see LICENSE file for details.
|
178
|
+
|
179
|
+
Query normalization code:<br>
|
180
|
+
Copyright (c) 2008-2015, PostgreSQL Global Development Group
|