pg_query 2.1.4 → 2.2.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/Rakefile +2 -2
  4. data/ext/pg_query/include/access/twophase.h +2 -0
  5. data/ext/pg_query/include/access/xact.h +6 -0
  6. data/ext/pg_query/include/access/xlog_internal.h +10 -1
  7. data/ext/pg_query/include/access/xlogreader.h +10 -0
  8. data/ext/pg_query/include/catalog/dependency.h +2 -0
  9. data/ext/pg_query/include/catalog/pg_class.h +1 -1
  10. data/ext/pg_query/include/catalog/pg_class_d.h +1 -1
  11. data/ext/pg_query/include/catalog/pg_control.h +2 -0
  12. data/ext/pg_query/include/catalog/pg_operator.h +3 -1
  13. data/ext/pg_query/include/catalog/pg_publication.h +3 -0
  14. data/ext/pg_query/include/catalog/pg_type.h +1 -0
  15. data/ext/pg_query/include/commands/async.h +1 -1
  16. data/ext/pg_query/include/commands/tablespace.h +2 -0
  17. data/ext/pg_query/include/commands/trigger.h +8 -0
  18. data/ext/pg_query/include/lib/simplehash.h +13 -13
  19. data/ext/pg_query/include/libpq/libpq.h +1 -0
  20. data/ext/pg_query/include/mb/pg_wchar.h +1 -0
  21. data/ext/pg_query/include/miscadmin.h +24 -11
  22. data/ext/pg_query/include/nodes/execnodes.h +2 -2
  23. data/ext/pg_query/include/nodes/parsenodes.h +5 -4
  24. data/ext/pg_query/include/nodes/pathnodes.h +2 -1
  25. data/ext/pg_query/include/nodes/pg_list.h +1 -0
  26. data/ext/pg_query/include/nodes/plannodes.h +18 -3
  27. data/ext/pg_query/include/optimizer/optimizer.h +0 -5
  28. data/ext/pg_query/include/parser/gram.h +2 -2
  29. data/ext/pg_query/include/parser/kwlist.h +1 -1
  30. data/ext/pg_query/include/parser/parse_coerce.h +1 -0
  31. data/ext/pg_query/include/pg_config.h +16 -13
  32. data/ext/pg_query/include/pg_query.h +2 -2
  33. data/ext/pg_query/include/pg_query_fingerprint_defs.c +286 -314
  34. data/ext/pg_query/include/pg_query_outfuncs_defs.c +1 -0
  35. data/ext/pg_query/include/pg_query_readfuncs_defs.c +1 -0
  36. data/ext/pg_query/include/pgstat.h +2 -1
  37. data/ext/pg_query/include/plpgsql.h +2 -2
  38. data/ext/pg_query/include/port/pg_bitutils.h +48 -2
  39. data/ext/pg_query/include/port.h +4 -0
  40. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +4 -3
  41. data/ext/pg_query/include/replication/reorderbuffer.h +6 -5
  42. data/ext/pg_query/include/replication/slot.h +1 -1
  43. data/ext/pg_query/include/storage/block.h +1 -1
  44. data/ext/pg_query/include/storage/lock.h +6 -5
  45. data/ext/pg_query/include/storage/lwlock.h +1 -0
  46. data/ext/pg_query/include/storage/proc.h +14 -0
  47. data/ext/pg_query/include/storage/s_lock.h +24 -0
  48. data/ext/pg_query/include/tcop/pquery.h +6 -0
  49. data/ext/pg_query/include/utils/builtins.h +1 -0
  50. data/ext/pg_query/include/utils/inval.h +1 -0
  51. data/ext/pg_query/include/utils/portal.h +13 -0
  52. data/ext/pg_query/include/utils/rel.h +0 -1
  53. data/ext/pg_query/include/utils/relcache.h +1 -2
  54. data/ext/pg_query/include/utils/snapmgr.h +1 -0
  55. data/ext/pg_query/pg_query.pb-c.c +18 -5
  56. data/ext/pg_query/pg_query_deparse.c +8 -8
  57. data/ext/pg_query/pg_query_fingerprint.c +1 -0
  58. data/ext/pg_query/pg_query_json_plpgsql.c +68 -0
  59. data/ext/pg_query/pg_query_normalize.c +43 -7
  60. data/ext/pg_query/pg_query_outfuncs.h +1 -0
  61. data/ext/pg_query/pg_query_outfuncs_json.c +11 -0
  62. data/ext/pg_query/pg_query_parse_plpgsql.c +58 -15
  63. data/ext/pg_query/src_backend_catalog_namespace.c +1 -0
  64. data/ext/pg_query/src_backend_libpq_pqcomm.c +8 -0
  65. data/ext/pg_query/src_backend_nodes_copyfuncs.c +23 -33
  66. data/ext/pg_query/src_backend_nodes_equalfuncs.c +1 -0
  67. data/ext/pg_query/src_backend_nodes_list.c +12 -0
  68. data/ext/pg_query/src_backend_parser_gram.c +18 -3
  69. data/ext/pg_query/src_backend_parser_scan.c +493 -253
  70. data/ext/pg_query/src_backend_tcop_postgres.c +11 -1
  71. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +38 -10
  72. data/ext/pg_query/src_backend_utils_misc_guc.c +1 -0
  73. data/ext/pg_query/src_common_wchar.c +11 -0
  74. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +4 -2
  75. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1 -1
  76. data/ext/pg_query/src_port_pg_bitutils.c +1 -22
  77. data/ext/pg_query/src_port_snprintf.c +9 -7
  78. data/lib/pg_query/deparse.rb +7 -1
  79. data/lib/pg_query/fingerprint.rb +13 -2
  80. data/lib/pg_query/pg_query_pb.rb +2 -1
  81. data/lib/pg_query/version.rb +1 -1
  82. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe9be3677078ec8a4990a53c9e0aa74c21f2a66672fe3a0990b23c00a6da34af
