pg_query 2.1.4 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/README.md +32 -0
  4. data/Rakefile +2 -2
  5. data/ext/pg_query/include/access/twophase.h +2 -0
  6. data/ext/pg_query/include/access/xact.h +6 -0
  7. data/ext/pg_query/include/access/xlog_internal.h +10 -1
  8. data/ext/pg_query/include/access/xlogreader.h +10 -0
  9. data/ext/pg_query/include/catalog/dependency.h +2 -0
  10. data/ext/pg_query/include/catalog/pg_class.h +1 -1
  11. data/ext/pg_query/include/catalog/pg_class_d.h +1 -1
  12. data/ext/pg_query/include/catalog/pg_control.h +2 -0
  13. data/ext/pg_query/include/catalog/pg_operator.h +3 -1
  14. data/ext/pg_query/include/catalog/pg_publication.h +3 -0
  15. data/ext/pg_query/include/catalog/pg_type.h +1 -0
  16. data/ext/pg_query/include/commands/async.h +1 -1
  17. data/ext/pg_query/include/commands/tablespace.h +2 -0
  18. data/ext/pg_query/include/commands/trigger.h +8 -0
  19. data/ext/pg_query/include/lib/simplehash.h +13 -13
  20. data/ext/pg_query/include/libpq/libpq.h +1 -0
  21. data/ext/pg_query/include/mb/pg_wchar.h +1 -0
  22. data/ext/pg_query/include/miscadmin.h +24 -11
  23. data/ext/pg_query/include/nodes/execnodes.h +2 -2
  24. data/ext/pg_query/include/nodes/parsenodes.h +5 -4
  25. data/ext/pg_query/include/nodes/pathnodes.h +2 -1
  26. data/ext/pg_query/include/nodes/pg_list.h +1 -0
  27. data/ext/pg_query/include/nodes/plannodes.h +18 -3
  28. data/ext/pg_query/include/optimizer/optimizer.h +0 -5
  29. data/ext/pg_query/include/parser/gram.h +2 -2
  30. data/ext/pg_query/include/parser/kwlist.h +1 -1
  31. data/ext/pg_query/include/parser/parse_coerce.h +1 -0
  32. data/ext/pg_query/include/pg_config.h +16 -13
  33. data/ext/pg_query/include/pg_query.h +2 -2
  34. data/ext/pg_query/include/pg_query_fingerprint_defs.c +286 -314
  35. data/ext/pg_query/include/pg_query_outfuncs_defs.c +1 -0
  36. data/ext/pg_query/include/pg_query_readfuncs_defs.c +1 -0
  37. data/ext/pg_query/include/pgstat.h +2 -1
  38. data/ext/pg_query/include/plpgsql.h +2 -2
  39. data/ext/pg_query/include/port/pg_bitutils.h +48 -2
  40. data/ext/pg_query/include/port.h +4 -0
  41. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +4 -3
  42. data/ext/pg_query/include/replication/reorderbuffer.h +6 -5
  43. data/ext/pg_query/include/replication/slot.h +1 -1
  44. data/ext/pg_query/include/storage/block.h +1 -1
  45. data/ext/pg_query/include/storage/lock.h +6 -5
  46. data/ext/pg_query/include/storage/lwlock.h +1 -0
  47. data/ext/pg_query/include/storage/proc.h +14 -0
  48. data/ext/pg_query/include/storage/s_lock.h +24 -0
  49. data/ext/pg_query/include/tcop/pquery.h +6 -0
  50. data/ext/pg_query/include/utils/builtins.h +1 -0
  51. data/ext/pg_query/include/utils/inval.h +1 -0
  52. data/ext/pg_query/include/utils/portal.h +13 -0
  53. data/ext/pg_query/include/utils/rel.h +0 -1
  54. data/ext/pg_query/include/utils/relcache.h +1 -2
  55. data/ext/pg_query/include/utils/snapmgr.h +1 -0
  56. data/ext/pg_query/pg_query.pb-c.c +18 -5
  57. data/ext/pg_query/pg_query_deparse.c +8 -8
  58. data/ext/pg_query/pg_query_fingerprint.c +1 -0
  59. data/ext/pg_query/pg_query_json_plpgsql.c +68 -0
  60. data/ext/pg_query/pg_query_normalize.c +43 -7
  61. data/ext/pg_query/pg_query_outfuncs.h +1 -0
  62. data/ext/pg_query/pg_query_outfuncs_json.c +11 -0
  63. data/ext/pg_query/pg_query_parse_plpgsql.c +58 -15
  64. data/ext/pg_query/src_backend_catalog_namespace.c +1 -0
  65. data/ext/pg_query/src_backend_libpq_pqcomm.c +8 -0
  66. data/ext/pg_query/src_backend_nodes_copyfuncs.c +23 -33
  67. data/ext/pg_query/src_backend_nodes_equalfuncs.c +1 -0
  68. data/ext/pg_query/src_backend_nodes_list.c +12 -0
  69. data/ext/pg_query/src_backend_parser_gram.c +18 -3
  70. data/ext/pg_query/src_backend_parser_scan.c +493 -253
  71. data/ext/pg_query/src_backend_tcop_postgres.c +11 -1
  72. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +38 -10
  73. data/ext/pg_query/src_backend_utils_misc_guc.c +1 -0
  74. data/ext/pg_query/src_common_wchar.c +11 -0
  75. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +4 -2
  76. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1 -1
  77. data/ext/pg_query/src_port_pg_bitutils.c +1 -22
  78. data/ext/pg_query/src_port_snprintf.c +9 -7
  79. data/lib/pg_query/deparse.rb +7 -1
  80. data/lib/pg_query/fingerprint.rb +13 -2
  81. data/lib/pg_query/parse.rb +5 -3
  82. data/lib/pg_query/pg_query_pb.rb +2 -1
  83. data/lib/pg_query/treewalker.rb +6 -0
  84. data/lib/pg_query/version.rb +1 -1
  85. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe9be3677078ec8a4990a53c9e0aa74c21f2a66672fe3a0990b23c00a6da34af
