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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9783bc0c3d779e2a2b262d2d9f28d78445e47f926766a83c8a6956c74fe2002a
4
- data.tar.gz: 568336bc9f418ab16023c636cc1bee2660a9a74b65659f801f97915d9da215dc
3
+ metadata.gz: 9b5b6ecf3017b7a20ab2e560e092ac24860d3be847df753556c784fdb63106a4
4
+ data.tar.gz: 488e1d7c21031689b9db0b266ba24395d91fbddb0c65783728243d0231bbd82b
5
5
  SHA512:
6
- metadata.gz: 515131344ad73fb9a0281534b78a5ed18388de64ec15162ac740b1d966f143530456e9058593339af46ee071413fe4b4d73e4bf22125099356d17b36bc402196
7
- data.tar.gz: ed62da64c5ae51ad2d58dd973a24e50bd6f54e4ebe89cea40858de6ac8338070734009ec9bad413e89abc4a0d493f3fded22759f04182f802730a2eda7c2921d
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
- * MRI 2.1
155
- * MRI 2.2
156
- * MRI 2.3
157
- * MRI 2.4
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
 
@@ -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
- unless File.exist?("#{workdir}/libpg_query.tar.gz")
14
- File.open("#{workdir}/libpg_query.tar.gz", 'wb') do |target_file|
15
- open('https://codeload.github.com/lfittl/libpg_query/tar.gz/' + LIB_PG_QUERY_TAG, 'rb') do |read_file|
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 #{workdir}/libpg_query.tar.gz") || raise('ERROR')
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 #{libdir}; #{ENV['MAKE'] || (RUBY_PLATFORM =~ /bsd/ ? 'gmake' : 'make')} build")
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!)
@@ -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) } - ['pg_catalog']).join('.')
421
- if name == 'overlay'
422
- output << format('%s(%s placing %s from %s for %s)', name, args[0], args[1], args[2], args[3])
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']['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
- def deparse_typecast(node) # rubocop:disable Metrics/CyclomaticComplexity
1312
- if deparse_item(node['typeName']) == 'boolean' || deparse_item(node['typeName']) == 'bool'
1313
- return 'true' if deparse_item(node['arg']) == "'t'" || deparse_item(node['arg']) == 'true'
1314
- return 'false' if deparse_item(node['arg']) == "'f'" || deparse_item(node['arg']) == 'false'
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']
@@ -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.3'
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: 2020-11-19 00:00:00.000000000 Z
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
- rubyforge_project:
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