gitlab-pg_query 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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.
@@ -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