pg_query 2.1.4 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +32 -0
- data/Rakefile +2 -2
- data/ext/pg_query/include/access/twophase.h +2 -0
- data/ext/pg_query/include/access/xact.h +6 -0
- data/ext/pg_query/include/access/xlog_internal.h +10 -1
- data/ext/pg_query/include/access/xlogreader.h +10 -0
- data/ext/pg_query/include/catalog/dependency.h +2 -0
- data/ext/pg_query/include/catalog/pg_class.h +1 -1
- data/ext/pg_query/include/catalog/pg_class_d.h +1 -1
- data/ext/pg_query/include/catalog/pg_control.h +2 -0
- data/ext/pg_query/include/catalog/pg_operator.h +3 -1
- data/ext/pg_query/include/catalog/pg_publication.h +3 -0
- data/ext/pg_query/include/catalog/pg_type.h +1 -0
- data/ext/pg_query/include/commands/async.h +1 -1
- data/ext/pg_query/include/commands/tablespace.h +2 -0
- data/ext/pg_query/include/commands/trigger.h +8 -0
- data/ext/pg_query/include/lib/simplehash.h +13 -13
- data/ext/pg_query/include/libpq/libpq.h +1 -0
- data/ext/pg_query/include/mb/pg_wchar.h +1 -0
- data/ext/pg_query/include/miscadmin.h +24 -11
- data/ext/pg_query/include/nodes/execnodes.h +2 -2
- data/ext/pg_query/include/nodes/parsenodes.h +5 -4
- data/ext/pg_query/include/nodes/pathnodes.h +2 -1
- data/ext/pg_query/include/nodes/pg_list.h +1 -0
- data/ext/pg_query/include/nodes/plannodes.h +18 -3
- data/ext/pg_query/include/optimizer/optimizer.h +0 -5
- data/ext/pg_query/include/parser/gram.h +2 -2
- data/ext/pg_query/include/parser/kwlist.h +1 -1
- data/ext/pg_query/include/parser/parse_coerce.h +1 -0
- data/ext/pg_query/include/pg_config.h +16 -13
- data/ext/pg_query/include/pg_query.h +2 -2
- data/ext/pg_query/include/pg_query_fingerprint_defs.c +286 -314
- data/ext/pg_query/include/pg_query_outfuncs_defs.c +1 -0
- data/ext/pg_query/include/pg_query_readfuncs_defs.c +1 -0
- data/ext/pg_query/include/pgstat.h +2 -1
- data/ext/pg_query/include/plpgsql.h +2 -2
- data/ext/pg_query/include/port/pg_bitutils.h +48 -2
- data/ext/pg_query/include/port.h +4 -0
- data/ext/pg_query/include/protobuf/pg_query.pb-c.h +4 -3
- data/ext/pg_query/include/replication/reorderbuffer.h +6 -5
- data/ext/pg_query/include/replication/slot.h +1 -1
- data/ext/pg_query/include/storage/block.h +1 -1
- data/ext/pg_query/include/storage/lock.h +6 -5
- data/ext/pg_query/include/storage/lwlock.h +1 -0
- data/ext/pg_query/include/storage/proc.h +14 -0
- data/ext/pg_query/include/storage/s_lock.h +24 -0
- data/ext/pg_query/include/tcop/pquery.h +6 -0
- data/ext/pg_query/include/utils/builtins.h +1 -0
- data/ext/pg_query/include/utils/inval.h +1 -0
- data/ext/pg_query/include/utils/portal.h +13 -0
- data/ext/pg_query/include/utils/rel.h +0 -1
- data/ext/pg_query/include/utils/relcache.h +1 -2
- data/ext/pg_query/include/utils/snapmgr.h +1 -0
- data/ext/pg_query/pg_query.pb-c.c +18 -5
- data/ext/pg_query/pg_query_deparse.c +8 -8
- data/ext/pg_query/pg_query_fingerprint.c +1 -0
- data/ext/pg_query/pg_query_json_plpgsql.c +68 -0
- data/ext/pg_query/pg_query_normalize.c +43 -7
- data/ext/pg_query/pg_query_outfuncs.h +1 -0
- data/ext/pg_query/pg_query_outfuncs_json.c +11 -0
- data/ext/pg_query/pg_query_parse_plpgsql.c +58 -15
- data/ext/pg_query/src_backend_catalog_namespace.c +1 -0
- data/ext/pg_query/src_backend_libpq_pqcomm.c +8 -0
- data/ext/pg_query/src_backend_nodes_copyfuncs.c +23 -33
- data/ext/pg_query/src_backend_nodes_equalfuncs.c +1 -0
- data/ext/pg_query/src_backend_nodes_list.c +12 -0
- data/ext/pg_query/src_backend_parser_gram.c +18 -3
- data/ext/pg_query/src_backend_parser_scan.c +493 -253
- data/ext/pg_query/src_backend_tcop_postgres.c +11 -1
- data/ext/pg_query/src_backend_utils_adt_ruleutils.c +38 -10
- data/ext/pg_query/src_backend_utils_misc_guc.c +1 -0
- data/ext/pg_query/src_common_wchar.c +11 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +4 -2
- data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1 -1
- data/ext/pg_query/src_port_pg_bitutils.c +1 -22
- data/ext/pg_query/src_port_snprintf.c +9 -7
- data/lib/pg_query/deparse.rb +7 -1
- data/lib/pg_query/fingerprint.rb +13 -2
- data/lib/pg_query/parse.rb +5 -3
- data/lib/pg_query/pg_query_pb.rb +2 -1
- data/lib/pg_query/treewalker.rb +6 -0
- data/lib/pg_query/version.rb +1 -1
- 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?
|
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
|
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
|
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))
|
data/ext/pg_query/include/port.h
CHANGED
@@ -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
|
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
|
-
|
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
|
50
|
-
* "speculative insertions",
|
51
|
-
* used by INSERT .. ON CONFLICT .. UPDATE. Users of
|
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
|
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) (
|
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
|
51
|
-
*
|
52
|
-
*
|
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
|
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(
|
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[
|
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,
|
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
|
-
|
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
|
-
{ "
|
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
|
-
|
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
|
-
|
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
|
-
|
9904
|
-
Assert(false);
|
9904
|
+
elog(ERROR, "deparse: unsupported top-level node type: %u", nodeTag(node));
|
9905
9905
|
}
|
9906
9906
|
}
|
9907
9907
|
|
@@ -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
|
{
|