pg_query 2.1.4 → 2.2.1

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 (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
@@ -897,6 +897,7 @@ _outAlterTableCmd(OUT_TYPE(AlterTableCmd, AlterTableCmd) out, const AlterTableCm
897
897
  WRITE_NODE_PTR_FIELD(def, def, def);
898
898
  WRITE_ENUM_FIELD(DropBehavior, behavior, behavior, behavior);
899
899
  WRITE_BOOL_FIELD(missing_ok, missing_ok, missing_ok);
900
+ WRITE_BOOL_FIELD(recurse, recurse, recurse);
900
901
  }
901
902
 
902
903
  static void
@@ -1014,6 +1014,7 @@ _readAlterTableCmd(OUT_TYPE(AlterTableCmd, AlterTableCmd) msg)
1014
1014
  READ_NODE_PTR_FIELD(def, def, def);
1015
1015
  READ_ENUM_FIELD(DropBehavior, behavior, behavior, behavior);
1016
1016
  READ_BOOL_FIELD(missing_ok, missing_ok, missing_ok);
1017
+ READ_BOOL_FIELD(recurse, recurse, recurse);
1017
1018
  return node;
1018
1019
  }
1019
1020
 
@@ -902,7 +902,8 @@ typedef enum
902
902
  WAIT_EVENT_PG_SLEEP,
903
903
  WAIT_EVENT_RECOVERY_APPLY_DELAY,
904
904
  WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL,
905
- WAIT_EVENT_VACUUM_DELAY
905
+ WAIT_EVENT_VACUUM_DELAY,
906
+ WAIT_EVENT_REGISTER_SYNC_REQUEST
906
907
  } WaitEventTimeout;
907
908
 
908
909
  /* ----------
@@ -919,10 +919,10 @@ typedef struct PLpgSQL_stmt_execsql
919
919
  int lineno;
920
920
  unsigned int stmtid;
921
921
  PLpgSQL_expr *sqlstmt;
922
- bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? Note:
923
- * mod_stmt is set when we plan the query */
922
+ bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? */
924
923
  bool into; /* INTO supplied? */
925
924
  bool strict; /* INTO STRICT flag */
925
+ bool mod_stmt_set; /* is mod_stmt valid yet? */
926
926
  PLpgSQL_variable *target; /* INTO target (record or row) */
927
927
  } PLpgSQL_stmt_execsql;
928
928
 
@@ -137,7 +137,7 @@ pg_rightmost_one_pos64(uint64 word)
137
137
 
