pg_query 6.0.0 → 6.1.0

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/Rakefile +4 -4
  4. data/ext/pg_query/ext_symbols_freebsd_with_ruby_abi_version.sym +2 -0
  5. data/ext/pg_query/ext_symbols_openbsd.sym +1 -0
  6. data/ext/pg_query/ext_symbols_openbsd_with_ruby_abi_version.sym +2 -0
  7. data/ext/pg_query/ext_symbols_with_ruby_abi_version.sym +2 -0
  8. data/ext/pg_query/extconf.rb +20 -6
  9. data/ext/pg_query/include/pg_query.h +2 -2
  10. data/ext/pg_query/include/postgres/access/amapi.h +4 -0
  11. data/ext/pg_query/include/postgres/access/genam.h +9 -0
  12. data/ext/pg_query/include/postgres/access/slru.h +3 -6
  13. data/ext/pg_query/include/postgres/access/tableam.h +2 -1
  14. data/ext/pg_query/include/postgres/access/transam.h +43 -0
  15. data/ext/pg_query/include/postgres/c.h +1 -1
  16. data/ext/pg_query/include/postgres/catalog/objectaddress.h +4 -0
  17. data/ext/pg_query/include/postgres/commands/event_trigger.h +6 -0
  18. data/ext/pg_query/include/postgres/common/hashfn_unstable.h +6 -52
  19. data/ext/pg_query/include/postgres/datatype/timestamp.h +1 -1
  20. data/ext/pg_query/include/postgres/executor/execdesc.h +1 -1
  21. data/ext/pg_query/include/postgres/libpq/libpq-be.h +6 -3
  22. data/ext/pg_query/include/postgres/mb/pg_wchar.h +1 -0
  23. data/ext/pg_query/include/postgres/miscadmin.h +10 -2
  24. data/ext/pg_query/include/postgres/nodes/execnodes.h +3 -0
  25. data/ext/pg_query/include/postgres/nodes/pathnodes.h +4 -1
  26. data/ext/pg_query/include/postgres/nodes/pg_list.h +1 -1
  27. data/ext/pg_query/include/postgres/nodes/primnodes.h +9 -5
  28. data/ext/pg_query/include/postgres/parser/parse_coerce.h +3 -0
  29. data/ext/pg_query/include/postgres/pg_config.h +28 -20
  30. data/ext/pg_query/include/postgres/port/pg_iovec.h +2 -2
  31. data/ext/pg_query/include/postgres/port/win32_port.h +0 -2
  32. data/ext/pg_query/include/postgres/port.h +32 -1
  33. data/ext/pg_query/include/postgres/replication/reorderbuffer.h +9 -18
  34. data/ext/pg_query/include/postgres/replication/slot.h +5 -1
  35. data/ext/pg_query/include/postgres/storage/lockdefs.h +2 -0
  36. data/ext/pg_query/include/postgres/storage/proc.h +13 -16
  37. data/ext/pg_query/include/postgres/storage/smgr.h +5 -2
  38. data/ext/pg_query/include/postgres/utils/catcache.h +1 -0
  39. data/ext/pg_query/include/postgres/utils/pgstat_internal.h +19 -0
  40. data/ext/pg_query/include/postgres/utils/portal.h +1 -1
  41. data/ext/pg_query/include/postgres/utils/syscache.h +5 -0
  42. data/ext/pg_query/postgres_deparse.c +197 -156
  43. data/ext/pg_query/src_backend_parser_gram.c +1 -1
  44. data/ext/pg_query/src_common_wchar.c +47 -1
  45. data/ext/pg_query/src_port_snprintf.c +14 -17
  46. data/lib/pg_query/fingerprint.rb +3 -5
  47. data/lib/pg_query/param_refs.rb +1 -1
  48. data/lib/pg_query/parse.rb +5 -7
  49. data/lib/pg_query/parse_error.rb +1 -0
  50. data/lib/pg_query/pg_query_pb.rb +1 -22
  51. data/lib/pg_query/scan.rb +1 -0
  52. data/lib/pg_query/treewalker.rb +2 -6
  53. data/lib/pg_query/truncate.rb +17 -19
  54. data/lib/pg_query/version.rb +1 -1
  55. metadata +15 -80
  56. /data/ext/pg_query/{pg_query_ruby.sym → ext_symbols.sym} +0 -0
  57. /data/ext/pg_query/{pg_query_ruby_freebsd.sym → ext_symbols_freebsd.sym} +0 -0
