pg_query_pg_ddm 0.3 → 0.4
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/README.md +8 -4
- data/ext/pg_query/extconf.rb +15 -5
- data/lib/pg_query/deparse.rb +31 -9
- data/lib/pg_query/node_types.rb +1 -0
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b5b6ecf3017b7a20ab2e560e092ac24860d3be847df753556c784fdb63106a4
|
4
|
+
data.tar.gz: 488e1d7c21031689b9db0b266ba24395d91fbddb0c65783728243d0231bbd82b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 900b3da4a2ce5066f4f851c7e6f0bb4f317f7d90ae44aeb2d4a16440c6afd5741c5e1e98ecaf6e6d389088533ccdb0be09045299905a4e3ee1d2bbc894c6b09a
|
7
|
+
data.tar.gz: 951806619168d1f76b3b3d8d0dc65e4c90a4e86f2f979b4a9657de185ea351abe8b81c3bf1eb7f7eab31744f8843a536589ab2076eae331961503449c68a58a5
|
data/README.md
CHANGED
@@ -151,11 +151,15 @@ to support parsing normalized queries containing `?` replacement characters.
|
|
151
151
|
|
152
152
|
Currently tested and officially supported Ruby versions:
|
153
153
|
|
154
|
-
*
|
155
|
-
*
|
156
|
-
*
|
157
|
-
*
|
154
|
+
* CRuby 2.5
|
155
|
+
* CRuby 2.6
|
156
|
+
* CRuby 2.7
|
157
|
+
* CRuby 3.0
|
158
158
|
|
159
|
+
Not supported:
|
160
|
+
|
161
|
+
* JRuby: `pg_query` relies on a C extension, which is discouraged / not properly supported for JRuby
|
162
|
+
* TruffleRuby: GraalVM [does not support sigjmp](https://www.graalvm.org/reference-manual/llvm/NativeExecution/), which is used by the Postgres error handling code (`pg_query` uses a copy of the Postgres parser & error handling code)
|
159
163
|
|
160
164
|
## Resources
|
161
165
|
|
data/ext/pg_query/extconf.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# rubocop:disable Style/GlobalVars
|
2
2
|
|
3
|
+
require 'digest'
|
3
4
|
require 'mkmf'
|
4
5
|
require 'open-uri'
|
5
6
|
|
@@ -10,21 +11,30 @@ libdir = File.join(workdir, 'libpg_query-' + LIB_PG_QUERY_TAG)
|
|
10
11
|
gemdir = File.join(__dir__, '../..')
|
11
12
|
libfile = libdir + '/libpg_query.a'
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
expected_sha256 = '1332761f31c198cb9825e6ccccda0b6a0e57daeb824870e8524df77f1592d149'
|
15
|
+
filename = "#{workdir}/libpg_query.tar.gz"
|
16
|
+
|
17
|
+
unless File.exist?(filename)
|
18
|
+
File.open(filename, 'wb') do |target_file|
|
19
|
+
URI.open('https://codeload.github.com/lfittl/libpg_query/tar.gz/' + LIB_PG_QUERY_TAG, 'rb') do |read_file|
|
16
20
|
target_file.write(read_file.read)
|
17
21
|
end
|
18
22
|
end
|
23
|
+
|
24
|
+
checksum = Digest::SHA256.hexdigest(File.read(filename))
|
25
|
+
|
26
|
+
if checksum != expected_sha256
|
27
|
+
raise "SHA256 of #{filename} does not match: got #{checksum}, expected #{expected_sha256}"
|
28
|
+
end
|
19
29
|
end
|
20
30
|
|
21
31
|
unless Dir.exist?(libdir)
|
22
|
-
system("tar -xzf #{
|
32
|
+
system("tar -xzf #{filename}") || raise('ERROR')
|
23
33
|
end
|
24
34
|
|
25
35
|
unless Dir.exist?(libfile)
|
26
36
|
# Build libpg_query (and parts of PostgreSQL)
|
27
|
-
system("cd
|
37
|
+
system(format("cd %s; %s build", libdir, ENV['MAKE'] || (RUBY_PLATFORM =~ /bsd/ ? 'gmake' : 'make')))
|
28
38
|
end
|
29
39
|
|
30
40
|
# Copy test files (this intentionally overwrites existing files!)
|
data/lib/pg_query/deparse.rb
CHANGED
@@ -314,7 +314,7 @@ class PgQuery
|
|
314
314
|
if node['indirection']
|
315
315
|
array_indirection = node['indirection'].select { |a| a.key?(A_INDICES) }
|
316
316
|
end
|
317
|
-
output << if node['arg'].key?(FUNC_CALL) || node['arg'].key?(A_EXPR) || (node['arg'].key?(SUB_LINK) && array_indirection.count.zero?)
|
317
|
+
output << if node['arg'].key?(FUNC_CALL) || node['arg'].key?(COLUMN_REF) || node['arg'].key?(A_EXPR) || (node['arg'].key?(SUB_LINK) && array_indirection.count.zero?)
|
318
318
|
"(#{arg})."
|
319
319
|
else
|
320
320
|
arg
|
@@ -417,9 +417,11 @@ class PgQuery
|
|
417
417
|
# COUNT(*)
|
418
418
|
args << '*' if node['agg_star']
|
419
419
|
|
420
|
-
name = (node['funcname'].map { |n| deparse_item(n, FUNC_CALL) }
|
421
|
-
if name == 'overlay'
|
422
|
-
|
420
|
+
name = (node['funcname'].map { |n| deparse_item(n, FUNC_CALL) }).join('.')
|
421
|
+
if name == 'pg_catalog.overlay'
|
422
|
+
# Note that this is a bit odd, but "OVERLAY" is a keyword on its own merit, and only accepts the
|
423
|
+
# keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlay)
|
424
|
+
output << format('OVERLAY(%s PLACING %s FROM %s FOR %s)', args[0], args[1], args[2], args[3])
|
423
425
|
else
|
424
426
|
distinct = node['agg_distinct'] ? 'DISTINCT ' : ''
|
425
427
|
output << format('%s(%s%s)', name, distinct, args.join(', '))
|
@@ -1223,7 +1225,7 @@ class PgQuery
|
|
1223
1225
|
output << deparse_item(node['selectStmt'])
|
1224
1226
|
|
1225
1227
|
if node['onConflictClause']
|
1226
|
-
output << deparse_insert_onconflict(node['onConflictClause'][
|
1228
|
+
output << deparse_insert_onconflict(node['onConflictClause'][ON_CONFLICT_CLAUSE])
|
1227
1229
|
end
|
1228
1230
|
|
1229
1231
|
if node['returningList']
|
@@ -1308,10 +1310,30 @@ class PgQuery
|
|
1308
1310
|
output.join(' ')
|
1309
1311
|
end
|
1310
1312
|
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1313
|
+
# Builds a properly-qualified reference to a built-in Postgres type.
|
1314
|
+
#
|
1315
|
+
# Inspired by SystemTypeName in Postgres' gram.y, but without node name
|
1316
|
+
# and locations, to simplify comparison.
|
1317
|
+
def make_system_type_name(name)
|
1318
|
+
{
|
1319
|
+
'names' => [
|
1320
|
+
{ 'String' => { 'str' => 'pg_catalog' } },
|
1321
|
+
{ 'String' => { 'str' => name } }
|
1322
|
+
],
|
1323
|
+
'typemod' => -1
|
1324
|
+
}
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
def make_string(str)
|
1328
|
+
{ 'String' => { 'str' => str } }
|
1329
|
+
end
|
1330
|
+
|
1331
|
+
def deparse_typecast(node)
|
1332
|
+
# Handle "bool" or "false" in the statement, which is represented as a typecast
|
1333
|
+
# (other boolean casts should be represented as a cast, i.e. don't need special handling)
|
1334
|
+
if node['arg'][A_CONST] && node['typeName'][TYPE_NAME].slice('names', 'typemod') == make_system_type_name('bool')
|
1335
|
+
return 'true' if node['arg'][A_CONST]['val'] == make_string('t')
|
1336
|
+
return 'false' if node['arg'][A_CONST]['val'] == make_string('f')
|
1315
1337
|
end
|
1316
1338
|
|
1317
1339
|
context = true if node['arg']['A_Expr']
|
data/lib/pg_query/node_types.rb
CHANGED
@@ -68,6 +68,7 @@ class PgQuery
|
|
68
68
|
NULL_TEST = 'NullTest'.freeze
|
69
69
|
OBJECT_WITH_ARGS = 'ObjectWithArgs'.freeze
|
70
70
|
OID_LIST = 'OidList'.freeze
|
71
|
+
ON_CONFLICT_CLAUSE = 'OnConflictClause'.freeze
|
71
72
|
PARAM_REF = 'ParamRef'.freeze
|
72
73
|
PREPARE_STMT = 'PrepareStmt'.freeze
|
73
74
|
RANGE_FUNCTION = 'RangeFunction'.freeze
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_query_pg_ddm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.4'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mehmet Emin KARAKAŞ
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -126,8 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
126
|
- !ruby/object:Gem::Version
|
127
127
|
version: '0'
|
128
128
|
requirements: []
|
129
|
-
|
130
|
-
rubygems_version: 2.7.6
|
129
|
+
rubygems_version: 3.1.2
|
131
130
|
signing_key:
|
132
131
|
specification_version: 4
|
133
132
|
summary: PostgreSQL query parsing and normalization library
|