138
138
  /*
139
139
  * pg_nextpower2_32
140
- * Returns the next highest power of 2 of 'num', or 'num', if it's
140
+ * Returns the next higher power of 2 above 'num', or 'num' if it's
141
141
  * already a power of 2.
142
142
  *
143
143
  * 'num' mustn't be 0 or be above PG_UINT32_MAX / 2 + 1.
@@ -160,7 +160,7 @@ pg_nextpower2_32(uint32 num)
160
160
 
161
161
  /*
162
162
  * pg_nextpower2_64
163
- * Returns the next highest power of 2 of 'num', or 'num', if it's
163
+ * Returns the next higher power of 2 above 'num', or 'num' if it's
164
164
  * already a power of 2.
165
165
  *
166
166
  * 'num' mustn't be 0 or be above PG_UINT64_MAX / 2 + 1.
@@ -181,6 +181,52 @@ pg_nextpower2_64(uint64 num)
181
181
  return ((uint64) 1) << (pg_leftmost_one_pos64(num) + 1);
182
182
  }
183
183
 
184
+ /*
185
+ * pg_nextpower2_size_t
186
+ * Returns the next higher power of 2 above 'num', for a size_t input.
187
+ */
188
+ #if SIZEOF_SIZE_T == 4
189
+ #define pg_nextpower2_size_t(num) pg_nextpower2_32(num)
190
+ #else
191
+ #define pg_nextpower2_size_t(num) pg_nextpower2_64(num)
192
+ #endif
193
+
194
+ /*
195
+ * pg_prevpower2_32
196
+ * Returns the next lower power of 2 below 'num', or 'num' if it's
197
+ * already a power of 2.
198
+ *
199
+ * 'num' mustn't be 0.
200
+ */
201
+ static inline uint32
202
+ pg_prevpower2_32(uint32 num)
203
+ {
204
+ return ((uint32) 1) << pg_leftmost_one_pos32(num);
205
+ }
206
+
207
+ /*
208
+ * pg_prevpower2_64
209
+ * Returns the next lower power of 2 below 'num', or 'num' if it's
210
+ * already a power of 2.
211
+ *
212
+ * 'num' mustn't be 0.
213
+ */
214
+ static inline uint64
215
+ pg_prevpower2_64(uint64 num)
216
+ {
217
+ return ((uint64) 1) << pg_leftmost_one_pos64(num);
218
+ }
219
+
220
+ /*
221
+ * pg_prevpower2_size_t
222
+ * Returns the next lower power of 2 below 'num', for a size_t input.
223
+ */
224
+ #if SIZEOF_SIZE_T == 4
225
+ #define pg_prevpower2_size_t(num) pg_prevpower2_32(num)
226
+ #else
227
+ #define pg_prevpower2_size_t(num) pg_prevpower2_64(num)
228
+ #endif
229
+
184
230
  /*
185
231
  * pg_ceil_log2_32
186
232
  * Returns equivalent of ceil(log2(num))
@@ -429,6 +429,10 @@ extern size_t strnlen(const char *str, size_t maxlen);
429
429
  extern long random(void);
430
430
  #endif
431
431
 
432
+ #ifndef HAVE_SETENV
433
+ extern int setenv(const char *name, const char *value, int overwrite);
434
+ #endif
435
+
432
436
  #ifndef HAVE_UNSETENV
433
437
  extern void unsetenv(const char *name);
434
438
  #endif
@@ -10,7 +10,7 @@ PROTOBUF_C__BEGIN_DECLS
10
10
 
11
11
  #if PROTOBUF_C_VERSION_NUMBER < 1003000
12
12
  # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
13
- #elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION
13
+ #elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION
14
14
  # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
15
15
  #endif
16
16
 
@@ -1268,7 +1268,7 @@ typedef enum _PgQuery__Token {
1268
1268
  PG_QUERY__TOKEN__REASSIGN = 579,
1269
1269
  PG_QUERY__TOKEN__RECHECK = 580,
1270
1270
  PG_QUERY__TOKEN__RECURSIVE = 581,
1271
- PG_QUERY__TOKEN__REF = 582,
1271
+ PG_QUERY__TOKEN__REF_P = 582,
1272
1272
  PG_QUERY__TOKEN__REFERENCES = 583,
1273
1273
  PG_QUERY__TOKEN__REFERENCING = 584,
1274
1274
  PG_QUERY__TOKEN__REFRESH = 585,
@@ -3047,10 +3047,11 @@ struct PgQuery__AlterTableCmd
3047
3047
  PgQuery__Node *def;
3048
3048
  PgQuery__DropBehavior behavior;
3049
3049
  protobuf_c_boolean missing_ok;
3050
+ protobuf_c_boolean recurse;
3050
3051
  };
3051
3052
  #define PG_QUERY__ALTER_TABLE_CMD__INIT \
3052
3053
  { PROTOBUF_C_MESSAGE_INIT (&pg_query__alter_table_cmd__descriptor) \
3053
- , PG_QUERY__ALTER_TABLE_TYPE__ALTER_TABLE_TYPE_UNDEFINED, (char *)protobuf_c_empty_string, 0, NULL, NULL, PG_QUERY__DROP_BEHAVIOR__DROP_BEHAVIOR_UNDEFINED, 0 }
3054
+ , PG_QUERY__ALTER_TABLE_TYPE__ALTER_TABLE_TYPE_UNDEFINED, (char *)protobuf_c_empty_string, 0, NULL, NULL, PG_QUERY__DROP_BEHAVIOR__DROP_BEHAVIOR_UNDEFINED, 0, 0 }
3054
3055
 
3055
3056
 
3056
3057
  struct PgQuery__AlterDomainStmt
@@ -46,10 +46,10 @@ typedef struct ReorderBufferTupleBuf
46
46
  * changes. Users of the decoding facilities will never see changes with
47
47
  * *_INTERNAL_* actions.
48
48
  *
49
- * The INTERNAL_SPEC_INSERT and INTERNAL_SPEC_CONFIRM changes concern
50
- * "speculative insertions", and their confirmation respectively. They're
51
- * used by INSERT .. ON CONFLICT .. UPDATE. Users of logical decoding don't
52
- * have to care about these.
49
+ * The INTERNAL_SPEC_INSERT and INTERNAL_SPEC_CONFIRM, and INTERNAL_SPEC_ABORT
50
+ * changes concern "speculative insertions", their confirmation, and abort
51
+ * respectively. They're used by INSERT .. ON CONFLICT .. UPDATE. Users of
52
+ * logical decoding don't have to care about these.
53
53
  */