@@ -34303,7 +34303,7 @@ yyreduce:
34303
34303
  n->def = (Node *) c;
34304
34304
  c->contype = CONSTR_FOREIGN; /* others not supported, yet */
34305
34305
  c->conname = (yyvsp[(3) - (4)].str);
34306
- processCASbits((yyvsp[(4) - (4)].ival), (yylsp[(4) - (4)]), "ALTER CONSTRAINT statement",
34306
+ processCASbits((yyvsp[(4) - (4)].ival), (yylsp[(4) - (4)]), "FOREIGN KEY",
34307
34307
  &c->deferrable,
34308
34308
  &c->initdeferred,
34309
34309
  NULL, NULL, yyscanner);
@@ -98,6 +98,25 @@
98
98
  #include "utils/ascii.h"
99
99
 
100
100
 
101
+ /*
102
+ * In today's multibyte encodings other than UTF8, this two-byte sequence
103
+ * ensures pg_encoding_mblen() == 2 && pg_encoding_verifymbstr() == 0.
104
+ *
105
+ * For historical reasons, several verifychar implementations opt to reject
106
+ * this pair specifically. Byte pair range constraints, in encoding
107
+ * originator documentation, always excluded this pair. No core conversion
108
+ * could translate it. However, longstanding verifychar implementations
109
+ * accepted any non-NUL byte. big5_to_euc_tw and big5_to_mic even translate
110
+ * pairs not valid per encoding originator documentation. To avoid tightening
111
+ * core or non-core conversions in a security patch, we sought this one pair.
112
+ *
113
+ * PQescapeString() historically used spaces for BYTE1; many other values
114
+ * could suffice for BYTE1.
115
+ */
116
+ #define NONUTF8_INVALID_BYTE0 (0x8d)
117
+ #define NONUTF8_INVALID_BYTE1 (' ')
118
+
119
+
101
120
  /*
102
121
  * Operations on multi-byte encodings are driven by a table of helper
103
122
  * functions.
@@ -1547,6 +1566,11 @@ pg_big5_verifychar(const unsigned char *s, int len)
1547
1566
  if (len < l)
1548
1567
  return -1;
1549
1568
 
1569
+ if (l == 2 &&
1570
+ s[0] == NONUTF8_INVALID_BYTE0 &&
1571
+ s[1] == NONUTF8_INVALID_BYTE1)
1572
+ return -1;
1573
+
1550
1574
  while (--l > 0)
1551
1575
  {
1552
1576
  if (*++s == '\0')
@@ -1596,6 +1620,11 @@ pg_gbk_verifychar(const unsigned char *s, int len)
1596
1620
  if (len < l)
1597
1621
  return -1;
1598
1622
 
1623
+ if (l == 2 &&
1624
+ s[0] == NONUTF8_INVALID_BYTE0 &&
1625
+ s[1] == NONUTF8_INVALID_BYTE1)
1626
+ return -1;
1627
+
1599
1628
  while (--l > 0)
1600
1629
  {
1601
1630
  if (*++s == '\0')
@@ -1645,6 +1674,11 @@ pg_uhc_verifychar(const unsigned char *s, int len)
1645
1674
  if (len < l)
1646
1675
  return -1;
1647
1676
 
1677
+ if (l == 2 &&
1678
+ s[0] == NONUTF8_INVALID_BYTE0 &&
1679
+ s[1] == NONUTF8_INVALID_BYTE1)
1680
+ return -1;
1681
+
1648
1682
  while (--l > 0)
1649
1683
  {
1650
1684
  if (*++s == '\0')
@@ -2089,6 +2123,12 @@ pg_utf8_islegal(const unsigned char *source, int length)
2089
2123
  }
2090
2124
 
2091
2125
 
2126
+ /*
2127
+ * Fills the provided buffer with two bytes such that:
2128
+ * pg_encoding_mblen(dst) == 2 && pg_encoding_verifymbstr(dst) == 0
2129
+ */
2130
+
2131
+
2092
2132
  /*
2093
2133
  *-------------------------------------------------------------------
2094
2134
  * encoding info table
@@ -2188,5 +2228,11 @@ pg_encoding_max_length(int encoding)
2188
2228
  {
2189
2229
  Assert(PG_VALID_ENCODING(encoding));
2190
2230
 
2191
- return pg_wchar_table[encoding].maxmblen;
2231
+ /*
2232
+ * Check for the encoding despite the assert, due to some mingw versions
2233
+ * otherwise issuing bogus warnings.
2234
+ */
2235
+ return PG_VALID_ENCODING(encoding) ?
2236
+ pg_wchar_table[encoding].maxmblen :
2237
+ pg_wchar_table[PG_SQL_ASCII].maxmblen;
2192
2238
  }