4
- data.tar.gz: 31e3bbcdfac0cd27a1553ac0f0d33f7cbd7e36ce8c5080f29a314da67adcc76a
3
+ metadata.gz: 27667deffca50f6c8efc514a644d951e5129e5a7ff5fdf472ad39501adda12f0
4
+ data.tar.gz: 3398f333de65ba7fdc637d9746805525b4a22933cbd9d6889c1d68643a780dca
5
5
  SHA512:
6
- metadata.gz: 7a8e0ef4b389446f952988903aa6b5772c6caabaea80d97e4f40affdf0830227285e60af0848a2786fcdab98232e96a5a75d3b5f73b24378b9ef67e9d24d9bf8
7
- data.tar.gz: ffd90f7bdf9a155cb7a014eaf9c8bfbf06d0905e70bc5dadc739015c4d11695ead10ae1960e1bcee44e3d81d3c8a5b7d47b6705a32ef93daa8d909b328ee9602
6
+ metadata.gz: c30bfcab9a142efc9c0fa8f12a18c157daa2074baf5b792cb832c2a214676f62aa558be69de2d5a0e15f87e3b4818b78d733844ada15fd0e96ba35fbe3b075da
7
+ data.tar.gz: 1292be5ffdf9021997514e2a8175a4fae4058fbf4ece99c1a49de09b2490d9244947d35b46ecb0574c32a61d4cbb86eee518372b8b20496d47fd86ae264b8489
data/CHANGELOG.md CHANGED
@@ -4,6 +4,29 @@
4
4
 
5
5
  * ...
6
6
 
7
+
8
+ ## 2.2.0 2022-11-02
9
+
10
+ * Update to libpg_query 13-2.2.0 ([#264](https://github.com/pganalyze/pg_query/pull/264))
11
+ - Fingerprinting version 3.1
12
+ - Fixes issue with "SELECT DISTINCT" having the same fingerprint as "SELECT"
13
+ (fingerprints for "SELECT DISTINCT" will change with this revision)
14
+ - Group additional DDL statements together that otherwise generate a lot of
15
+ unique fingerprints (ListenStmt, UnlistenStmt, NotifyStmt, CreateFunctionStmt,
16
+ FunctionParameter and DoStmt)
17
+ - Deparser improvements
18
+ - Prefix errors with "deparse", and remove some asserts
19
+ - Fix potential segfault when passing invalid protobuf (RawStmt without Stmt)
20
+ - Update to Postgres 13.8 patch release
21
+ - Backport Xcode 14.1 build fix from upcoming 13.9 release
22
+ - Normalize additional DDL statements
23
+ - Add support for analyzing PL/pgSQL code inside DO blocks
24
+ - Fix memory leak in pg_query_fingerprint error handling
25
+ - PL/pgSQL parser: Add support for Assert, SET, COMMIT, ROLLBACK and CALL
26
+ - Add support for parsing more operators that include a `?` character
27
+ * Support deparsing deeply nested queries ([#259](https://github.com/pganalyze/pg_query/pull/259))
28
+
29
+
7
30
  ## 2.1.4 2022-09-19
8
31
 
9
32
  * Truncate: Simplify VALUES(...) lists
@@ -13,6 +36,7 @@
13
36
  * Find function calls referenced in expression indexes ([#249](https://github.com/pganalyze/pg_query/pull/249))
14
37
  * Drop `Init_pg_query` from exported symbol map ([#256](https://github.com/pganalyze/pg_query/pull/256))
15
38
 
39
+
16
40
  ## 2.1.3 2022-01-28
17
41
 
18
42
  * Track tables in EXCEPT and INTERSECT queries ([#239](https://github.com/pganalyze/pg_query/pull/239))
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,