54
54
  enum ReorderBufferChangeType
55
55
  {
@@ -62,7 +62,8 @@ enum ReorderBufferChangeType
62
62
  REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID,
63
63
  REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT,
64
64
  REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM,
65
- REORDER_BUFFER_CHANGE_TRUNCATE
65
+ REORDER_BUFFER_CHANGE_TRUNCATE,
66
+ REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT
66
67
  };
67
68
 
68
69
  /* forward declaration */
@@ -209,7 +209,7 @@ extern void ReplicationSlotsComputeRequiredLSN(void);
209
209
  extern XLogRecPtr ReplicationSlotsComputeLogicalRestartLSN(void);
210
210
  extern bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive);
211
211
  extern void ReplicationSlotsDropDBSlots(Oid dboid);
212
- extern void InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno);
212
+ extern bool InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno);
213
213
 
214
214
  extern void StartupReplicationSlots(void);
215
215
  extern void CheckPointReplicationSlots(void);
@@ -115,7 +115,7 @@ typedef BlockIdData *BlockId; /* block identifier */
115
115
  #define BlockIdGetBlockNumber(blockId) \
116
116
  ( \
117
117
  AssertMacro(BlockIdIsValid(blockId)), \
118
- (BlockNumber) (((blockId)->bi_hi << 16) | ((uint16) (blockId)->bi_lo)) \
118
+ ((((BlockNumber) (blockId)->bi_hi) << 16) | ((BlockNumber) (blockId)->bi_lo)) \
119
119
  )
120
120
 
121
121
  #endif /* BLOCK_H */
@@ -46,10 +46,11 @@ extern bool Debug_deadlocks;
46
46
 
47
47
  /*
48
48
  * Top-level transactions are identified by VirtualTransactionIDs comprising
49
- * PGPROC fields backendId and lxid. For prepared transactions, the
50
- * LocalTransactionId is an ordinary XID. These are guaranteed unique over
51
- * the short term, but will be reused after a database restart or XID
52
- * wraparound; hence they should never be stored on disk.
49
+ * PGPROC fields backendId and lxid. For recovered prepared transactions, the
50
+ * LocalTransactionId is an ordinary XID; LOCKTAG_VIRTUALTRANSACTION never
51
+ * refers to that kind. These are guaranteed unique over the short term, but
52
+ * will be reused after a database restart or XID wraparound; hence they
53
+ * should never be stored on disk.
53
54
  *
54
55
  * Note that struct VirtualTransactionId can not be assumed to be atomically
55
56
  * assignable as a whole. However, type LocalTransactionId is assumed to
@@ -69,7 +70,7 @@ typedef struct
69
70
  #define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)
70
71
  #define VirtualTransactionIdIsValid(vxid) \
71
72
  (LocalTransactionIdIsValid((vxid).localTransactionId))
72
- #define VirtualTransactionIdIsPreparedXact(vxid) \
73
+ #define VirtualTransactionIdIsRecoveredPreparedXact(vxid) \
73
74
  ((vxid).backendId == InvalidBackendId)
74
75
  #define VirtualTransactionIdEquals(vxid1, vxid2) \
75
76
  ((vxid1).backendId == (vxid2).backendId && \
@@ -149,6 +149,7 @@ extern void LWLockRelease(LWLock *lock);
149
149
  extern void LWLockReleaseClearVar(LWLock *lock, uint64 *valptr, uint64 val);
150
150
  extern void LWLockReleaseAll(void);
151
151
  extern bool LWLockHeldByMe(LWLock *lock);
152
+ extern bool LWLockAnyHeldByMe(LWLock *lock, int nlocks, size_t stride);
152
153
  extern bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode);
153
154
 
154
155
  extern bool LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval);
@@ -62,6 +62,12 @@ struct XidCache
62
62
  #define PROC_VACUUM_STATE_MASK \
63
63
  (PROC_IN_VACUUM | PROC_IN_ANALYZE | PROC_VACUUM_FOR_WRAPAROUND)
64
64
 
65
+ /*
66
+ * Xmin-related flags. Make sure any flags that affect how the process' Xmin
67
+ * value is interpreted by VACUUM are included here.
68
+ */
69
+ #define PROC_XMIN_FLAGS (PROC_IN_VACUUM)
70
+
65
71
  /*
66
72
  * We allow a small number of "weak" relation locks (AccessShareLock,
67
73
  * RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure
@@ -76,6 +82,13 @@ struct XidCache
76
82
  */