@@ -3,7 +3,7 @@
3
3
  * - pg_vsnprintf
4
4
  * - dopr
5
5
  * - pg_snprintf
6
- * - strchrnul
6
+ * - pg_strchrnul
7
7
  * - dostr
8
8
  * - flushbuffer
9
9
  * - find_arguments
@@ -362,13 +362,22 @@ static void leading_pad(int zpad, int signvalue, int *padlen,
362
362
  static void trailing_pad(int padlen, PrintfTarget *target);
363
363
 
364
364
  /*
365
- * If strchrnul exists (it's a glibc-ism), it's a good bit faster than the
366
- * equivalent manual loop. If it doesn't exist, provide a replacement.
365
+ * If strchrnul exists (it's a glibc-ism, but since adopted by some other
366
+ * platforms), it's a good bit faster than the equivalent manual loop.
367
+ * Use it if possible, and if it doesn't exist, use this replacement.
367
368
  *
368
369
  * Note: glibc declares this as returning "char *", but that would require
369
370
  * casting away const internally, so we don't follow that detail.
371
+ *
372
+ * Note: macOS has this too as of Sequoia 15.4, but it's hidden behind
373
+ * a deployment-target check that causes compile errors if the deployment
374
+ * target isn't high enough. So !HAVE_DECL_STRCHRNUL may mean "yes it's
375
+ * declared, but it doesn't compile". To avoid failing in that scenario,
376
+ * use a macro to avoid matching <string.h>'s name.
370
377
  */
371
- #ifndef HAVE_STRCHRNUL
378
+ #if !HAVE_DECL_STRCHRNUL
379
+
380
+ #define strchrnul pg_strchrnul
372
381
 
373
382
  static inline const char *
374
383
  strchrnul(const char *s, int c)
@@ -378,19 +387,7 @@ strchrnul(const char *s, int c)
378
387
  return s;
379
388
  }
380
389
 
381
- #else
382
-
383
- /*
384
- * glibc's <string.h> declares strchrnul only if _GNU_SOURCE is defined.
385
- * While we typically use that on glibc platforms, configure will set
386
- * HAVE_STRCHRNUL whether it's used or not. Fill in the missing declaration
387
- * so that this file will compile cleanly with or without _GNU_SOURCE.
388
- */
389
- #ifndef _GNU_SOURCE
390
- extern char *strchrnul(const char *s, int c);
391
- #endif
392
-
393
- #endif /* HAVE_STRCHRNUL */
390
+ #endif /* !HAVE_DECL_STRCHRNUL */
394
391
 
395
392
 