4
- data.tar.gz: 31e3bbcdfac0cd27a1553ac0f0d33f7cbd7e36ce8c5080f29a314da67adcc76a
3
+ metadata.gz: 9625ed6fd4d8f67673ee922f191996d2c157addf6d97aa092af682a21bf96ce7
4
+ data.tar.gz: 9a20dedc0420e5a7f2162c642c2ddee60cd98fd6bbfeff1b1affc181f6dcbc27
5
5
  SHA512:
6
- metadata.gz: 7a8e0ef4b389446f952988903aa6b5772c6caabaea80d97e4f40affdf0830227285e60af0848a2786fcdab98232e96a5a75d3b5f73b24378b9ef67e9d24d9bf8
7
- data.tar.gz: ffd90f7bdf9a155cb7a014eaf9c8bfbf06d0905e70bc5dadc739015c4d11695ead10ae1960e1bcee44e3d81d3c8a5b7d47b6705a32ef93daa8d909b328ee9602
6
+ metadata.gz: 7f4633dd45e1530cebc92731315a238f22e4111ba23e10ea6991b6466f444ce2b974ffd858aaf5c93c5b6597e004e0b2334ac1832c24851956e34dd629fe58ff
7
+ data.tar.gz: 36d225dc15a58db4336cdbdd571a385308403b93d5507ec25b0deb5179be87b8a00fb029b1e5b77bdf62f79861fedd39ba350a50897bcfec4d61e266b2cdf639
data/CHANGELOG.md CHANGED
@@ -4,6 +4,34 @@
4
4
 
5
5
  * ...
6
6
 
