pg_query 2.1.4 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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
  {