396
393
  /*
@@ -61,7 +61,7 @@ module PgQuery
61
61
 
62
62
  def ignored_node_type?(node)
63
63
  [A_Const, Alias, ParamRef, SetToDefault, IntList, OidList].include?(node.class) ||
64
- node.is_a?(TypeCast) && (node.arg.node == :a_const || node.arg.node == :param_ref)
64
+ (node.is_a?(TypeCast) && %i[a_const param_ref].include?(node.arg.node))
65
65
  end
66
66
 
67
67
  def node_protobuf_field_name_to_json_name(node_class, field)
@@ -112,12 +112,10 @@ module PgQuery
112
112
  fingerprint_value(val.gsub(/\d{2,}/, ''), hash, postgres_node_name, postgres_field_name, true)
113
113
  next
114
114
  end
115
- when 'stmt_len'
116
- next if node.is_a?(RawStmt)
117
- when 'stmt_location'
115
+ when 'stmt_len', 'stmt_location'
118
116
  next if node.is_a?(RawStmt)
119
117
  when 'kind'
120
- if node.is_a?(A_Expr) && (val == :AEXPR_OP_ANY || val == :AEXPR_IN)
118
+ if node.is_a?(A_Expr) && %i[AEXPR_OP_ANY AEXPR_IN].include?(val)
121
119
  fingerprint_value(:AEXPR_OP, hash, postgres_node_name, postgres_field_name, true)
122
120
  next
123
121
  end
@@ -7,7 +7,7 @@ module PgQuery
7
7
  case node
8
8
  when PgQuery::ParamRef
9
9
  # Ignore param refs inside type casts, as these are already handled
10
- next if location[-3..-1] == %i[type_cast arg param_ref]
10
+ next if location[-3..] == %i[type_cast arg param_ref]
11
11
 
12
12
  results << { 'location' => node.location,
13
13
  'length' => param_ref_length(node) }
@@ -24,9 +24,7 @@ module PgQuery
24
24
  end
25
25
 
26
26
  class ParserResult
27
- attr_reader :query
28
- attr_reader :tree
29
- attr_reader :warnings
27
+ attr_reader :query, :tree, :warnings
30
28
 
31
29
  def initialize(query, tree, warnings = [])
32
30
  @query = query
@@ -176,7 +174,7 @@ module PgQuery
176
174
  # The following statement types are DDL (changing table structure)
177
175
  when :alter_table_stmt
178
176
  case statement.alter_table_stmt.objtype
179
- when :OBJECT_INDEX # Index # rubocop:disable Lint/EmptyWhen
177
+ when :OBJECT_INDEX # Index
180
178
  # ignore `ALTER INDEX index_name`
181
179
  else
182
180
  from_clause_items << { item: PgQuery::Node.new(range_var: statement.alter_table_stmt.relation), type: :ddl }
@@ -230,11 +228,11 @@ module PgQuery
230
228
  when :grant_stmt
231
229
  objects = statement.grant_stmt.objects
232
230
  case statement.grant_stmt.objtype
233
- when :OBJECT_COLUMN # Column # rubocop:disable Lint/EmptyWhen
231
+ when :OBJECT_COLUMN # Column
234
232
  # FIXME
235
233
  when :OBJECT_TABLE # Table
236
234
  from_clause_items += objects.map { |o| { item: o, type: :ddl } }
237
- when :OBJECT_SEQUENCE # Sequence # rubocop:disable Lint/EmptyWhen
235
+ when :OBJECT_SEQUENCE # Sequence
238
236
  # FIXME
239
237
  end
240
238
  when :lock_stmt
@@ -339,7 +337,7 @@ module PgQuery
339
337
  @cte_names.uniq!
340
338
  end
341
339
 
342
- def statements_and_cte_names_for_with_clause(with_clause) # FIXME
340
+ def statements_and_cte_names_for_with_clause(with_clause)
343
341
  statements = []
344
342
  cte_names = []
345
343
 
@@ -1,6 +1,7 @@
1
1
  module PgQuery
2
2
  class ParseError < ArgumentError
3
3
  attr_reader :location
4
+
4
5
  def initialize(message, source_file, source_line, location)
5
6
  super("#{message} (#{source_file}:#{source_line})")
6
7
  @location = location