44#include "catalog/pg_database_d.h"
63 bool all_visible_cleared,
bool new_all_visible_cleared);
64#ifdef USE_ASSERT_CHECKING
65static void check_lock_if_inplace_updateable_rel(
Relation relation,
68static void check_inplace_rel_lock(
HeapTuple oldtup);
77 bool *have_tuple_lock);
105 bool logLockFailure);
157#define LOCKMODE_from_mxstatus(status) \
158 (tupleLockExtraInfo[TUPLOCK_from_mxstatus((status))].hwlock)
165#define LockTupleTuplock(rel, tup, mode) \
166 LockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock)
167#define UnlockTupleTuplock(rel, tup, mode) \
168 UnlockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock)
169#define ConditionalLockTupleTuplock(rel, tup, mode, log) \
170 ConditionalLockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock, (log))
183} IndexDeletePrefetchState;
187#define BOTTOMUP_MAX_NBLOCKS 6
188#define BOTTOMUP_TOLERANCE_NBLOCKS 3
216#define TUPLOCK_from_mxstatus(status) \
217 (MultiXactStatusLock[(status)])
225#ifdef USE_ASSERT_CHECKING
251 void *callback_private_data,
252 void *per_buffer_data)
291 void *callback_private_data,
292 void *per_buffer_data)
316 void *per_buffer_data)
399 allow_strat = allow_sync =
false;
429 if (!keep_startblock)
507 Assert(startBlk == 0 || startBlk < scan->rs_nblocks);
523 bool all_visible,
bool check_serializable)
547 if (check_serializable)
549 &loctup, buffer, snapshot);
579 bool check_serializable;
634 if (
likely(!check_serializable))
636 block, lines,
true,
false);
639 block, lines,
true,
true);
643 if (
likely(!check_serializable))
645 block, lines,
false,
false);
648 block, lines,
false,
true);
808 *linesleft = *lineoff;
957 for (; linesleft > 0; linesleft--, lineoff += dir)
1066 linesleft = scan->rs_ntuples;
1075 for (; linesleft > 0; linesleft--, lineindex += dir)
1080 Assert(lineindex < scan->rs_ntuples);
1081 lineoff = scan->rs_vistuples[lineindex];
1095 scan->rs_cindex = lineindex;
1170 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
1171 errmsg(
"cannot query non-catalog table \"%s\" during logical decoding",
1206 if (parallel_scan != NULL)
1273 bool allow_strat,
bool allow_sync,
bool allow_pagemode)
1377 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1388 elog(
ERROR,
"unexpected heap_getnext call during logical decoding");
1745 bool *all_dead,
bool first_call)
1751 bool at_chain_start;
1758 *all_dead = first_call;
1762 at_chain_start = first_call;
1788 at_chain_start =
false;
1855 if (all_dead && *all_dead)
1873 at_chain_start =
false;
2113 bool all_visible_cleared =
false;
2163 all_visible_cleared =
true;
2214 if (all_visible_cleared)
2308 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2309 errmsg(
"cannot insert tuples in a parallel worker")));
2326 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
2327 relation->
rd_rel->relkind != RELKIND_MATVIEW)
2350 for (
int i = done;
i < ntuples;
i++)
2354 if (page_avail < tup_sz)
2359 page_avail -= tup_sz;
2391 bool starting_with_empty_page =
false;
2393 int npages_used = 0;
2406 for (
i = 0;
i < ntuples;
i++)
2443 while (ndone < ntuples)
2446 bool all_visible_cleared =
false;
2447 bool all_frozen_set =
false;
2462 if (ndone == 0 || !starting_with_empty_page)
2481 npages - npages_used);
2488 all_frozen_set =
true;
2506 if (needwal && need_cids)
2509 for (nthispage = 1; ndone + nthispage < ntuples; nthispage++)
2511 HeapTuple heaptup = heaptuples[ndone + nthispage];
2522 if (needwal && need_cids)
2536 all_visible_cleared =
true;
2542 else if (all_frozen_set)
2566 char *scratchptr = scratch.
data;
2574 init = starting_with_empty_page;
2590 tupledata = scratchptr;
2593 Assert(!(all_visible_cleared && all_frozen_set));
2596 if (all_visible_cleared)
2613 for (
i = 0;
i < nthispage;
i++)
2635 scratchptr += datalen;
2637 totaldatalen = scratchptr - tupledata;
2638 Assert((scratchptr - scratch.
data) < BLCKSZ);
2640 if (need_tuple_data)
2648 if (ndone + nthispage == ntuples)
2661 if (need_tuple_data)
2728 for (
i = 0;
i < ntuples;
i++)
2733 for (
i = 0;
i < ntuples;
i++)
2734 slots[
i]->tts_tid = heaptuples[
i]->t_self;
2786 const uint16 interesting =
2789 if ((new_infomask & interesting) != (old_infomask & interesting))
2822 bool have_tuple_lock =
false;
2824 bool all_visible_cleared =
false;
2826 bool old_key_copied =
false;
2839 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2840 errmsg(
"cannot delete tuples during a parallel operation")));
2886 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2887 errmsg(
"attempted to delete invisible tuple")));
2913 bool current_is_member =
false;
2924 if (!current_is_member)
3004 if (result !=
TM_Ok)
3022 if (result !=
TM_Ok)
3031 if (have_tuple_lock)
3071 &new_xmax, &new_infomask, &new_infomask2);
3086 all_visible_cleared =
true;
3129 if (all_visible_cleared)
3136 xlrec.
xmax = new_xmax;
3138 if (old_key_tuple != NULL)
3140 if (relation->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
3154 if (old_key_tuple != NULL)
3163 old_key_tuple->
t_len
3188 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3189 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3210 if (have_tuple_lock)
3215 if (old_key_tuple != NULL && old_key_copied)
3243 elog(
ERROR,
"tuple already updated by self");
3251 elog(
ERROR,
"tuple concurrently updated");
3255 elog(
ERROR,
"tuple concurrently deleted");
3259 elog(
ERROR,
"unrecognized heap_delete status: %u", result);
3293 bool old_key_copied =
false;
3304 bool have_tuple_lock =
false;
3306 bool use_hot_update =
false;
3307 bool summarized_update =
false;
3309 bool all_visible_cleared =
false;
3310 bool all_visible_cleared_new =
false;
3311 bool checked_lockers;
3312 bool locker_remains;
3313 bool id_has_external =
false;
3316 uint16 infomask_old_tuple,
3317 infomask2_old_tuple,
3319 infomask2_new_tuple;
3336 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3337 errmsg(
"cannot update tuples during a parallel operation")));
3339#ifdef USE_ASSERT_CHECKING
3340 check_lock_if_inplace_updateable_rel(relation, otid, newtup);
3366 interesting_attrs = NULL;
3418 Assert(!have_tuple_lock);
3457 newtup, &id_has_external);
3502 checked_lockers =
false;
3503 locker_remains =
false;
3513 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3514 errmsg(
"attempted to update invisible tuple")));
3520 bool can_continue =
false;
3565 bool current_is_member =
false;
3568 *lockmode, ¤t_is_member))
3576 if (!current_is_member)
3584 checked_lockers =
true;
3585 locker_remains = remain != 0;
3632 can_continue =
true;
3640 checked_lockers =
true;
3641 locker_remains =
true;
3642 can_continue =
true;
3651 checked_lockers =
true;
3652 locker_remains =
true;
3653 can_continue =
true;
3666 checked_lockers =
true;
3682 can_continue =
true;
3694 if (result !=
TM_Ok)
3712 if (result !=
TM_Ok)
3721 if (have_tuple_lock)
3762 xid, *lockmode,
true,
3763 &xmax_old_tuple, &infomask_old_tuple,
3764 &infomask2_old_tuple);
3775 (checked_lockers && !locker_remains))
3783 infomask2_new_tuple = 0;
3796 &infomask2_new_tuple);
3801 infomask2_new_tuple = 0;
3834 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3835 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3851 if (need_toast || newtupsize > pagefree)
3854 uint16 infomask_lock_old_tuple,
3855 infomask2_lock_old_tuple;
3856 bool cleared_all_frozen =
false;
3879 xid, *lockmode,
false,
3880 &xmax_lock_old_tuple, &infomask_lock_old_tuple,
3881 &infomask2_lock_old_tuple);
3910 cleared_all_frozen =
true;
3923 xlrec.
xmax = xmax_lock_old_tuple;
3978 if (newtupsize > pagefree)
3983 &vmbuffer_new, &vmbuffer,
3995 if (newtupsize > pagefree ||
4043 if (newbuf == buffer)
4052 use_hot_update =
true;
4062 summarized_update =
true;
4136 all_visible_cleared =
true;
4143 all_visible_cleared_new =
true;
4149 if (newbuf != buffer)
4169 newbuf, &oldtup, heaptup,
4171 all_visible_cleared,
4172 all_visible_cleared_new);
4173 if (newbuf != buffer)
4182 if (newbuf != buffer)
4197 if (newbuf != buffer)
4208 if (have_tuple_lock)
4217 if (heaptup != newtup)
4231 if (summarized_update)
4237 *update_indexes =
TU_All;
4239 if (old_key_tuple != NULL && old_key_copied)
4252#ifdef USE_ASSERT_CHECKING
4258check_lock_if_inplace_updateable_rel(
Relation relation,
4265 case RelationRelationId:
4266 case DatabaseRelationId:
4286 case RelationRelationId:
4290 Oid relid = classForm->oid;
4299 if (classForm->relkind == RELKIND_INDEX)
4312 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4320 case DatabaseRelationId:
4326 "missing lock on database \"%s\" (OID %u) @ TID (%u,%u)",
4344 Oid relid = classForm->oid;
4353 if (classForm->relkind == RELKIND_INDEX)
4365 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4380 bool isnull1,
bool isnull2)
4386 if (isnull1 != isnull2)
4413 Assert(attrnum <= tupdesc->natts);
4481 value1 =
heap_getattr(oldtup, attrnum, tupdesc, &isnull1);
4482 value2 =
heap_getattr(newtup, attrnum, tupdesc, &isnull2);
4485 value2, isnull1, isnull2))
4495 if (attrnum < 0 || isnull1 ||
4505 *has_external =
true;
4530 &tmfd, &lockmode, update_indexes);
4535 elog(
ERROR,
"tuple already updated by self");
4543 elog(
ERROR,
"tuple concurrently updated");
4547 elog(
ERROR,
"tuple concurrently deleted");
4551 elog(
ERROR,
"unrecognized heap_update status: %u", result);
4572 is_update ?
"true" :
"false");
4610 bool follow_updates,
4624 bool first_time =
true;
4625 bool skip_tuple_lock =
false;
4626 bool have_tuple_lock =
false;
4627 bool cleared_all_frozen =
false;
4714 for (
i = 0;
i < nmembers;
i++)
4739 skip_tuple_lock =
true;
4788 require_sleep =
true;
4822 if (follow_updates && updated &&
4828 infomask, xwait, &t_ctid,
4855 require_sleep =
false;
4884 require_sleep =
false;
4910 require_sleep =
false;
4923 require_sleep =
false;
4949 require_sleep =
false;
4968 else if (require_sleep)
4980 if (!skip_tuple_lock &&
5000 elog(
ERROR,
"invalid lock mode in heap_lock_tuple");
5003 switch (wait_policy)
5011 status, infomask, relation,
5022 status, infomask, relation,
5025 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5026 errmsg(
"could not obtain lock on row in relation \"%s\"",
5045 switch (wait_policy)
5063 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5064 errmsg(
"could not obtain lock on row in relation \"%s\"",
5077 infomask, xwait, &t_ctid,
5122 if (!require_sleep ||
5134 if (result !=
TM_Ok)
5196 &xid, &new_infomask, &new_infomask2);
5232 cleared_all_frozen =
true;
5291 if (have_tuple_lock)
5313 if (*have_tuple_lock)
5316 switch (wait_policy)
5330 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5331 errmsg(
"could not obtain lock on row in relation \"%s\"",
5335 *have_tuple_lock =
true;
5363 uint16 *result_infomask2)
5386 new_xmax = add_to_xmax;
5396 new_xmax = add_to_xmax;
5400 new_xmax = add_to_xmax;
5404 new_xmax = add_to_xmax;
5408 new_xmax = add_to_xmax;
5437 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5464 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5532 elog(
WARNING,
"LOCK_ONLY found for Xid in progress %u", xmax);
5534 old_infomask &= ~HEAP_XMAX_LOCK_ONLY;
5554 if (xmax == add_to_xmax)
5568 if (
mode < old_mode)
5579 add_to_xmax, new_status);
5619 *result_infomask = new_infomask;
5620 *result_infomask2 = new_infomask2;
5621 *result_xmax = new_xmax;
5745 bool cleared_all_frozen =
false;
5746 bool pinned_desired_page;
5784 pinned_desired_page =
true;
5787 pinned_desired_page =
false;
5867 for (
i = 0;
i < nmembers;
i++)
5900 if (result !=
TM_Ok)
5937 elog(
ERROR,
"invalid lock status in tuple");
5971 if (result !=
TM_Ok)
5981 &new_xmax, &new_infomask, &new_infomask2);
5986 cleared_all_frozen =
true;
6010 xlrec.
xmax = new_xmax;
6255 elog(
ERROR,
"attempted to kill a tuple inserted by another transaction");
6257 elog(
ERROR,
"attempted to kill a non-speculative tuple");
6284 prune_xid = relfrozenxid;
6403 void (*release_callback) (
void *),
void *
arg)
6409#ifdef USE_ASSERT_CHECKING
6411 check_inplace_rel_lock(oldtup_ptr);
6448 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6460 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6461 errmsg(
"tuple to be updated was already modified by an operation triggered by the current command")));
6481 release_callback(
arg);
6497 release_callback(
arg);
6505 ret = (result ==
TM_Ok);
6509 release_callback(
arg);
6550 bool RelcacheInitFileInval =
false;
6558 dst = (
char *) htup + htup->
t_hoff;
6564 &RelcacheInitFileInval);
6620 uintptr_t dst_offset_in_block;
6630 xlrec.
nmsgs = nmsgs;
6639 memcpy(copied_buffer.
data, origdata,
lower);
6641 dst_offset_in_block = dst - origdata;
6642 memcpy(copied_buffer.
data + dst_offset_in_block, src, newlen);
6656 memcpy(dst, src, newlen);
6696#define FRM_NOOP 0x0001
6697#define FRM_INVALIDATE_XMAX 0x0002
6698#define FRM_RETURN_IS_XID 0x0004
6699#define FRM_RETURN_IS_MULTI 0x0008
6700#define FRM_MARK_COMMITTED 0x0010
6761 bool update_committed;
6795 errmsg_internal(
"multixact %u from before multi freeze cutoff %u found to be still running",
6810 errmsg_internal(
"multixact %u contains update XID %u from before relfrozenxid %u",
6823 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
6871 need_replace =
false;
6873 for (
int i = 0;
i < nmembers;
i++)
6882 need_replace =
true;
6886 FreezePageRelfrozenXid = xid;
6918 has_lockers =
false;
6920 update_committed =
false;
6925 for (
int i = 0;
i < nmembers;
i++)
6944 errmsg_internal(
"multixact %u contains running locker XID %u from before removable cutoff %u",
6947 newmembers[nnewmembers++] = members[
i];
6988 update_committed =
true;
7007 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
7009 newmembers[nnewmembers++] = members[
i];
7018 if (nnewmembers == 0)
7033 Assert(nnewmembers == 1);
7035 if (update_committed)
7037 newxmax = update_xid;
7104 bool xmin_already_frozen =
false,
7105 xmax_already_frozen =
false;
7106 bool freeze_xmin =
false,
7107 replace_xvac =
false,
7108 replace_xmax =
false,
7109 freeze_xmax =
false;
7125 xmin_already_frozen =
true;
7218 frz->
xmax = newxmax;
7221 replace_xmax =
true;
7245 frz->
xmax = newxmax;
7246 replace_xmax =
true;
7288 xmax_already_frozen =
true;
7293 errmsg_internal(
"found raw xmax %u (infomask 0x%04x) not invalid and not multi",
7298 Assert(!xmin_already_frozen);
7317 Assert(!xmax_already_frozen && !freeze_xmax);
7324 Assert(!xmax_already_frozen && !replace_xmax);
7343 *totally_frozen = ((freeze_xmin || xmin_already_frozen) &&
7344 (freeze_xmax || xmax_already_frozen));
7347 xmax_already_frozen))
7360 return freeze_xmin || replace_xvac || replace_xmax || freeze_xmax;
7377 for (
int i = 0;
i < ntuples;
i++)
7429 for (
int i = 0;
i < ntuples;
i++)
7453 bool totally_frozen;
7464 pagefrz.freeze_required =
true;
7471 &pagefrz, &frz, &totally_frozen);
7499 bool has_update =
false;
7508 for (
i = 0;
i < nmembers;
i++)
7517 if (
mode > strongest)
7521 switch (members[
i].status)
7557 *new_infomask = bits;
7558 *new_infomask2 = bits2;
7591 for (
i = 0;
i < nmembers;
i++)
7599 update_xact = members[
i].
xid;
7600#ifndef USE_ASSERT_CHECKING
7645 bool result =
false;
7657 for (
i = 0;
i < nmembers;
i++)
7662 if (result && (current_is_member == NULL || *current_is_member))
7668 memxid = members[
i].
xid;
7671 if (current_is_member != NULL)
7672 *current_is_member =
true;
7741 uint16 infomask,
bool nowait,
7759 for (
i = 0;
i < nmembers;
i++)
7842 bool logLockFailure)
7917 bool freeze =
false;
7925 *NoFreezePageRelfrozenXid = xid;
7943 *NoFreezePageRelfrozenXid = xid;
7955 *NoFreezePageRelminMxid = multi;
7967 *NoFreezePageRelminMxid = multi;
7975 for (
int i = 0;
i < nmembers;
i++)
7977 xid = members[
i].
xid;
7980 *NoFreezePageRelfrozenXid = xid;
7995 *NoFreezePageRelfrozenXid = xid;
8028 *snapshotConflictHorizon = xvac;
8042 *snapshotConflictHorizon = xmax;
8058index_delete_prefetch_buffer(
Relation rel,
8059 IndexDeletePrefetchState *prefetch_state,
8062 BlockNumber cur_hblkno = prefetch_state->cur_hblkno;
8065 int ndeltids = prefetch_state->ndeltids;
8068 for (
i = prefetch_state->next_item;
8069 i < ndeltids && count < prefetch_count;
8087 prefetch_state->next_item =
i;
8088 prefetch_state->cur_hblkno = cur_hblkno;
8112 if (
unlikely(indexpagehoffnum > maxoff))
8114 (
errcode(ERRCODE_INDEX_CORRUPTED),
8115 errmsg_internal(
"heap tid from index tuple (%u,%u) points past end of heap page line pointer array at offset %u of block %u in index \"%s\"",
8124 (
errcode(ERRCODE_INDEX_CORRUPTED),
8125 errmsg_internal(
"heap tid from index tuple (%u,%u) points to unused heap page item at offset %u of block %u in index \"%s\"",
8140 (
errcode(ERRCODE_INDEX_CORRUPTED),
8141 errmsg_internal(
"heap tid from index tuple (%u,%u) points to heap-only tuple at offset %u of block %u in index \"%s\"",
8173 IndexDeletePrefetchState prefetch_state;
8174 int prefetch_distance;
8177 int finalndeltids = 0,
8178 nblocksaccessed = 0;
8181 int nblocksfavorable = 0;
8184 actualfreespace = 0;
8185 bool bottomup_final_block =
false;
8205 prefetch_state.next_item = 0;
8206 prefetch_state.ndeltids = delstate->
ndeltids;
8207 prefetch_state.deltids = delstate->
deltids;
8225 Assert(nblocksfavorable >= 1);
8227 prefetch_distance =
Min(prefetch_distance, nblocksfavorable);
8231 index_delete_prefetch_buffer(rel, &prefetch_state, prefetch_distance);
8274 if (bottomup_final_block)
8283 if (nblocksaccessed >= 1 && actualfreespace == lastfreespace)
8285 lastfreespace = actualfreespace;
8311 Assert(nblocksaccessed > 0 || nblocksfavorable > 0);
8312 if (nblocksfavorable > 0)
8315 curtargetfreespace /= 2;
8334 index_delete_prefetch_buffer(rel, &prefetch_state, 1);
8360 &heapTuple, NULL,
true))
8371 if (actualfreespace >= curtargetfreespace)
8372 bottomup_final_block =
true;
8396 if (offnum > maxoff)
8433 &snapshotConflictHorizon);
8451 finalndeltids =
i + 1;
8463 delstate->
ndeltids = finalndeltids;
8465 return snapshotConflictHorizon;
8482 return (blk1 < blk2) ? -1 : 1;
8489 return (pos1 < pos2) ? -1 : 1;
8519 const int gaps[9] = {1968, 861, 336, 112, 48, 21, 7, 3, 1};
8523 "element size exceeds 8 bytes");
8525 for (
int g = 0; g <
lengthof(gaps); g++)
8527 for (
int hi = gaps[g],
i = hi;
i < ndeltids;
i++)
8534 deltids[
j] = deltids[
j - hi];
8607 int64 lastblock = -1;
8608 int nblocksfavorable = 0;
8610 Assert(nblockgroups >= 1);
8622 for (
int b = 0;
b < nblockgroups;
b++)
8628 if (lastblock != -1 &&
8638 Assert(nblocksfavorable >= 1);
8640 return nblocksfavorable;
8675 if (ntids1 > ntids2)
8677 if (ntids1 < ntids2)
8725 int nblockgroups = 0;
8727 int nblocksfavorable = 0;
8751 blockgroups[nblockgroups - 1].
ntids = 1;
8756 blockgroups[nblockgroups - 1].
ntids++;
8791 for (
int b = 0;
b < nblockgroups;
b++)
8813 for (
int b = 0;
b < nblockgroups;
b++)
8818 memcpy(reordereddeltids + ncopied, firstdtid,
8820 ncopied += group->
ntids;
8824 memcpy(delstate->
deltids, reordereddeltids,
8828 pfree(reordereddeltids);
8831 return nblocksfavorable;
8860 xlrec.
flags = vmflags;
8886 bool all_visible_cleared,
bool new_all_visible_cleared)
8931 if (oldbuf == newbuf && !need_tuple_data &&
8940 for (prefixlen = 0; prefixlen <
Min(oldlen, newlen); prefixlen++)
8942 if (newp[prefixlen] != oldp[prefixlen])
8954 for (suffixlen = 0; suffixlen <
Min(oldlen, newlen) - prefixlen; suffixlen++)
8956 if (newp[newlen - suffixlen - 1] != oldp[oldlen - suffixlen - 1])
8965 if (all_visible_cleared)
8967 if (new_all_visible_cleared)
8973 if (need_tuple_data)
8978 if (reln->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
9008 if (need_tuple_data)
9012 if (oldbuf != newbuf)
9020 if (prefixlen > 0 || suffixlen > 0)
9022 if (prefixlen > 0 && suffixlen > 0)
9024 prefix_suffix[0] = prefixlen;
9025 prefix_suffix[1] = suffixlen;
9028 else if (prefixlen > 0)
9076 if (need_tuple_data && old_key_tuple)
9190 char replident = relation->
rd_rel->relreplident;
9201 if (replident == REPLICA_IDENTITY_NOTHING)
9204 if (replident == REPLICA_IDENTITY_FULL)
9242 for (
int i = 0;
i < desc->
natts;
i++)
9346 elog(
ERROR,
"unrecognized return value from HeapTupleSatisfiesVacuum: %u", htsvResult);
int bms_next_member(const Bitmapset *a, int prevbit)
void bms_free(Bitmapset *a)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
static Datum values[MAXATTR]
BlockNumber BufferGetBlockNumber(Buffer buffer)
PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
void LockBuffer(Buffer buffer, BufferLockMode mode)
void BufferGetTag(Buffer buffer, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum)
bool BufferIsDirty(Buffer buffer)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
int maintenance_io_concurrency
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static Block BufferGetBlock(Buffer buffer)
static bool BufferIsValid(Buffer bufnum)
Size PageGetHeapFreeSpace(const PageData *page)
PageHeaderData * PageHeader
static bool PageIsAllVisible(const PageData *page)
static void PageClearAllVisible(Page page)
#define SizeOfPageHeaderData
static void PageSetAllVisible(Page page)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void * PageGetItem(PageData *page, const ItemIdData *itemId)
static void PageSetFull(Page page)
static void PageSetLSN(Page page, XLogRecPtr lsn)
#define PageSetPrunable(page, xid)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
TransactionId MultiXactId
#define pg_attribute_always_inline
#define StaticAssertDecl(condition, errmessage)
#define OidIsValid(objectId)
bool IsToastRelation(Relation relation)
bool IsCatalogRelation(Relation relation)
bool IsSharedRelation(Oid relationId)
bool IsInplaceUpdateRelation(Relation relation)
CommandId HeapTupleHeaderGetCmin(const HeapTupleHeaderData *tup)
void HeapTupleHeaderAdjustCmax(const HeapTupleHeaderData *tup, CommandId *cmax, bool *iscombo)
CommandId HeapTupleHeaderGetCmax(const HeapTupleHeaderData *tup)
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
int errmsg_internal(const char *fmt,...)
int errdetail_internal(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
HeapTuple ExecFetchSlotHeapTuple(TupleTableSlot *slot, bool materialize, bool *shouldFree)
TupleTableSlot * ExecStoreBufferHeapTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer)
#define palloc_object(type)
#define palloc_array(type, count)
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
void FreeAccessStrategy(BufferAccessStrategy strategy)
Assert(PointerIsAligned(start, uint64))
void simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup, TU_UpdateIndexes *update_indexes)
static bool DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask, LockTupleMode lockmode, bool *current_is_member)
void heap_insert(Relation relation, HeapTuple tup, CommandId cid, int options, BulkInsertState bistate)
static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup)
XLogRecPtr log_heap_visible(Relation rel, Buffer heap_buffer, Buffer vm_buffer, TransactionId snapshotConflictHorizon, uint8 vmflags)
static void compute_new_xmax_infomask(TransactionId xmax, uint16 old_infomask, uint16 old_infomask2, TransactionId add_to_xmax, LockTupleMode mode, bool is_update, TransactionId *result_xmax, uint16 *result_infomask, uint16 *result_infomask2)
struct IndexDeleteCounts IndexDeleteCounts
static TM_Result heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, const ItemPointerData *tid, TransactionId xid, LockTupleMode mode)
static void heap_fetch_next_buffer(HeapScanDesc scan, ScanDirection dir)
bool heap_inplace_lock(Relation relation, HeapTuple oldtup_ptr, Buffer buffer, void(*release_callback)(void *), void *arg)
bool heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tuple, Buffer *userbuf, bool keep_buf)
#define BOTTOMUP_TOLERANCE_NBLOCKS
static HeapTuple heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, CommandId cid, int options)
static BlockNumber heap_scan_stream_read_next_parallel(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
static int bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate)
static bool heap_acquire_tuplock(Relation relation, const ItemPointerData *tid, LockTupleMode mode, LockWaitPolicy wait_policy, bool *have_tuple_lock)
static int heap_multi_insert_pages(HeapTuple *heaptuples, int done, int ntuples, Size saveFreeSpace)
static pg_attribute_always_inline int page_collect_tuples(HeapScanDesc scan, Snapshot snapshot, Page page, Buffer buffer, BlockNumber block, int lines, bool all_visible, bool check_serializable)
static BlockNumber heap_scan_stream_read_next_serial(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask, uint16 *new_infomask2)
void heap_finish_speculative(Relation relation, const ItemPointerData *tid)
void HeapTupleHeaderAdvanceConflictHorizon(HeapTupleHeader tuple, TransactionId *snapshotConflictHorizon)
bool heap_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
#define LOCKMODE_from_mxstatus(status)
void heap_endscan(TableScanDesc sscan)
#define FRM_RETURN_IS_XID
#define TUPLOCK_from_mxstatus(status)
void heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params, bool allow_strat, bool allow_sync, bool allow_pagemode)
void heap_inplace_unlock(Relation relation, HeapTuple oldtup, Buffer buffer)
TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, CommandId cid, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes)
static int index_delete_sort_cmp(TM_IndexDelete *deltid1, TM_IndexDelete *deltid2)
static bool ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, Relation rel, int *remaining, bool logLockFailure)
bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple)
TM_Result heap_delete(Relation relation, const ItemPointerData *tid, CommandId cid, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, bool changingPart)
static TransactionId FreezeMultiXactId(MultiXactId multi, uint16 t_infomask, const struct VacuumCutoffs *cutoffs, uint16 *flags, HeapPageFreeze *pagefrz)
static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, bool *copy)
static pg_noinline BlockNumber heapgettup_initial_block(HeapScanDesc scan, ScanDirection dir)
static TM_Result heap_lock_updated_tuple(Relation rel, uint16 prior_infomask, TransactionId prior_raw_xmax, const ItemPointerData *prior_ctid, TransactionId xid, LockTupleMode mode)
#define LockTupleTuplock(rel, tup, mode)
bool heap_tuple_should_freeze(HeapTupleHeader tuple, const struct VacuumCutoffs *cutoffs, TransactionId *NoFreezePageRelfrozenXid, MultiXactId *NoFreezePageRelminMxid)
bool heap_freeze_tuple(HeapTupleHeader tuple, TransactionId relfrozenxid, TransactionId relminmxid, TransactionId FreezeLimit, TransactionId MultiXactCutoff)
void heap_inplace_update_and_unlock(Relation relation, HeapTuple oldtup, HeapTuple tuple, Buffer buffer)
static BlockNumber heapgettup_advance_block(HeapScanDesc scan, BlockNumber block, ScanDirection dir)
static TransactionId MultiXactIdGetUpdateXid(TransactionId xmax, uint16 t_infomask)
#define BOTTOMUP_MAX_NBLOCKS
void ReleaseBulkInsertStatePin(BulkInsertState bistate)
#define FRM_MARK_COMMITTED
static void index_delete_check_htid(TM_IndexDeleteOp *delstate, Page page, OffsetNumber maxoff, const ItemPointerData *htid, TM_IndexStatus *istatus)
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
bool heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, Snapshot snapshot, HeapTuple heapTuple, bool *all_dead, bool first_call)
void heap_freeze_prepared_tuples(Buffer buffer, HeapTupleFreeze *tuples, int ntuples)
bool heap_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
static void MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, Relation rel, const ItemPointerData *ctid, XLTW_Oper oper, int *remaining)
void heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid, ItemPointer maxtid)
void heap_abort_speculative(Relation relation, const ItemPointerData *tid)
static BlockNumber bitmapheap_stream_read_next(ReadStream *pgsr, void *private_data, void *per_buffer_data)
TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot, int nkeys, ScanKey key, ParallelTableScanDesc parallel_scan, uint32 flags)
static void heapgettup(HeapScanDesc scan, ScanDirection dir, int nkeys, ScanKey key)
static Page heapgettup_continue_page(HeapScanDesc scan, ScanDirection dir, int *linesleft, OffsetNumber *lineoff)
static uint8 compute_infobits(uint16 infomask, uint16 infomask2)
#define FRM_RETURN_IS_MULTI
#define FRM_INVALIDATE_XMAX
static bool heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, bool isnull1, bool isnull2)
static void index_delete_sort(TM_IndexDeleteOp *delstate)
void heap_prepare_pagescan(TableScanDesc sscan)
static Bitmapset * HeapDetermineColumnsInfo(Relation relation, Bitmapset *interesting_cols, Bitmapset *external_cols, HeapTuple oldtup, HeapTuple newtup, bool *has_external)
static const int MultiXactStatusLock[MaxMultiXactStatus+1]
void simple_heap_insert(Relation relation, HeapTuple tup)
static bool xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask)
#define UnlockTupleTuplock(rel, tup, mode)
static TM_Result test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, LockTupleMode mode, HeapTuple tup, bool *needwait)
bool heap_prepare_freeze_tuple(HeapTupleHeader tuple, const struct VacuumCutoffs *cutoffs, HeapPageFreeze *pagefrz, HeapTupleFreeze *frz, bool *totally_frozen)
static void AssertHasSnapshotForToast(Relation rel)
void simple_heap_delete(Relation relation, const ItemPointerData *tid)
static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf, Buffer newbuf, HeapTuple oldtup, HeapTuple newtup, HeapTuple old_key_tuple, bool all_visible_cleared, bool new_all_visible_cleared)
TransactionId HeapTupleGetUpdateXid(const HeapTupleHeaderData *tup)
TransactionId heap_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, int options, BulkInsertState bistate)
#define ConditionalLockTupleTuplock(rel, tup, mode, log)
static void initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock)
static int bottomup_nblocksfavorable(IndexDeleteCounts *blockgroups, int nblockgroups, TM_IndexDelete *deltids)
static void heapgettup_pagemode(HeapScanDesc scan, ScanDirection dir, int nkeys, ScanKey key)
TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, bool follow_updates, Buffer *buffer, TM_FailureData *tmfd)
static void UpdateXmaxHintBits(HeapTupleHeader tuple, Buffer buffer, TransactionId xid)
static bool Do_MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, bool nowait, Relation rel, const ItemPointerData *ctid, XLTW_Oper oper, int *remaining, bool logLockFailure)
static int bottomup_sort_and_shrink_cmp(const void *arg1, const void *arg2)
void heap_get_latest_tid(TableScanDesc sscan, ItemPointer tid)
void heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, BlockNumber numBlks)
void HeapCheckForSerializableConflictOut(bool visible, Relation relation, HeapTuple tuple, Buffer buffer, Snapshot snapshot)
static Page heapgettup_start_page(HeapScanDesc scan, ScanDirection dir, int *linesleft, OffsetNumber *lineoff)
static MultiXactStatus get_mxact_status_for_lock(LockTupleMode mode, bool is_update)
void heap_pre_freeze_checks(Buffer buffer, HeapTupleFreeze *tuples, int ntuples)
BulkInsertState GetBulkInsertState(void)
void FreeBulkInsertState(BulkInsertState bistate)
static const struct @15 tupleLockExtraInfo[MaxLockTupleMode+1]
#define HEAP_INSERT_SPECULATIVE
#define HEAP_FREEZE_CHECK_XMAX_ABORTED
struct HeapScanDescData * HeapScanDesc
@ HEAPTUPLE_RECENTLY_DEAD
@ HEAPTUPLE_INSERT_IN_PROGRESS
@ HEAPTUPLE_DELETE_IN_PROGRESS
struct BitmapHeapScanDescData * BitmapHeapScanDesc
#define HEAP_INSERT_FROZEN
static void heap_execute_freeze_tuple(HeapTupleHeader tuple, HeapTupleFreeze *frz)
#define HEAP_FREEZE_CHECK_XMIN_COMMITTED
#define HEAP_INSERT_NO_LOGICAL
struct BulkInsertStateData * BulkInsertState
const TableAmRoutine * GetHeapamTableAmRoutine(void)
void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
bool HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, Buffer buffer)
bool HeapTupleIsSurelyDead(HeapTuple htup, GlobalVisState *vistest)
HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, Buffer buffer)
bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
TM_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, Buffer buffer)
#define XLH_INSERT_ON_TOAST_RELATION
#define SizeOfHeapMultiInsert
#define XLOG_HEAP2_MULTI_INSERT
#define XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED
#define SizeOfHeapVisible
#define XLOG_HEAP_HOT_UPDATE
#define XLH_INSERT_IS_SPECULATIVE
#define XLH_LOCK_ALL_FROZEN_CLEARED
#define XLH_DELETE_CONTAINS_OLD_KEY
#define XLH_UPDATE_CONTAINS_NEW_TUPLE
#define XLH_INSERT_LAST_IN_MULTI
#define XLH_INSERT_ALL_FROZEN_SET
#define XLHL_XMAX_KEYSHR_LOCK
#define XLH_DELETE_ALL_VISIBLE_CLEARED
#define XLH_UPDATE_CONTAINS_OLD_TUPLE
#define SizeOfHeapLockUpdated
#define XLHL_XMAX_IS_MULTI
#define XLH_INSERT_ALL_VISIBLE_CLEARED
#define XLH_DELETE_IS_PARTITION_MOVE
#define MinSizeOfHeapInplace
#define XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED
#define XLHL_XMAX_LOCK_ONLY
#define XLOG_HEAP_INPLACE
#define XLOG_HEAP2_LOCK_UPDATED
#define XLH_UPDATE_SUFFIX_FROM_OLD
#define XLH_UPDATE_PREFIX_FROM_OLD
#define SizeOfMultiInsertTuple
#define XLHL_XMAX_EXCL_LOCK
#define XLOG_HEAP2_NEW_CID
#define XLH_DELETE_CONTAINS_OLD_TUPLE
#define XLH_DELETE_IS_SUPER
#define XLH_UPDATE_CONTAINS_OLD_KEY
#define XLHL_KEYS_UPDATED
#define XLOG_HEAP2_VISIBLE
#define XLH_INSERT_CONTAINS_NEW_TUPLE
#define XLOG_HEAP_INIT_PAGE
#define SizeOfHeapConfirm
#define XLOG_HEAP_CONFIRM
void heap_toast_delete(Relation rel, HeapTuple oldtup, bool is_speculative)
HeapTuple heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup, int options)
HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc)
#define TOAST_TUPLE_THRESHOLD
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
void heap_freetuple(HeapTuple htup)
void RelationPutHeapTuple(Relation relation, Buffer buffer, HeapTuple tuple, bool token)
Buffer RelationGetBufferForTuple(Relation relation, Size len, Buffer otherBuffer, int options, BulkInsertState bistate, Buffer *vmbuffer, Buffer *vmbuffer_other, int num_pages)
HeapTupleHeaderData * HeapTupleHeader
#define HEAP_XMAX_SHR_LOCK
static bool HeapTupleIsHotUpdated(const HeapTupleData *tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static bool HeapTupleHeaderXminFrozen(const HeapTupleHeaderData *tup)
#define HeapTupleHeaderGetNatts(tup)
static void HeapTupleHeaderSetXminFrozen(HeapTupleHeaderData *tup)
#define SizeofHeapTupleHeader
#define HEAP_KEYS_UPDATED
static bool HEAP_XMAX_IS_SHR_LOCKED(uint16 infomask)
static bool HEAP_XMAX_IS_LOCKED_ONLY(uint16 infomask)
static bool HeapTupleHeaderXminInvalid(const HeapTupleHeaderData *tup)
static void HeapTupleClearHotUpdated(const HeapTupleData *tuple)
static bool HeapTupleHasExternal(const HeapTupleData *tuple)
static TransactionId HeapTupleHeaderGetXvac(const HeapTupleHeaderData *tup)
static void HeapTupleHeaderSetCmax(HeapTupleHeaderData *tup, CommandId cid, bool iscombo)
#define HEAP_XMAX_LOCK_ONLY
static void HeapTupleHeaderClearHotUpdated(HeapTupleHeaderData *tup)
static void HeapTupleHeaderSetCmin(HeapTupleHeaderData *tup, CommandId cid)
static CommandId HeapTupleHeaderGetRawCommandId(const HeapTupleHeaderData *tup)
static TransactionId HeapTupleHeaderGetRawXmax(const HeapTupleHeaderData *tup)
static bool HeapTupleHeaderIsHeapOnly(const HeapTupleHeaderData *tup)
static bool HeapTupleIsHeapOnly(const HeapTupleData *tuple)
static void HeapTupleSetHeapOnly(const HeapTupleData *tuple)
#define HEAP_XMAX_IS_MULTI
static bool HEAP_XMAX_IS_KEYSHR_LOCKED(uint16 infomask)
#define HEAP_XMAX_COMMITTED
static TransactionId HeapTupleHeaderGetXmin(const HeapTupleHeaderData *tup)
static bool HeapTupleHeaderIndicatesMovedPartitions(const HeapTupleHeaderData *tup)
static void HeapTupleSetHotUpdated(const HeapTupleData *tuple)
#define HEAP_XMAX_EXCL_LOCK
static bool HeapTupleHeaderIsHotUpdated(const HeapTupleHeaderData *tup)
#define HEAP_XMAX_INVALID
static TransactionId HeapTupleHeaderGetRawXmin(const HeapTupleHeaderData *tup)
static void * GETSTRUCT(const HeapTupleData *tuple)
static void HeapTupleClearHeapOnly(const HeapTupleData *tuple)
#define MaxHeapAttributeNumber
static bool HeapTupleHeaderIsSpeculative(const HeapTupleHeaderData *tup)
static TransactionId HeapTupleHeaderGetUpdateXid(const HeapTupleHeaderData *tup)
#define MaxHeapTuplesPerPage
static bool HEAP_XMAX_IS_EXCL_LOCKED(uint16 infomask)
static void HeapTupleHeaderSetXmin(HeapTupleHeaderData *tup, TransactionId xid)
static bool HEAP_LOCKED_UPGRADED(uint16 infomask)
#define HEAP_XMAX_KEYSHR_LOCK
static void HeapTupleHeaderSetMovedPartitions(HeapTupleHeaderData *tup)
static void HeapTupleHeaderSetXmax(HeapTupleHeaderData *tup, TransactionId xid)
static bool HeapTupleHeaderXminCommitted(const HeapTupleHeaderData *tup)
#define IsParallelWorker()
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
#define INJECTION_POINT(name, arg)
void AcceptInvalidationMessages(void)
int inplaceGetInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
void PreInplace_Inval(void)
void CacheInvalidateHeapTupleInplace(Relation relation, HeapTuple key_equivalent_tuple)
void AtInplace_Inval(void)
void ForgetInplace_Inval(void)
void CacheInvalidateHeapTuple(Relation relation, HeapTuple tuple, HeapTuple newtuple)
#define ItemIdGetLength(itemId)
#define ItemIdIsNormal(itemId)
struct ItemIdData ItemIdData
#define ItemIdGetRedirect(itemId)
#define ItemIdIsUsed(itemId)
#define ItemIdIsRedirected(itemId)
#define ItemIdHasStorage(itemId)
int32 ItemPointerCompare(const ItemPointerData *arg1, const ItemPointerData *arg2)
bool ItemPointerEquals(const ItemPointerData *pointer1, const ItemPointerData *pointer2)
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
static void ItemPointerSetInvalid(ItemPointerData *pointer)
static void ItemPointerSetOffsetNumber(ItemPointerData *pointer, OffsetNumber offsetNumber)
static void ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static bool ItemPointerIndicatesMovedPartitions(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer)
static void ItemPointerCopy(const ItemPointerData *fromPointer, ItemPointerData *toPointer)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
void UnlockTuple(Relation relation, const ItemPointerData *tid, LOCKMODE lockmode)
bool ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
void LockTuple(Relation relation, const ItemPointerData *tid, LOCKMODE lockmode)
void XactLockTableWait(TransactionId xid, Relation rel, const ItemPointerData *ctid, XLTW_Oper oper)
bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode, bool orstronger)
bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2)
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
#define SET_LOCKTAG_TUPLE(locktag, dboid, reloid, blocknum, offnum)
#define AccessExclusiveLock
#define ShareRowExclusiveLock
#define InplaceUpdateTupleLock
#define ShareUpdateExclusiveLock
@ LockTupleNoKeyExclusive
void pfree(void *pointer)
#define IsBootstrapProcessingMode()
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define IsNormalProcessingMode()
#define END_CRIT_SECTION()
MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid, MultiXactStatus status)
bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)
bool MultiXactIdPrecedesOrEquals(MultiXactId multi1, MultiXactId multi2)
bool MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly)
void MultiXactIdSetOldestMember(void)
MultiXactId MultiXactIdCreateFromMembers(int nmembers, MultiXactMember *members)
MultiXactId MultiXactIdCreate(TransactionId xid1, MultiXactStatus status1, TransactionId xid2, MultiXactStatus status2)
int GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, bool from_pgupgrade, bool isLockOnly)
#define MultiXactIdIsValid(multi)
@ MultiXactStatusForShare
@ MultiXactStatusForNoKeyUpdate
@ MultiXactStatusNoKeyUpdate
@ MultiXactStatusForUpdate
@ MultiXactStatusForKeyShare
#define ISUPDATE_from_mxstatus(status)
#define InvalidMultiXactId
#define MaxMultiXactStatus
#define InvalidOffsetNumber
#define OffsetNumberIsValid(offsetNumber)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
#define OffsetNumberPrev(offsetNumber)
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
#define ERRCODE_DATA_CORRUPTED
static uint32 pg_nextpower2_32(uint32 num)
static PgChecksumMode mode
static const struct exclude_list_item skip[]
FormData_pg_class * Form_pg_class
FormData_pg_database * Form_pg_database
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define pgstat_count_heap_getnext(rel)
#define pgstat_count_heap_scan(rel)
void pgstat_count_heap_update(Relation rel, bool hot, bool newpage)
void pgstat_count_heap_delete(Relation rel)
void pgstat_count_heap_insert(Relation rel, PgStat_Counter n)
#define qsort(a, b, c, d)
static Oid DatumGetObjectId(Datum X)
static Pointer DatumGetPointer(Datum X)
void CheckForSerializableConflictIn(Relation relation, const ItemPointerData *tid, BlockNumber blkno)
void CheckForSerializableConflictOut(Relation relation, TransactionId xid, Snapshot snapshot)
void PredicateLockRelation(Relation relation, Snapshot snapshot)
void PredicateLockTID(Relation relation, const ItemPointerData *tid, Snapshot snapshot, TransactionId tuple_xid)
bool CheckForSerializableConflictOutNeeded(Relation relation, Snapshot snapshot)
#define DELAY_CHKPT_START
GlobalVisState * GlobalVisTestFor(Relation rel)
bool TransactionIdIsInProgress(TransactionId xid)
void heap_page_prune_opt(Relation relation, Buffer buffer)
void read_stream_reset(ReadStream *stream)
Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
ReadStream * read_stream_begin_relation(int flags, BufferAccessStrategy strategy, Relation rel, ForkNumber forknum, ReadStreamBlockNumberCB callback, void *callback_private_data, size_t per_buffer_data_size)
void read_stream_end(ReadStream *stream)
#define READ_STREAM_USE_BATCHING
BlockNumber(* ReadStreamBlockNumberCB)(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
#define READ_STREAM_DEFAULT
#define READ_STREAM_SEQUENTIAL
#define RelationGetRelid(relation)
#define RelationIsLogicallyLogged(relation)
#define RelationGetTargetPageFreeSpace(relation, defaultff)
#define RelationGetDescr(relation)
#define RelationGetNumberOfAttributes(relation)
#define RelationGetRelationName(relation)
#define RelationIsAccessibleInLogicalDecoding(relation)
#define RelationNeedsWAL(relation)
#define RelationUsesLocalBuffers(relation)
#define HEAP_DEFAULT_FILLFACTOR
void RelationDecrementReferenceCount(Relation rel)
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
void RelationIncrementReferenceCount(Relation rel)
@ INDEX_ATTR_BITMAP_HOT_BLOCKING
@ INDEX_ATTR_BITMAP_SUMMARIZED
@ INDEX_ATTR_BITMAP_IDENTITY_KEY
struct ParallelBlockTableScanDescData * ParallelBlockTableScanDesc
#define ScanDirectionIsForward(direction)
#define ScanDirectionIsBackward(direction)
void UnregisterSnapshot(Snapshot snapshot)
TransactionId TransactionXmin
bool HaveRegisteredOrActiveSnapshot(void)
void InvalidateCatalogSnapshot(void)
#define IsHistoricMVCCSnapshot(snapshot)
#define InitNonVacuumableSnapshot(snapshotdata, vistestp)
#define IsMVCCSnapshot(snapshot)
int get_tablespace_maintenance_io_concurrency(Oid spcid)
BufferAccessStrategy strategy
uint32 already_extended_by
MultiXactId NoFreezePageRelminMxid
TransactionId FreezePageRelfrozenXid
MultiXactId FreezePageRelminMxid
TransactionId NoFreezePageRelfrozenXid
BufferAccessStrategy rs_strategy
ParallelBlockTableScanWorkerData * rs_parallelworkerdata
BlockNumber rs_startblock
OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]
ReadStream * rs_read_stream
BlockNumber rs_prefetch_block
TableScanDescData rs_base
const struct TableAmRoutine * rd_tableam
RelFileLocator rd_locator
TBMIterator rs_tbmiterator
ItemPointerData rs_mintid
union TableScanDescData::@49 st
ItemPointerData rs_maxtid
struct TableScanDescData::@49::@50 tidrange
struct ScanKeyData * rs_key
struct SnapshotData * rs_snapshot
struct ParallelTableScanDescData * rs_parallel
TransactionId FreezeLimit
TransactionId relfrozenxid
MultiXactId MultiXactCutoff
bool relcacheInitFileInval
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]
ItemPointerData target_tid
RelFileLocator target_locator
TransactionId snapshotConflictHorizon
TransactionId SubTransGetTopmostTransaction(TransactionId xid)
void ss_report_location(Relation rel, BlockNumber location)
BlockNumber ss_get_location(Relation rel, BlockNumber relnblocks)
#define FirstLowInvalidHeapAttributeNumber
#define TableOidAttributeNumber
bool RelationSupportsSysCache(Oid relid)
void table_block_parallelscan_startblock_init(Relation rel, ParallelBlockTableScanWorker pbscanwork, ParallelBlockTableScanDesc pbscan, BlockNumber startblock, BlockNumber numblocks)
BlockNumber table_block_parallelscan_nextpage(Relation rel, ParallelBlockTableScanWorker pbscanwork, ParallelBlockTableScanDesc pbscan)
bool synchronize_seqscans
bool tbm_iterate(TBMIterator *iterator, TBMIterateResult *tbmres)
bool TransactionIdDidCommit(TransactionId transactionId)
bool TransactionIdDidAbort(TransactionId transactionId)
static bool TransactionIdFollows(TransactionId id1, TransactionId id2)
#define InvalidTransactionId
static bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
static bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
#define TransactionIdEquals(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static bool HeapKeyTest(HeapTuple tuple, TupleDesc tupdesc, int nkeys, ScanKey keys)
static bool VARATT_IS_EXTERNAL(const void *PTR)
bool visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer vmbuf, uint8 flags)
void visibilitymap_pin(Relation rel, BlockNumber heapBlk, Buffer *vmbuf)
uint8 visibilitymap_set_vmbits(BlockNumber heapBlk, Buffer vmBuf, uint8 flags, const RelFileLocator rlocator)
#define VISIBILITYMAP_VALID_BITS
#define VISIBILITYMAP_ALL_FROZEN
#define VISIBILITYMAP_XLOG_CATALOG_REL
#define VISIBILITYMAP_ALL_VISIBLE
TransactionId GetTopTransactionId(void)
TransactionId CheckXidAlive
TransactionId GetTopTransactionIdIfAny(void)
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
bool IsInParallelMode(void)
TransactionId GetCurrentTransactionId(void)
CommandId GetCurrentCommandId(bool used)
#define IsolationIsSerializable()
#define XLOG_INCLUDE_ORIGIN
#define XLogHintBitIsNeeded()
#define XLogStandbyInfoActive()
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBufData(uint8 block_id, const void *data, uint32 len)
bool XLogCheckBufferNeedsBackup(Buffer buffer)
void XLogRegisterData(const void *data, uint32 len)
void XLogSetRecordFlags(uint8 flags)
void XLogRegisterBlock(uint8 block_id, RelFileLocator *rlocator, ForkNumber forknum, BlockNumber blknum, const PageData *page, uint8 flags)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)