7
+ ## 2.2.1 2022-01-20
8
+
9
+ * Detect tables used in the query of a PREPARE statement ([#273](https://github.com/pganalyze/pg_query/pull/273))
10
+ * Expose recursive walk functionality via walk! ([#268](https://github.com/pganalyze/pg_query/pull/268))
11
+ * Retain schema in name when parsing out functions ([#272](https://github.com/pganalyze/pg_query/pull/272))
12
+
13
+ ## 2.2.0 2022-11-02
14
+
15
+ * Update to libpg_query 13-2.2.0 ([#264](https://github.com/pganalyze/pg_query/pull/264))
16
+ - Fingerprinting version 3.1
17
+ - Fixes issue with "SELECT DISTINCT" having the same fingerprint as "SELECT"
18
+ (fingerprints for "SELECT DISTINCT" will change with this revision)
19
+ - Group additional DDL statements together that otherwise generate a lot of
20
+ unique fingerprints (ListenStmt, UnlistenStmt, NotifyStmt, CreateFunctionStmt,
21
+ FunctionParameter and DoStmt)
22
+ - Deparser improvements
23
+ - Prefix errors with "deparse", and remove some asserts
24
+ - Fix potential segfault when passing invalid protobuf (RawStmt without Stmt)
25
+ - Update to Postgres 13.8 patch release
26
+ - Backport Xcode 14.1 build fix from upcoming 13.9 release
27
+ - Normalize additional DDL statements
28
+ - Add support for analyzing PL/pgSQL code inside DO blocks
29
+ - Fix memory leak in pg_query_fingerprint error handling
30
+ - PL/pgSQL parser: Add support for Assert, SET, COMMIT, ROLLBACK and CALL
31
+ - Add support for parsing more operators that include a `?` character
32
+ * Support deparsing deeply nested queries ([#259](https://github.com/pganalyze/pg_query/pull/259))
33
+
34
+
7
35
  ## 2.1.4 2022-09-19
8
36
 
9
37
  * Truncate: Simplify VALUES(...) lists
@@ -13,6 +41,7 @@
13
41
  * Find function calls referenced in expression indexes ([#249](https://github.com/pganalyze/pg_query/pull/249))
14
42
  * Drop `Init_pg_query` from exported symbol map ([#256](https://github.com/pganalyze/pg_query/pull/256))
15
43
 
44
+
16
45
  ## 2.1.3 2022-01-28
17
46
 
18
47
  * Track tables in EXCEPT and INTERSECT queries ([#239](https://github.com/pganalyze/pg_query/pull/239))
data/README.md CHANGED
@@ -72,6 +72,8 @@ PgQuery.parse("SELECT 1")
72
72
 
73
73
  ### Modifying a parsed query and turning it into SQL again
74
74
 
75
+ This is a simple example for `deparse`, for more complex modification, use `walk!`.
76
+
75
77
  ```ruby
76
78
  parsed_query = PgQuery.parse("SELECT * FROM users")
77
79
 
@@ -145,6 +147,36 @@ PgQuery.scan('SELECT 1 --comment')
145
147
  []]
146
148
  ```
147
149
 
150
+ ### Walking the parse tree
151
+
152
+ For generalized use, PgQuery provides `walk!` as a means to recursively work with the parsed query.
153
+
154
+ This can be used to create a bespoke pretty printer:
155
+
156
+ ```ruby
157
+ parsed_query = PgQuery.parse "SELECT * FROM tbl"
158
+ parsed_query.walk! { |node, k, v, location| puts k }
159
+ ```
160
+
161
+ More usefully, this can be used to rewrite a query. For example:
162
+
163
+ ```ruby
164
+ parsed_query.walk! do |node, k, v, location| puts k
165
+ next unless k.eql?(:range_var) || k.eql?(:relation)
166
+ next if v.relname.nil?
167
+ v.relname = "X_" + v.relname
168
+ end
169
+
170
+ parsed_query.deparse
171
+ ```
172
+
173
+ There are some caveats, and limitations, in this example.
174
+
175
+ First, some of the tree nodes are frozen. You can replace them, but you cannot modify in place.
176
+
177
+ Second, table rewriting is a bit more nuanced than this example. While this will rewrite the table names, it will
178
+ not correctly handle all CTEs, or rewrite columns with explicit table names.
179
+
148
180
  ## Differences from Upstream PostgreSQL
149
181
 
150
182
  This gem is based on [libpg_query](https://github.com/pganalyze/libpg_query),
data/Rakefile CHANGED
@@ -5,8 +5,8 @@ require 'rspec/core/rake_task'
5
5
  require 'rubocop/rake_task'
6
6
  require 'open-uri'
7
7
 
8
- LIB_PG_QUERY_TAG = '13-2.1.0'.freeze
9
- LIB_PG_QUERY_SHA256SUM = 'a01329ae5bac19b10b8ddf8012bd663a20f85f180d6d7b900c1a1ca8444d19a5'.freeze
8
+ LIB_PG_QUERY_TAG = '13-2.2.0'.freeze
9
+ LIB_PG_QUERY_SHA256SUM = '07916be1a2b780dee6feed936aaa04ccee2a3afde8570a6920c3a839c87539c6'.freeze
10
10
 
11
11
  Rake::ExtensionTask.new 'pg_query' do |ext|
12
12
  ext.lib_dir = 'lib/pg_query'
@@ -34,6 +34,8 @@ extern void TwoPhaseShmemInit(void);
34
34
  extern void AtAbort_Twophase(void);
35
35
  extern void PostPrepare_Twophase(void);
36
36
 
37
+ extern TransactionId TwoPhaseGetXidByVirtualXID(VirtualTransactionId vxid,
38
+ bool *have_more);
37
39
  extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid, bool lock_held);
38
40
  extern BackendId TwoPhaseGetDummyBackendId(TransactionId xid, bool lock_held);
39
41
 
@@ -103,6 +103,12 @@ extern int MyXactFlags;
103
103
  */
104
104
  #define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK (1U << 1)
105
105
 
106
+ /*
107
+ * XACT_FLAGS_NEEDIMMEDIATECOMMIT - records whether the top level statement
108
+ * is one that requires immediate commit, such as CREATE DATABASE.
109
+ */
110
+ #define XACT_FLAGS_NEEDIMMEDIATECOMMIT (1U << 2)
111
+
106
112
  /*
107
113
  * start- and end-of-transaction callbacks for dynamically loaded modules
108
114
  */
@@ -79,8 +79,10 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
79
79
  #define XLP_LONG_HEADER 0x0002
80
80
  /* This flag indicates backup blocks starting in this page are optional */
81
81
  #define XLP_BKP_REMOVABLE 0x0004
82
+ /* Replaces a missing contrecord; see CreateOverwriteContrecordRecord */
83
+ #define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0008
82
84
  /* All defined flag bits in xlp_info (used for validity checking of header) */
83
- #define XLP_ALL_FLAGS 0x0007
85
+ #define XLP_ALL_FLAGS 0x000F
84
86
 
85
87
  #define XLogPageHeaderSize(hdr) \
86
88
  (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD)
@@ -252,6 +254,13 @@ typedef struct xl_restore_point
252
254
  char rp_name[MAXFNAMELEN];
253
255
  } xl_restore_point;
254
256
 
257
+ /* Overwrite of prior contrecord */
258
+ typedef struct xl_overwrite_contrecord
259
+ {
260
+ XLogRecPtr overwritten_lsn;
261
+ TimestampTz overwrite_time;
262
+ } xl_overwrite_contrecord;
263
+
255
264
  /* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */
256
265
  typedef struct xl_end_of_recovery
257
266
  {
@@ -250,6 +250,16 @@ struct XLogReaderState
250
250
 
251
251
  /* Buffer to hold error message */
252
252
  char *errormsg_buf;
253
+
254
+ /*
255
+ * Set at the end of recovery: the start point of a partial record at the
256
+ * end of WAL (InvalidXLogRecPtr if there wasn't one), and the start
257
+ * location of its first contrecord that went missing.
258
+ */
259
+ XLogRecPtr abortedRecPtr;
260
+ XLogRecPtr missingContrecPtr;
261
+ /* Set when XLP_FIRST_IS_OVERWRITE_CONTRECORD is found */
262
+ XLogRecPtr overwrittenRecPtr;
253
263
  };
254
264
 
255
265
  /* Get a new XLogReader */
@@ -201,6 +201,8 @@ extern void recordMultipleDependencies(const ObjectAddress *depender,
201
201
  extern void recordDependencyOnCurrentExtension(const ObjectAddress *object,
202
202
  bool isReplace);
203
203
 
204
+ extern void checkMembershipInCurrentExtension(const ObjectAddress *object);
205
+
204
206
  extern long deleteDependencyRecordsFor(Oid classId, Oid objectId,
205
207
  bool skipExtensionDeps);
206
208
 
@@ -178,7 +178,7 @@ typedef FormData_pg_class *Form_pg_class;
178
178
  /*
179
179
  * an explicitly chosen candidate key's columns are used as replica identity.
180
180
  * Note this will still be set if the index has been dropped; in that case it
181
- * has the same meaning as 'd'.
181
+ * has the same meaning as 'n'.
182
182
  */
183
183
  #define REPLICA_IDENTITY_INDEX 'i'
184
184
 
@@ -82,7 +82,7 @@
82
82
  /*
83
83
  * an explicitly chosen candidate key's columns are used as replica identity.
84
84
  * Note this will still be set if the index has been dropped; in that case it
85
- * has the same meaning as 'd'.
85
+ * has the same meaning as 'n'.
86
86
  */
87
87
  #define REPLICA_IDENTITY_INDEX 'i'
88
88
 
@@ -76,6 +76,8 @@ typedef struct CheckPoint
76
76
  #define XLOG_END_OF_RECOVERY 0x90
77
77
  #define XLOG_FPI_FOR_HINT 0xA0
78
78
  #define XLOG_FPI 0xB0
79
+ /* 0xC0 is used in Postgres 9.5-11 */
80
+ #define XLOG_OVERWRITE_CONTRECORD 0xD0
79
81
 
80
82
 
81
83
  /*
@@ -95,7 +95,9 @@ extern ObjectAddress OperatorCreate(const char *operatorName,
95
95
  bool canMerge,
96
96
  bool canHash);
97
97
 
98
- extern ObjectAddress makeOperatorDependencies(HeapTuple tuple, bool isUpdate);
98
+ extern ObjectAddress makeOperatorDependencies(HeapTuple tuple,
99
+ bool makeExtensionDep,
100
+ bool isUpdate);
99
101
 
100
102
  extern void OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete);
101
103
 
@@ -107,6 +107,9 @@ extern List *GetAllTablesPublicationRelations(bool pubviaroot);
107
107
  extern bool is_publishable_relation(Relation rel);
108
108
  extern ObjectAddress publication_add_relation(Oid pubid, Relation targetrel,
109
109
  bool if_not_exists);
110
+ extern List *GetPubPartitionOptionRelations(List *result,
111
+ PublicationPartOpt pub_partopt,
112
+ Oid relid);
110
113
 
111
114
  extern Oid get_publication_oid(const char *pubname, bool missing_ok);
112
115
  extern char *get_publication_name(Oid pubid, bool missing_ok);
@@ -359,6 +359,7 @@ extern void GenerateTypeDependencies(HeapTuple typeTuple,
359
359
  * rowtypes */
360
360
  bool isImplicitArray,
361
361
  bool isDependentType,
362
+ bool makeExtensionDep,
362
363
  bool rebuild);
363
364
 
364
365
  extern void RenameTypeInternal(Oid typeOid, const char *newTypeName,
@@ -49,6 +49,6 @@ extern void ProcessCompletedNotifies(void);
49
49
  extern void HandleNotifyInterrupt(void);
50
50
 
51
51
  /* process interrupts */
52
- extern void ProcessNotifyInterrupt(void);
52
+ extern void ProcessNotifyInterrupt(bool flush);
53
53
 
54
54
  #endif /* ASYNC_H */
@@ -19,6 +19,8 @@
19
19
  #include "lib/stringinfo.h"
20
20
  #include "nodes/parsenodes.h"
21
21
 
22
+ extern bool allow_in_place_tablespaces;
23
+
22
24
  /* XLOG stuff */
23
25
  #define XLOG_TBLSPC_CREATE 0x00
24
26
  #define XLOG_TBLSPC_DROP 0x10
@@ -162,12 +162,20 @@ extern ObjectAddress CreateTrigger(CreateTrigStmt *stmt, const char *queryString
162
162
  Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid,
163
163
  Oid funcoid, Oid parentTriggerOid, Node *whenClause,
164
164
  bool isInternal, bool in_partition);
165
+ extern ObjectAddress CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString,
166
+ Oid relOid, Oid refRelOid, Oid constraintOid,
167
+ Oid indexOid, Oid funcoid, Oid parentTriggerOid,
168
+ Node *whenClause, bool isInternal, bool in_partition,
169
+ char trigger_fires_when);
165
170
 
166
171
  extern void RemoveTriggerById(Oid trigOid);
167
172
  extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok);
168
173
 
169
174
  extern ObjectAddress renametrig(RenameStmt *stmt);
170
175
 
176
+ extern void EnableDisableTriggerNew(Relation rel, const char *tgname,
177
+ char fires_when, bool skip_system, bool recurse,
178
+ LOCKMODE lockmode);
171
179
  extern void EnableDisableTrigger(Relation rel, const char *tgname,
172
180
  char fires_when, bool skip_system, LOCKMODE lockmode);
173
181
 
@@ -55,6 +55,11 @@
55
55
  * presence is relevant to determine whether a lookup needs to continue
56
56
  * looking or is done - buckets following a deleted element are shifted
57
57
  * backwards, unless they're empty or already at their optimal position.
58
+ *
59
+ * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
60
+ * Portions Copyright (c) 1994, Regents of the University of California
61
+ *
62
+ * src/include/lib/simplehash.h
58
63
  */
59
64
 
60
65
  #include "port/pg_bitutils.h"
@@ -156,7 +161,7 @@ SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements,
156
161
  #endif
157
162
  SH_SCOPE void SH_DESTROY(SH_TYPE * tb);
158
163
  SH_SCOPE void SH_RESET(SH_TYPE * tb);
159
- SH_SCOPE void SH_GROW(SH_TYPE * tb, uint32 newsize);
164
+ SH_SCOPE void SH_GROW(SH_TYPE * tb, uint64 newsize);
160
165
  SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found);
161
166
  SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT_HASH(SH_TYPE * tb, SH_KEY_TYPE key,
162
167
  uint32 hash, bool *found);
@@ -218,7 +223,8 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb);
218
223
  #define SIMPLEHASH_H
219
224
 
220
225
  #ifdef FRONTEND
221
- #define sh_error(...) pg_log_error(__VA_ARGS__)
226
+ #define sh_error(...) \
227
+ do { pg_log_fatal(__VA_ARGS__); exit(1); } while(0)
222
228
  #define sh_log(...) pg_log_info(__VA_ARGS__)
223
229
  #else
224
230
  #define sh_error(...) elog(ERROR, __VA_ARGS__)
@@ -232,7 +238,7 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb);
232
238
  * the hashtable.
233
239
  */
234
240
  static inline void
235
- SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint32 newsize)
241
+ SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint64 newsize)
236
242
  {
237
243
  uint64 size;
238
244
 
@@ -247,16 +253,12 @@ SH_COMPUTE_PARAMETERS(SH_TYPE * tb, uint32 newsize)
247
253
  * Verify that allocation of ->data is possible on this platform, without
248
254
  * overflowing Size.
249
255
  */
250
- if ((((uint64) sizeof(SH_ELEMENT_TYPE)) * size) >= SIZE_MAX / 2)
256
+ if (unlikely((((uint64) sizeof(SH_ELEMENT_TYPE)) * size) >= SIZE_MAX / 2))
251
257
  sh_error("hash table too large");
252
258
 
253
259
  /* now set size */
254
260
  tb->size = size;
255
-
256
- if (tb->size == SH_MAX_SIZE)
257
- tb->sizemask = 0;
258
- else
259
- tb->sizemask = tb->size - 1;
261
+ tb->sizemask = (uint32) (size - 1);
260
262
 
261
263
  /*
262
264
  * Compute the next threshold at which we need to grow the hash table
@@ -406,7 +408,7 @@ SH_RESET(SH_TYPE * tb)
406
408
  * performance-wise, when known at some point.
407
409
  */
408
410
  SH_SCOPE void
409
- SH_GROW(SH_TYPE * tb, uint32 newsize)
411
+ SH_GROW(SH_TYPE * tb, uint64 newsize)
410
412
  {
411
413
  uint64 oldsize = tb->size;
412
414
  SH_ELEMENT_TYPE *olddata = tb->data;
@@ -536,10 +538,8 @@ restart:
536
538
  */
537
539
  if (unlikely(tb->members >= tb->grow_threshold))
538
540
  {
539
- if (tb->size == SH_MAX_SIZE)
540
- {
541
+ if (unlikely(tb->size == SH_MAX_SIZE))
541
542
  sh_error("hash table size exceeded");
542
- }
543
543
 
544
544
  /*
545
545
  * When optimizing, it can be very useful to print these out.
@@ -72,6 +72,7 @@ extern int pq_getmessage(StringInfo s, int maxlen);
72
72
  extern int pq_getbyte(void);
73
73
  extern int pq_peekbyte(void);
74
74
  extern int pq_getbyte_if_available(unsigned char *c);
75
+ extern bool pq_buffer_has_data(void);
75
76
  extern int pq_putbytes(const char *s, size_t len);
76
77
 
77
78
  /*
@@ -553,6 +553,7 @@ extern int pg_valid_server_encoding_id(int encoding);
553
553
  * earlier in this file are also available from libpgcommon.
554
554
  */
555
555
  extern int pg_encoding_mblen(int encoding, const char *mbstr);
556
+ extern int pg_encoding_mblen_bounded(int encoding, const char *mbstr);
556
557
  extern int pg_encoding_dsplen(int encoding, const char *mbstr);
557
558
  extern int pg_encoding_verifymb(int encoding, const char *mbstr, int len);
558
559
  extern int pg_encoding_max_length(int encoding);
@@ -57,6 +57,15 @@
57
57
  * allowing die interrupts: HOLD_CANCEL_INTERRUPTS() and
58
58
  * RESUME_CANCEL_INTERRUPTS().
59
59
  *
60
+ * Note that ProcessInterrupts() has also acquired a number of tasks that
61
+ * do not necessarily cause a query-cancel-or-die response. Hence, it's
62
+ * possible that it will just clear InterruptPending and return.
63
+ *
64
+ * INTERRUPTS_PENDING_CONDITION() can be checked to see whether an
65
+ * interrupt needs to be serviced, without trying to do so immediately.
66
+ * Some callers are also interested in INTERRUPTS_CAN_BE_PROCESSED(),
67
+ * which tells whether ProcessInterrupts is sure to clear the interrupt.
68
+ *
60
69
  * Special mechanisms are used to let an interrupt be accepted when we are
61
70
  * waiting for a lock or when we are waiting for command input (but, of
62
71
  * course, only if the interrupt holdoff counter is zero). See the
@@ -94,24 +103,27 @@ extern PGDLLIMPORT __thread volatile uint32 CritSectionCount;
94
103
  /* in tcop/postgres.c */
95
104
  extern void ProcessInterrupts(void);
96
105
 
106
+ /* Test whether an interrupt is pending */
97
107
  #ifndef WIN32
108
+ #define INTERRUPTS_PENDING_CONDITION() \
109
+ (unlikely(InterruptPending))
110
+ #else
111
+ #define INTERRUPTS_PENDING_CONDITION() \
112
+ (unlikely(UNBLOCKED_SIGNAL_QUEUE()) ? pgwin32_dispatch_queued_signals() : 0, \
113
+ unlikely(InterruptPending))
114
+ #endif
98
115
 
116
+ /* Service interrupt, if one is pending and it's safe to service it now */
99
117
  #define CHECK_FOR_INTERRUPTS() \
100
118
  do { \
101
- if (unlikely(InterruptPending)) \
102
- ProcessInterrupts(); \
103
- } while(0)
104
- #else /* WIN32 */
105
-
106
- #define CHECK_FOR_INTERRUPTS() \
107
- do { \
108
- if (unlikely(UNBLOCKED_SIGNAL_QUEUE())) \
109
- pgwin32_dispatch_queued_signals(); \
110
- if (unlikely(InterruptPending)) \
119
+ if (INTERRUPTS_PENDING_CONDITION()) \
111
120
  ProcessInterrupts(); \
112
121
  } while(0)
113
- #endif /* WIN32 */
114
122
 
123
+ /* Is ProcessInterrupts() guaranteed to clear InterruptPending? */
124
+ #define INTERRUPTS_CAN_BE_PROCESSED() \
125
+ (InterruptHoldoffCount == 0 && CritSectionCount == 0 && \
126
+ QueryCancelHoldoffCount == 0)
115
127
 
116
128
  #define HOLD_INTERRUPTS() (InterruptHoldoffCount++)
117
129
 
@@ -471,6 +483,7 @@ extern bool BackupInProgress(void);
471
483
  extern void CancelBackup(void);
472
484
 
473
485
  /* in executor/nodeHash.c */
486
+ extern size_t get_hash_memory_limit(void);
474
487
  extern int get_hash_mem(void);
475
488
 
476
489
  #endif /* MISCADMIN_H */
@@ -1454,7 +1454,7 @@ typedef struct IndexScanState
1454
1454
  /* ----------------
1455
1455
  * IndexOnlyScanState information
1456
1456
  *
1457
- * indexqual execution state for indexqual expressions
1457
+ * recheckqual execution state for recheckqual expressions
1458
1458
  * ScanKeys Skey structures for index quals
1459
1459
  * NumScanKeys number of ScanKeys
1460
1460
  * OrderByKeys Skey structures for index ordering operators
@@ -1473,7 +1473,7 @@ typedef struct IndexScanState
1473
1473
  typedef struct IndexOnlyScanState
1474
1474
  {
1475
1475
  ScanState ss; /* its first field is NodeTag */
1476
- ExprState *indexqual;
1476
+ ExprState *recheckqual;
1477
1477
  struct ScanKeyData *ioss_ScanKeys;
1478
1478
  int ioss_NumScanKeys;
1479
1479
  struct ScanKeyData *ioss_OrderByKeys;
@@ -915,10 +915,10 @@ typedef struct PartitionCmd
915
915
  * inFromCl marks those range variables that are listed in the FROM clause.
916
916
  * It's false for RTEs that are added to a query behind the scenes, such
917
917
  * as the NEW and OLD variables for a rule, or the subqueries of a UNION.
918
- * This flag is not used anymore during parsing, since the parser now uses
919
- * a separate "namespace" data structure to control visibility, but it is
920
- * needed by ruleutils.c to determine whether RTEs should be shown in
921
- * decompiled queries.
918
+ * This flag is not used during parsing (except in transformLockingClause,
919
+ * q.v.); the parser now uses a separate "namespace" data structure to
920
+ * control visibility. But it is needed by ruleutils.c to determine
921
+ * whether RTEs should be shown in decompiled queries.
922
922
  *
923
923
  * requiredPerms and checkAsUser specify run-time access permissions
924
924
  * checks to be performed at query startup. The user must have *all*
@@ -1876,6 +1876,7 @@ typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */
1876
1876
  * constraint, or parent table */
1877
1877
  DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */
1878
1878
  bool missing_ok; /* skip error if missing? */
1879
+ bool recurse; /* exec-time recursion */
1879
1880
  } AlterTableCmd;
1880
1881
 
1881
1882
 
@@ -258,7 +258,8 @@ struct PlannerInfo
258
258
 
259
259
  List *init_plans; /* init SubPlans for query */
260
260
 
261
- List *cte_plan_ids; /* per-CTE-item list of subplan IDs */
261
+ List *cte_plan_ids; /* per-CTE-item list of subplan IDs (or -1 if
262
+ * no subplan was made for that CTE) */
262
263
 
263
264
  List *multiexpr_params; /* List of Lists of Params for MULTIEXPR
264
265
  * subquery outputs */
@@ -560,6 +560,7 @@ extern List *list_delete_int(List *list, int datum);
560
560
  extern List *list_delete_oid(List *list, Oid datum);
561
561
  extern List *list_delete_first(List *list);
562
562
  extern List *list_delete_last(List *list);
563
+ extern List *list_delete_first_n(List *list, int n);
563
564
  extern List *list_delete_nth_cell(List *list, int n);
564
565
  extern List *list_delete_cell(List *list, ListCell *cell);
565
566
 
@@ -418,14 +418,28 @@ typedef struct IndexScan
418
418
  * index-only scan, in which the data comes from the index not the heap.
419
419
  * Because of this, *all* Vars in the plan node's targetlist, qual, and
420
420
  * index expressions reference index columns and have varno = INDEX_VAR.
421
- * Hence we do not need separate indexqualorig and indexorderbyorig lists,
422
- * since their contents would be equivalent to indexqual and indexorderby.
421
+ *
422
+ * We could almost use indexqual directly against the index's output tuple
423
+ * when rechecking lossy index operators, but that won't work for quals on
424
+ * index columns that are not retrievable. Hence, recheckqual is needed
425
+ * for rechecks: it expresses the same condition as indexqual, but using
426
+ * only index columns that are retrievable. (We will not generate an
427
+ * index-only scan if this is not possible. An example is that if an
428
+ * index has table column "x" in a retrievable index column "ind1", plus
429
+ * an expression f(x) in a non-retrievable column "ind2", an indexable
430
+ * query on f(x) will use "ind2" in indexqual and f(ind1) in recheckqual.
431
+ * Without the "ind1" column, an index-only scan would be disallowed.)
432
+ *
433
+ * We don't currently need a recheckable equivalent of indexorderby,
434
+ * because we don't support lossy operators in index ORDER BY.
423
435
  *
424
436
  * To help EXPLAIN interpret the index Vars for display, we provide
425
437
  * indextlist, which represents the contents of the index as a targetlist
426
438
  * with one TLE per index column. Vars appearing in this list reference
427
439
  * the base table, and this is the only field in the plan node that may
428
- * contain such Vars.
440
+ * contain such Vars. Also, for the convenience of setrefs.c, TLEs in
441
+ * indextlist are marked as resjunk if they correspond to columns that
442
+ * the index AM cannot reconstruct.
429
443
  * ----------------
430
444
  */
431
445
  typedef struct IndexOnlyScan
@@ -436,6 +450,7 @@ typedef struct IndexOnlyScan
436
450
  List *indexorderby; /* list of index ORDER BY exprs */
437
451
  List *indextlist; /* TargetEntry list describing index's cols */
438
452
  ScanDirection indexorderdir; /* forward or backward or don't care */
453
+ List *recheckqual; /* index quals in recheckable form */
439
454
  } IndexOnlyScan;
440
455
 
441
456
  /* ----------------
@@ -24,11 +24,6 @@
24
24
 
25
25
  #include "nodes/parsenodes.h"
26
26
 
27
- /* Test if an expression node represents a SRF call. Beware multiple eval! */
28
- #define IS_SRF_CALL(node) \
29
- ((IsA(node, FuncExpr) && ((FuncExpr *) (node))->funcretset) || \
30
- (IsA(node, OpExpr) && ((OpExpr *) (node))->opretset))
31
-
32
27
  /*
33
28
  * We don't want to include nodes/pathnodes.h here, because non-planner
34
29
  * code should generally treat PlannerInfo as an opaque typedef.
@@ -363,7 +363,7 @@
363
363
  REASSIGN = 579,
364
364
  RECHECK = 580,
365
365
  RECURSIVE = 581,
366
- REF = 582,
366
+ REF_P = 582,
367
367
  REFERENCES = 583,
368
368
  REFERENCING = 584,
369
369
  REFRESH = 585,
@@ -840,7 +840,7 @@
840
840
  #define REASSIGN 579
841
841
  #define RECHECK 580
842
842
  #define RECURSIVE 581
843
- #define REF 582
843
+ #define REF_P 582
844
844
  #define REFERENCES 583
845
845
  #define REFERENCING 584
846
846
  #define REFRESH 585
@@ -330,7 +330,7 @@ PG_KEYWORD("real", REAL, COL_NAME_KEYWORD)
330
330
  PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD)
331
331
  PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD)
332
332
  PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD)
333
- PG_KEYWORD("ref", REF, UNRESERVED_KEYWORD)
333
+ PG_KEYWORD("ref", REF_P, UNRESERVED_KEYWORD)
334
334
  PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD)
335
335
  PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD)
336
336
  PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD)
@@ -70,6 +70,7 @@ extern Oid select_common_type(ParseState *pstate, List *exprs,
70
70
  extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
71
71
  Oid targetTypeId,
72
72
  const char *context);
73
+ extern bool verify_common_type(Oid common_type, List *exprs);
73
74
 
74
75
  extern bool check_generic_type_consistency(const Oid *actual_arg_types,
75
76
  const Oid *declared_arg_types,