77
83
  #define INVALID_PGPROCNO PG_INT32_MAX
78
84
 
85
+ /*
86
+ * Flags used only for type of internal functions
87
+ * GetVirtualXIDsDelayingChkptGuts and HaveVirtualXIDsDelayingChkptGuts.
88
+ */
89
+ #define DELAY_CHKPT_START (1<<0)
90
+ #define DELAY_CHKPT_COMPLETE (1<<1)
91
+
79
92
  /*
80
93
  * Each backend has a PGPROC struct in shared memory. There is also a list of
81
94
  * currently-unused PGPROC structs that will be reallocated to new backends.
@@ -143,6 +156,7 @@ struct PGPROC
143
156
  * lock object by this backend */
144
157
 
145
158
  bool delayChkpt; /* true if this proc delays checkpoint start */
159
+ bool delayChkptEnd; /* true if this proc delays checkpoint end */
146
160
 
147
161
  /*
148
162
  * Info to allow us to wait for synchronous replication, if needed.
@@ -314,6 +314,7 @@ tas(volatile slock_t *lock)
314
314
  #endif /* __INTEL_COMPILER */
315
315
  #endif /* __ia64__ || __ia64 */
316
316
 
317
+
317
318
  /*
318
319
  * On ARM and ARM64, we use __sync_lock_test_and_set(int *, int) if available.
319
320
  *
@@ -340,6 +341,29 @@ tas(volatile slock_t *lock)
340
341
  #endif /* __arm__ || __arm || __aarch64__ || __aarch64 */
341
342
 
342
343
 
344
+ /*
345
+ * RISC-V likewise uses __sync_lock_test_and_set(int *, int) if available.
346
+ */
347
+ #if defined(__riscv)
348
+ #ifdef HAVE_GCC__SYNC_INT32_TAS
349
+ #define HAS_TEST_AND_SET
350
+
351
+ #define TAS(lock) tas(lock)
352
+
353
+ typedef int slock_t;
354
+
355
+ static __inline__ int
356
+ tas(volatile slock_t *lock)
357
+ {
358
+ return __sync_lock_test_and_set(lock, 1);
359
+ }
360
+
361
+ #define S_UNLOCK(lock) __sync_lock_release(lock)
362
+
363
+ #endif /* HAVE_GCC__SYNC_INT32_TAS */
364
+ #endif /* __riscv */
365
+
366
+
343
367
  /* S/390 and S/390x Linux (32- and 64-bit zSeries) */
344
368
  #if defined(__s390__) || defined(__s390x__)
345
369
  #define HAS_TEST_AND_SET
@@ -17,6 +17,8 @@
17
17
  #include "nodes/parsenodes.h"
18
18
  #include "utils/portal.h"
19
19
 
20
+ struct PlannedStmt; /* avoid including plannodes.h here */
21
+
20
22
 
21
23
  extern PGDLLIMPORT Portal ActivePortal;
22
24
 
@@ -42,4 +44,8 @@ extern uint64 PortalRunFetch(Portal portal,
42
44
  long count,
43
45
  DestReceiver *dest);
44
46
 
47
+ extern bool PlannedStmtRequiresSnapshot(struct PlannedStmt *pstmt);
48
+
49
+ extern void EnsurePortalSnapshotExists(void);
50
+
45
51
  #endif /* PQUERY_H */
@@ -89,6 +89,7 @@ extern void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len);
89
89
 
90
90
  /* xid.c */
91
91
  extern int xidComparator(const void *arg1, const void *arg2);
92
+ extern int xidLogicalComparator(const void *arg1, const void *arg2);
92
93
 
93
94
  /* inet_cidr_ntop.c */
94
95
  extern char *pg_inet_cidr_ntop(int af, const void *src, int bits,
@@ -61,4 +61,5 @@ extern void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func,
61
61
  extern void CallSyscacheCallbacks(int cacheid, uint32 hashvalue);
62
62
 
63
63
  extern void InvalidateSystemCaches(void);
64
+ extern void InvalidateSystemCachesExtended(bool debug_discard);
64
65
  #endif /* INVAL_H */
@@ -194,6 +194,17 @@ typedef struct PortalData
194
194
  /* Presentation data, primarily used by the pg_cursors system view */
195
195
  TimestampTz creation_time; /* time at which this portal was defined */
196
196
  bool visible; /* include this portal in pg_cursors? */
197
+
198
+ /* Stuff added at the end to avoid ABI break in stable branches: */
199
+
200
+ /*
201
+ * Outermost ActiveSnapshot for execution of the portal's queries. For
202
+ * all but a few utility commands, we require such a snapshot to exist.
203
+ * This ensures that TOAST references in query results can be detoasted,
204
+ * and helps to reduce thrashing of the process's exposed xmin.
205
+ */
206
+ Snapshot portalSnapshot; /* active snapshot, or NULL if none */
207
+ int createLevel; /* creating subxact's nesting level */
197
208
  } PortalData;
198
209
 
199
210
  /*
@@ -211,6 +222,7 @@ extern void AtCleanup_Portals(void);
211
222
  extern void PortalErrorCleanup(void);
212
223
  extern void AtSubCommit_Portals(SubTransactionId mySubid,
213
224
  SubTransactionId parentSubid,
225
+ int parentLevel,
214
226
  ResourceOwner parentXactOwner);
215
227
  extern void AtSubAbort_Portals(SubTransactionId mySubid,
216
228
  SubTransactionId parentSubid,
@@ -237,5 +249,6 @@ extern void PortalCreateHoldStore(Portal portal);
237
249
  extern void PortalHashTableDeleteAll(void);
238
250
  extern bool ThereAreNoReadyPortals(void);
239
251
  extern void HoldPinnedPortals(void);
252
+ extern void ForgetPortalSnapshots(void);
240
253
 
241
254
  #endif /* PORTAL_H */
@@ -298,7 +298,6 @@ typedef struct StdRdOptions
298
298
  {
299
299
  int32 vl_len_; /* varlena header (do not touch directly!) */
300
300
  int fillfactor; /* page fill factor in percent (0..100) */
301
- /* fraction of newly inserted tuples prior to trigger index cleanup */
302
301
  int toast_tuple_target; /* target for tuple toasting */
303
302
  AutoVacOpts autovacuum; /* autovacuum-related options */
304
303
  bool user_catalog_table; /* use as an additional catalog relation */
@@ -14,7 +14,6 @@
14
14
  #ifndef RELCACHE_H
15
15
  #define RELCACHE_H
16
16
 
17
- #include "postgres.h"
18
17
  #include "access/tupdesc.h"
19
18
  #include "nodes/bitmapset.h"
20
19
 
@@ -121,7 +120,7 @@ extern void RelationForgetRelation(Oid rid);
121
120
 
122
121
  extern void RelationCacheInvalidateEntry(Oid relationId);
123
122
 
124
- extern void RelationCacheInvalidate(void);
123
+ extern void RelationCacheInvalidate(bool debug_discard);
125
124
 
126
125
  extern void RelationCloseSmgrByOid(Oid relationId);
127
126
 
@@ -110,6 +110,7 @@ extern void InvalidateCatalogSnapshot(void);
110
110
  extern void InvalidateCatalogSnapshotConditionally(void);
111
111
 
112
112
  extern void PushActiveSnapshot(Snapshot snapshot);
113
+ extern void PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level);
113
114
  extern void PushCopiedSnapshot(Snapshot snapshot);
114
115
  extern void UpdateActiveSnapshotCommandId(void);
115
116
  extern void PopActiveSnapshot(void);
@@ -20686,7 +20686,7 @@ const ProtobufCMessageDescriptor pg_query__alter_table_stmt__descriptor =
20686
20686
  (ProtobufCMessageInit) pg_query__alter_table_stmt__init,
20687
20687
  NULL,NULL,NULL /* reserved[123] */
20688
20688
  };
20689
- static const ProtobufCFieldDescriptor pg_query__alter_table_cmd__field_descriptors[7] =
20689
+ static const ProtobufCFieldDescriptor pg_query__alter_table_cmd__field_descriptors[8] =
20690
20690
  {
20691
20691
  {
20692
20692
  "subtype",
@@ -20772,6 +20772,18 @@ static const ProtobufCFieldDescriptor pg_query__alter_table_cmd__field_descripto
20772
20772
  0, /* flags */
20773
20773
  0,NULL,NULL /* reserved1,reserved2, etc */
20774
20774
  },
20775
+ {
20776
+ "recurse",
20777
+ 8,
20778
+ PROTOBUF_C_LABEL_NONE,
20779
+ PROTOBUF_C_TYPE_BOOL,
20780
+ 0, /* quantifier_offset */
20781
+ offsetof(PgQuery__AlterTableCmd, recurse),
20782
+ NULL,
20783
+ NULL,
20784
+ 0, /* flags */
20785
+ 0,NULL,NULL /* reserved1,reserved2, etc */
20786
+ },
20775
20787
  };
20776
20788
  static const unsigned pg_query__alter_table_cmd__field_indices_by_name[] = {
20777
20789
  5, /* field[5] = behavior */
@@ -20780,12 +20792,13 @@ static const unsigned pg_query__alter_table_cmd__field_indices_by_name[] = {
20780
20792
  1, /* field[1] = name */
20781
20793
  3, /* field[3] = newowner */
20782
20794
  2, /* field[2] = num */
20795
+ 7, /* field[7] = recurse */
20783
20796
  0, /* field[0] = subtype */
20784
20797
  };
20785
20798
  static const ProtobufCIntRange pg_query__alter_table_cmd__number_ranges[1 + 1] =
20786
20799
  {
20787
20800
  { 1, 0 },
20788
- { 0, 7 }
20801
+ { 0, 8 }
20789
20802
  };
20790
20803
  const ProtobufCMessageDescriptor pg_query__alter_table_cmd__descriptor =
20791
20804
  {
@@ -20795,7 +20808,7 @@ const ProtobufCMessageDescriptor pg_query__alter_table_cmd__descriptor =
20795
20808
  "PgQuery__AlterTableCmd",
20796
20809
  "pg_query",
20797
20810
  sizeof(PgQuery__AlterTableCmd),
20798
- 7,
20811
+ 8,
20799
20812
  pg_query__alter_table_cmd__field_descriptors,
20800
20813
  pg_query__alter_table_cmd__field_indices_by_name,
20801
20814
  1, pg_query__alter_table_cmd__number_ranges,
@@ -36975,7 +36988,7 @@ static const ProtobufCEnumValue pg_query__token__enum_values_by_number[494] =
36975
36988
  { "REASSIGN", "PG_QUERY__TOKEN__REASSIGN", 579 },
36976
36989
  { "RECHECK", "PG_QUERY__TOKEN__RECHECK", 580 },
36977
36990
  { "RECURSIVE", "PG_QUERY__TOKEN__RECURSIVE", 581 },
36978
- { "REF", "PG_QUERY__TOKEN__REF", 582 },
36991
+ { "REF_P", "PG_QUERY__TOKEN__REF_P", 582 },
36979
36992
  { "REFERENCES", "PG_QUERY__TOKEN__REFERENCES", 583 },
36980
36993
  { "REFERENCING", "PG_QUERY__TOKEN__REFERENCING", 584 },
36981
36994
  { "REFRESH", "PG_QUERY__TOKEN__REFRESH", 585 },
@@ -37472,10 +37485,10 @@ static const ProtobufCEnumValueIndex pg_query__token__enum_values_by_name[494] =
37472
37485
  { "REASSIGN", 341 },
37473
37486
  { "RECHECK", 342 },
37474
37487
  { "RECURSIVE", 343 },
37475
- { "REF", 344 },
37476
37488
  { "REFERENCES", 345 },
37477
37489
  { "REFERENCING", 346 },
37478
37490
  { "REFRESH", 347 },
37491
+ { "REF_P", 344 },
37479
37492
  { "REINDEX", 348 },
37480
37493
  { "RELATIVE_P", 349 },
37481
37494
  { "RELEASE", 350 },
@@ -321,8 +321,7 @@ static void deparseExpr(StringInfo str, Node *node)
321
321
  deparseGroupingFunc(str, castNode(GroupingFunc, node));
322
322
  break;
323
323
  default:
324
- Assert(false);
325
- elog(ERROR, "unpermitted node type in a_expr/b_expr: %d",
324
+ elog(ERROR, "deparse: unpermitted node type in a_expr/b_expr: %d",
326
325
  (int) nodeTag(node));
327
326
  break;
328
327
  }
@@ -372,8 +371,7 @@ static void deparseCExpr(StringInfo str, Node *node)
372
371
  deparseGroupingFunc(str, castNode(GroupingFunc, node));
373
372
  break;
374
373
  default:
375
- Assert(false);
376
- elog(ERROR, "unpermitted node type in c_expr: %d",
374
+ elog(ERROR, "deparse: unpermitted node type in c_expr: %d",
377
375
  (int) nodeTag(node));
378
376
  break;
379
377
  }
@@ -1416,7 +1414,7 @@ static void deparseTargetList(StringInfo str, List *l)
1416
1414
  ResTarget *res_target = castNode(ResTarget, lfirst(lc));
1417
1415
 
1418
1416
  if (res_target->val == NULL)
1419
- elog(ERROR, "deparse error in deparseTargetList: ResTarget without val");
1417
+ elog(ERROR, "deparse: error in deparseTargetList: ResTarget without val");
1420
1418
  else if (IsA(res_target->val, ColumnRef))
1421
1419
  deparseColumnRef(str, castNode(ColumnRef, res_target->val));
1422
1420
  else
@@ -2276,6 +2274,9 @@ static void deparseRangeVar(StringInfo str, RangeVar *range_var, DeparseNodeCont
2276
2274
 
2277
2275
  static void deparseRawStmt(StringInfo str, RawStmt *raw_stmt)
2278
2276
  {
2277
+ if (raw_stmt->stmt == NULL)
2278
+ elog(ERROR, "deparse error in deparseRawStmt: RawStmt with empty Stmt");
2279
+
2279
2280
  deparseStmt(str, raw_stmt->stmt);
2280
2281
  }
2281
2282
 
@@ -9427,7 +9428,7 @@ static void deparseValue(StringInfo str, Value *value, DeparseNodeContext contex
9427
9428
  appendStringInfoString(str, "NULL");
9428
9429
  break;
9429
9430
  default:
9430
- elog(ERROR, "unrecognized value node type: %d",
9431
+ elog(ERROR, "deparse: unrecognized value node type: %d",
9431
9432
  (int) nodeTag(value));
9432
9433
  break;
9433
9434
  }
@@ -9900,8 +9901,7 @@ static void deparseStmt(StringInfo str, Node *node)
9900
9901
  deparseCreateRangeStmt(str, castNode(CreateRangeStmt, node));
9901
9902
  break;
9902
9903
  default:
9903
- // No other node types are supported at the top-level
9904
- Assert(false);
9904
+ elog(ERROR, "deparse: unsupported top-level node type: %u", nodeTag(node));
9905
9905
  }
9906
9906
  }
9907
9907
 
@@ -374,6 +374,7 @@ void pg_query_free_fingerprint_result(PgQueryFingerprintResult result)
374
374
  if (result.error) {
375
375
  free(result.error->message);
376
376
  free(result.error->filename);
377
+ free(result.error->funcname);
377
378
  free(result.error);
378
379
  }
379
380
 
@@ -117,6 +117,7 @@ static void dump_return_next(StringInfo out, PLpgSQL_stmt_return_next *stmt);
117
117
  static void dump_return_query(StringInfo out, PLpgSQL_stmt_return_query *stmt);
118
118
  static void dump_raise(StringInfo out, PLpgSQL_stmt_raise *stmt);
119
119
  static void dump_raise_option(StringInfo out, PLpgSQL_raise_option *node);
120
+ static void dump_assert(StringInfo out, PLpgSQL_stmt_assert *stmt);
120
121
  static void dump_execsql(StringInfo out, PLpgSQL_stmt_execsql *stmt);
121
122
  static void dump_dynexecute(StringInfo out, PLpgSQL_stmt_dynexecute *stmt);
122
123
  static void dump_dynfors(StringInfo out, PLpgSQL_stmt_dynfors *stmt);
@@ -126,6 +127,10 @@ static void dump_open(StringInfo out, PLpgSQL_stmt_open *stmt);
126
127
  static void dump_fetch(StringInfo out, PLpgSQL_stmt_fetch *stmt);
127
128
  static void dump_close(StringInfo out, PLpgSQL_stmt_close *stmt);
128
129
  static void dump_perform(StringInfo out, PLpgSQL_stmt_perform *stmt);
130
+ static void dump_call(StringInfo out, PLpgSQL_stmt_call *stmt);
131
+ static void dump_commit(StringInfo out, PLpgSQL_stmt_commit *stmt);
132
+ static void dump_rollback(StringInfo out, PLpgSQL_stmt_rollback *stmt);
133
+ static void dump_set(StringInfo out, PLpgSQL_stmt_set *stmt);
129
134
  static void dump_expr(StringInfo out, PLpgSQL_expr *expr);
130
135
  static void dump_function(StringInfo out, PLpgSQL_function *func);
131
136
  static void dump_exception(StringInfo out, PLpgSQL_exception *node);
@@ -183,6 +188,9 @@ dump_stmt(StringInfo out, PLpgSQL_stmt *node)
183
188
  case PLPGSQL_STMT_RAISE:
184
189
  dump_raise(out, (PLpgSQL_stmt_raise *) node);
185
190
  break;
191
+ case PLPGSQL_STMT_ASSERT:
192
+ dump_assert(out, (PLpgSQL_stmt_assert *) node);
193
+ break;
186
194
  case PLPGSQL_STMT_EXECSQL:
187
195
  dump_execsql(out, (PLpgSQL_stmt_execsql *) node);
188
196
  break;
@@ -207,6 +215,18 @@ dump_stmt(StringInfo out, PLpgSQL_stmt *node)
207
215
  case PLPGSQL_STMT_PERFORM:
208
216
  dump_perform(out, (PLpgSQL_stmt_perform *) node);
209
217
  break;
218
+ case PLPGSQL_STMT_CALL:
219
+ dump_call(out, (PLpgSQL_stmt_call *) node);
220
+ break;
221
+ case PLPGSQL_STMT_COMMIT:
222
+ dump_commit(out, (PLpgSQL_stmt_commit *) node);
223
+ break;
224
+ case PLPGSQL_STMT_ROLLBACK:
225
+ dump_rollback(out, (PLpgSQL_stmt_rollback *) node);
226
+ break;
227
+ case PLPGSQL_STMT_SET:
228
+ dump_set(out, (PLpgSQL_stmt_set *) node);
229
+ break;
210
230
  default:
211
231
  elog(ERROR, "unrecognized cmd_type: %d", node->cmd_type);
212
232
  break;
@@ -444,6 +464,44 @@ dump_perform(StringInfo out, PLpgSQL_stmt_perform *node)
444
464
  WRITE_EXPR_FIELD(expr);
445
465
  }
446
466
 
467
+ static void
468
+ dump_call(StringInfo out, PLpgSQL_stmt_call *node)
469
+ {
470
+ WRITE_NODE_TYPE("PLpgSQL_stmt_call");
471
+
472
+ WRITE_INT_FIELD(lineno, lineno, lineno);
473
+ WRITE_EXPR_FIELD(expr);
474
+ WRITE_BOOL_FIELD(is_call, is_call, is_call);
475
+ WRITE_VARIABLE_FIELD(target);
476
+ }
477
+
478
+ static void
479
+ dump_commit(StringInfo out, PLpgSQL_stmt_commit *node)
480
+ {
481
+ WRITE_NODE_TYPE("PLpgSQL_stmt_commit");
482
+
483
+ WRITE_INT_FIELD(lineno, lineno, lineno);
484
+ WRITE_BOOL_FIELD(chain, chain, chain);
485
+ }
486
+
487
+ static void
488
+ dump_rollback(StringInfo out, PLpgSQL_stmt_rollback *node)
489
+ {
490
+ WRITE_NODE_TYPE("PLpgSQL_stmt_rollback");
491
+
492
+ WRITE_INT_FIELD(lineno, lineno, lineno);
493
+ WRITE_BOOL_FIELD(chain, chain, chain);
494
+ }
495
+
496
+ static void
497
+ dump_set(StringInfo out, PLpgSQL_stmt_set *node)
498
+ {
499
+ WRITE_NODE_TYPE("PLpgSQL_stmt_set");
500
+
501
+ WRITE_INT_FIELD(lineno, lineno, lineno);
502
+ WRITE_EXPR_FIELD(expr);
503
+ }
504
+
447
505
  static void
448
506
  dump_exit(StringInfo out, PLpgSQL_stmt_exit *node)
449
507
  {
@@ -508,6 +566,16 @@ dump_raise_option(StringInfo out, PLpgSQL_raise_option *node)
508
566
  WRITE_EXPR_FIELD(expr);
509
567
  }
510
568
 
569
+ static void
570
+ dump_assert(StringInfo out, PLpgSQL_stmt_assert *node)
571
+ {
572
+ WRITE_NODE_TYPE("PLpgSQL_stmt_assert");
573
+
574
+ WRITE_INT_FIELD(lineno, lineno, lineno);
575
+ WRITE_EXPR_FIELD(cond);
576
+ WRITE_EXPR_FIELD(message);
577
+ }
578
+
511
579
  static void
512
580
  dump_execsql(StringInfo out, PLpgSQL_stmt_execsql *node)
513
581
  {