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);
102 bool logLockFailure);
154#define LOCKMODE_from_mxstatus(status) \
155 (tupleLockExtraInfo[TUPLOCK_from_mxstatus((status))].hwlock)
162#define LockTupleTuplock(rel, tup, mode) \
163 LockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock)
164#define UnlockTupleTuplock(rel, tup, mode) \
165 UnlockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock)
166#define ConditionalLockTupleTuplock(rel, tup, mode, log) \
167 ConditionalLockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock, (log))
180} IndexDeletePrefetchState;
184#define BOTTOMUP_MAX_NBLOCKS 6
185#define BOTTOMUP_TOLERANCE_NBLOCKS 3
213#define TUPLOCK_from_mxstatus(status) \
214 (MultiXactStatusLock[(status)])
227 void *callback_private_data,
228 void *per_buffer_data)
265 void *callback_private_data,
266 void *per_buffer_data)
290 void *per_buffer_data)
373 allow_strat = allow_sync =
false;
396 else if (keep_startblock)
468 Assert(startBlk == 0 || startBlk < scan->rs_nblocks);
484 bool all_visible,
bool check_serializable)
508 if (check_serializable)
510 &loctup, buffer, snapshot);
540 bool check_serializable;
595 if (
likely(!check_serializable))
597 block, lines,
true,
false);
600 block, lines,
true,
true);
604 if (
likely(!check_serializable))
606 block, lines,
false,
false);
609 block, lines,
false,
true);
769 *linesleft = *lineoff;
918 for (; linesleft > 0; linesleft--, lineoff += dir)
1027 linesleft = scan->rs_ntuples;
1036 for (; linesleft > 0; linesleft--, lineindex += dir)
1041 Assert(lineindex <= scan->rs_ntuples);
1042 lineoff = scan->rs_vistuples[lineindex];
1056 scan->rs_cindex = lineindex;
1156 if (parallel_scan != NULL)
1223 bool allow_strat,
bool allow_sync,
bool allow_pagemode)
1327 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1338 elog(
ERROR,
"unexpected heap_getnext call during logical decoding");
1695 bool *all_dead,
bool first_call)
1701 bool at_chain_start;
1708 *all_dead = first_call;
1712 at_chain_start = first_call;
1738 at_chain_start =
false;
1805 if (all_dead && *all_dead)
1823 at_chain_start =
false;
2063 bool all_visible_cleared =
false;
2111 all_visible_cleared =
true;
2162 if (all_visible_cleared)
2256 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2257 errmsg(
"cannot insert tuples in a parallel worker")));
2274 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
2275 relation->
rd_rel->relkind != RELKIND_MATVIEW)
2298 for (
int i = done;
i < ntuples;
i++)
2302 if (page_avail < tup_sz)
2307 page_avail -= tup_sz;
2339 bool starting_with_empty_page =
false;
2341 int npages_used = 0;
2352 for (
i = 0;
i < ntuples;
i++)
2389 while (ndone < ntuples)
2392 bool all_visible_cleared =
false;
2393 bool all_frozen_set =
false;
2408 if (ndone == 0 || !starting_with_empty_page)
2427 npages - npages_used);
2433 all_frozen_set =
true;
2448 if (needwal && need_cids)
2451 for (nthispage = 1; ndone + nthispage < ntuples; nthispage++)
2453 HeapTuple heaptup = heaptuples[ndone + nthispage];
2464 if (needwal && need_cids)
2477 all_visible_cleared =
true;
2483 else if (all_frozen_set)
2500 char *scratchptr = scratch.
data;
2508 init = starting_with_empty_page;
2524 tupledata = scratchptr;
2527 Assert(!(all_visible_cleared && all_frozen_set));
2530 if (all_visible_cleared)
2541 for (
i = 0;
i < nthispage;
i++)
2563 scratchptr += datalen;
2565 totaldatalen = scratchptr - tupledata;
2566 Assert((scratchptr - scratch.
data) < BLCKSZ);
2568 if (need_tuple_data)
2576 if (ndone + nthispage == ntuples)
2589 if (need_tuple_data)
2666 for (
i = 0;
i < ntuples;
i++)
2671 for (
i = 0;
i < ntuples;
i++)
2672 slots[
i]->tts_tid = heaptuples[
i]->t_self;
2724 const uint16 interesting =
2727 if ((new_infomask & interesting) != (old_infomask & interesting))
2760 bool have_tuple_lock =
false;
2762 bool all_visible_cleared =
false;
2764 bool old_key_copied =
false;
2775 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2776 errmsg(
"cannot delete tuples during a parallel operation")));
2822 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2823 errmsg(
"attempted to delete invisible tuple")));
2849 bool current_is_member =
false;
2860 if (!current_is_member)
2940 if (result !=
TM_Ok)
2958 if (result !=
TM_Ok)
2967 if (have_tuple_lock)
3007 &new_xmax, &new_infomask, &new_infomask2);
3022 all_visible_cleared =
true;
3065 if (all_visible_cleared)
3072 xlrec.
xmax = new_xmax;
3074 if (old_key_tuple != NULL)
3076 if (relation->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
3090 if (old_key_tuple != NULL)
3099 old_key_tuple->
t_len
3124 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3125 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3146 if (have_tuple_lock)
3151 if (old_key_tuple != NULL && old_key_copied)
3179 elog(
ERROR,
"tuple already updated by self");
3187 elog(
ERROR,
"tuple concurrently updated");
3191 elog(
ERROR,
"tuple concurrently deleted");
3195 elog(
ERROR,
"unrecognized heap_delete status: %u", result);
3229 bool old_key_copied =
false;
3240 bool have_tuple_lock =
false;
3242 bool use_hot_update =
false;
3243 bool summarized_update =
false;
3245 bool all_visible_cleared =
false;
3246 bool all_visible_cleared_new =
false;
3247 bool checked_lockers;
3248 bool locker_remains;
3249 bool id_has_external =
false;
3252 uint16 infomask_old_tuple,
3253 infomask2_old_tuple,
3255 infomask2_new_tuple;
3270 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3271 errmsg(
"cannot update tuples during a parallel operation")));
3273#ifdef USE_ASSERT_CHECKING
3274 check_lock_if_inplace_updateable_rel(relation, otid, newtup);
3300 interesting_attrs = NULL;
3352 Assert(!have_tuple_lock);
3391 newtup, &id_has_external);
3436 checked_lockers =
false;
3437 locker_remains =
false;
3447 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3448 errmsg(
"attempted to update invisible tuple")));
3454 bool can_continue =
false;
3499 bool current_is_member =
false;
3502 *lockmode, ¤t_is_member))
3510 if (!current_is_member)
3518 checked_lockers =
true;
3519 locker_remains = remain != 0;
3566 can_continue =
true;
3574 checked_lockers =
true;
3575 locker_remains =
true;
3576 can_continue =
true;
3585 checked_lockers =
true;
3586 locker_remains =
true;
3587 can_continue =
true;
3600 checked_lockers =
true;
3616 can_continue =
true;
3628 if (result !=
TM_Ok)
3646 if (result !=
TM_Ok)
3655 if (have_tuple_lock)
3696 xid, *lockmode,
true,
3697 &xmax_old_tuple, &infomask_old_tuple,
3698 &infomask2_old_tuple);
3709 (checked_lockers && !locker_remains))
3717 infomask2_new_tuple = 0;
3730 &infomask2_new_tuple);
3735 infomask2_new_tuple = 0;
3768 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3769 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3785 if (need_toast || newtupsize > pagefree)
3788 uint16 infomask_lock_old_tuple,
3789 infomask2_lock_old_tuple;
3790 bool cleared_all_frozen =
false;
3813 xid, *lockmode,
false,
3814 &xmax_lock_old_tuple, &infomask_lock_old_tuple,
3815 &infomask2_lock_old_tuple);
3844 cleared_all_frozen =
true;
3857 xlrec.
xmax = xmax_lock_old_tuple;
3912 if (newtupsize > pagefree)
3917 &vmbuffer_new, &vmbuffer,
3929 if (newtupsize > pagefree ||
3977 if (newbuf == buffer)
3986 use_hot_update =
true;
3996 summarized_update =
true;
4070 all_visible_cleared =
true;
4077 all_visible_cleared_new =
true;
4083 if (newbuf != buffer)
4103 newbuf, &oldtup, heaptup,
4105 all_visible_cleared,
4106 all_visible_cleared_new);
4107 if (newbuf != buffer)
4116 if (newbuf != buffer)
4131 if (newbuf != buffer)
4142 if (have_tuple_lock)
4151 if (heaptup != newtup)
4165 if (summarized_update)
4171 *update_indexes =
TU_All;
4173 if (old_key_tuple != NULL && old_key_copied)
4186#ifdef USE_ASSERT_CHECKING
4192check_lock_if_inplace_updateable_rel(
Relation relation,
4199 case RelationRelationId:
4200 case DatabaseRelationId:
4220 case RelationRelationId:
4224 Oid relid = classForm->oid;
4233 if (classForm->relkind == RELKIND_INDEX)
4246 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4254 case DatabaseRelationId:
4260 "missing lock on database \"%s\" (OID %u) @ TID (%u,%u)",
4278 Oid relid = classForm->oid;
4287 if (classForm->relkind == RELKIND_INDEX)
4299 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4314 bool isnull1,
bool isnull2)
4320 if (isnull1 != isnull2)
4347 Assert(attrnum <= tupdesc->natts);
4415 value1 =
heap_getattr(oldtup, attrnum, tupdesc, &isnull1);
4416 value2 =
heap_getattr(newtup, attrnum, tupdesc, &isnull2);
4419 value2, isnull1, isnull2))
4429 if (attrnum < 0 || isnull1 ||
4439 *has_external =
true;
4464 &tmfd, &lockmode, update_indexes);
4469 elog(
ERROR,
"tuple already updated by self");
4477 elog(
ERROR,
"tuple concurrently updated");
4481 elog(
ERROR,
"tuple concurrently deleted");
4485 elog(
ERROR,
"unrecognized heap_update status: %u", result);
4506 is_update ?
"true" :
"false");
4545 bool follow_updates,
4559 bool first_time =
true;
4560 bool skip_tuple_lock =
false;
4561 bool have_tuple_lock =
false;
4562 bool cleared_all_frozen =
false;
4649 for (
i = 0;
i < nmembers;
i++)
4674 skip_tuple_lock =
true;
4723 require_sleep =
true;
4757 if (follow_updates && updated)
4788 require_sleep =
false;
4817 require_sleep =
false;
4843 require_sleep =
false;
4856 require_sleep =
false;
4882 require_sleep =
false;
4901 else if (require_sleep)
4913 if (!skip_tuple_lock &&
4933 elog(
ERROR,
"invalid lock mode in heap_lock_tuple");
4936 switch (wait_policy)
4944 status, infomask, relation,
4955 status, infomask, relation,
4958 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
4959 errmsg(
"could not obtain lock on row in relation \"%s\"",
4978 switch (wait_policy)
4996 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
4997 errmsg(
"could not obtain lock on row in relation \"%s\"",
5053 if (!require_sleep ||
5065 if (result !=
TM_Ok)
5127 &xid, &new_infomask, &new_infomask2);
5163 cleared_all_frozen =
true;
5222 if (have_tuple_lock)
5244 if (*have_tuple_lock)
5247 switch (wait_policy)
5261 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5262 errmsg(
"could not obtain lock on row in relation \"%s\"",
5266 *have_tuple_lock =
true;
5294 uint16 *result_infomask2)
5317 new_xmax = add_to_xmax;
5327 new_xmax = add_to_xmax;
5331 new_xmax = add_to_xmax;
5335 new_xmax = add_to_xmax;
5339 new_xmax = add_to_xmax;
5368 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5395 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5463 elog(
WARNING,
"LOCK_ONLY found for Xid in progress %u", xmax);
5465 old_infomask &= ~HEAP_XMAX_LOCK_ONLY;
5485 if (xmax == add_to_xmax)
5499 if (
mode < old_mode)
5510 add_to_xmax, new_status);
5550 *result_infomask = new_infomask;
5551 *result_infomask2 = new_infomask2;
5552 *result_xmax = new_xmax;
5676 bool cleared_all_frozen =
false;
5677 bool pinned_desired_page;
5715 pinned_desired_page =
true;
5718 pinned_desired_page =
false;
5798 for (
i = 0;
i < nmembers;
i++)
5831 if (result !=
TM_Ok)
5868 elog(
ERROR,
"invalid lock status in tuple");
5902 if (result !=
TM_Ok)
5912 &new_xmax, &new_infomask, &new_infomask2);
5917 cleared_all_frozen =
true;
5941 xlrec.
xmax = new_xmax;
6175 elog(
ERROR,
"attempted to kill a tuple inserted by another transaction");
6177 elog(
ERROR,
"attempted to kill a non-speculative tuple");
6204 prune_xid = relfrozenxid;
6320 void (*release_callback) (
void *),
void *
arg)
6326#ifdef USE_ASSERT_CHECKING
6328 check_inplace_rel_lock(oldtup_ptr);
6363 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6375 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6376 errmsg(
"tuple to be updated was already modified by an operation triggered by the current command")));
6396 release_callback(
arg);
6412 release_callback(
arg);
6420 ret = (result ==
TM_Ok);
6424 release_callback(
arg);
6465 bool RelcacheInitFileInval =
false;
6473 dst = (
char *) htup + htup->
t_hoff;
6479 &RelcacheInitFileInval);
6527 uintptr_t dst_offset_in_block;
6537 xlrec.
nmsgs = nmsgs;
6546 memcpy(copied_buffer.
data, origdata,
lower);
6548 dst_offset_in_block = dst - origdata;
6549 memcpy(copied_buffer.
data + dst_offset_in_block, src, newlen);
6563 memcpy(dst, src, newlen);
6607#define FRM_NOOP 0x0001
6608#define FRM_INVALIDATE_XMAX 0x0002
6609#define FRM_RETURN_IS_XID 0x0004
6610#define FRM_RETURN_IS_MULTI 0x0008
6611#define FRM_MARK_COMMITTED 0x0010
6672 bool update_committed;
6706 errmsg_internal(
"multixact %u from before multi freeze cutoff %u found to be still running",
6721 errmsg_internal(
"multixact %u contains update XID %u from before relfrozenxid %u",
6734 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
6782 need_replace =
false;
6784 for (
int i = 0;
i < nmembers;
i++)
6793 need_replace =
true;
6797 FreezePageRelfrozenXid = xid;
6829 has_lockers =
false;
6831 update_committed =
false;
6836 for (
int i = 0;
i < nmembers;
i++)
6855 errmsg_internal(
"multixact %u contains running locker XID %u from before removable cutoff %u",
6858 newmembers[nnewmembers++] = members[
i];
6899 update_committed =
true;
6918 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
6920 newmembers[nnewmembers++] = members[
i];
6929 if (nnewmembers == 0)
6944 Assert(nnewmembers == 1);
6946 if (update_committed)
6948 newxmax = update_xid;
7015 bool xmin_already_frozen =
false,
7016 xmax_already_frozen =
false;
7017 bool freeze_xmin =
false,
7018 replace_xvac =
false,
7019 replace_xmax =
false,
7020 freeze_xmax =
false;
7036 xmin_already_frozen =
true;
7129 frz->
xmax = newxmax;
7132 replace_xmax =
true;
7156 frz->
xmax = newxmax;
7157 replace_xmax =
true;
7199 xmax_already_frozen =
true;
7204 errmsg_internal(
"found raw xmax %u (infomask 0x%04x) not invalid and not multi",
7209 Assert(!xmin_already_frozen);
7228 Assert(!xmax_already_frozen && !freeze_xmax);
7235 Assert(!xmax_already_frozen && !replace_xmax);
7254 *totally_frozen = ((freeze_xmin || xmin_already_frozen) &&
7255 (freeze_xmax || xmax_already_frozen));
7258 xmax_already_frozen))
7271 return freeze_xmin || replace_xvac || replace_xmax || freeze_xmax;
7288 for (
int i = 0;
i < ntuples;
i++)
7340 for (
int i = 0;
i < ntuples;
i++)
7364 bool totally_frozen;
7375 pagefrz.freeze_required =
true;
7382 &pagefrz, &frz, &totally_frozen);
7410 bool has_update =
false;
7419 for (
i = 0;
i < nmembers;
i++)
7428 if (
mode > strongest)
7432 switch (members[
i].status)
7468 *new_infomask = bits;
7469 *new_infomask2 = bits2;
7502 for (
i = 0;
i < nmembers;
i++)
7510 update_xact = members[
i].
xid;
7511#ifndef USE_ASSERT_CHECKING
7556 bool result =
false;
7568 for (
i = 0;
i < nmembers;
i++)
7573 if (result && (current_is_member == NULL || *current_is_member))
7579 memxid = members[
i].
xid;
7582 if (current_is_member != NULL)
7583 *current_is_member =
true;
7652 uint16 infomask,
bool nowait,
7670 for (
i = 0;
i < nmembers;
i++)
7753 bool logLockFailure)
7828 bool freeze =
false;
7836 *NoFreezePageRelfrozenXid = xid;
7854 *NoFreezePageRelfrozenXid = xid;
7866 *NoFreezePageRelminMxid = multi;
7878 *NoFreezePageRelminMxid = multi;
7886 for (
int i = 0;
i < nmembers;
i++)
7888 xid = members[
i].
xid;
7891 *NoFreezePageRelfrozenXid = xid;
7906 *NoFreezePageRelfrozenXid = xid;
7939 *snapshotConflictHorizon = xvac;
7953 *snapshotConflictHorizon = xmax;
7969index_delete_prefetch_buffer(
Relation rel,
7970 IndexDeletePrefetchState *prefetch_state,
7973 BlockNumber cur_hblkno = prefetch_state->cur_hblkno;
7976 int ndeltids = prefetch_state->ndeltids;
7979 for (
i = prefetch_state->next_item;
7980 i < ndeltids && count < prefetch_count;
7998 prefetch_state->next_item =
i;
7999 prefetch_state->cur_hblkno = cur_hblkno;
8023 if (
unlikely(indexpagehoffnum > maxoff))
8025 (
errcode(ERRCODE_INDEX_CORRUPTED),
8026 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\"",
8035 (
errcode(ERRCODE_INDEX_CORRUPTED),
8036 errmsg_internal(
"heap tid from index tuple (%u,%u) points to unused heap page item at offset %u of block %u in index \"%s\"",
8051 (
errcode(ERRCODE_INDEX_CORRUPTED),
8052 errmsg_internal(
"heap tid from index tuple (%u,%u) points to heap-only tuple at offset %u of block %u in index \"%s\"",
8084 IndexDeletePrefetchState prefetch_state;
8085 int prefetch_distance;
8088 int finalndeltids = 0,
8089 nblocksaccessed = 0;
8092 int nblocksfavorable = 0;
8095 actualfreespace = 0;
8096 bool bottomup_final_block =
false;
8116 prefetch_state.next_item = 0;
8117 prefetch_state.ndeltids = delstate->
ndeltids;
8118 prefetch_state.deltids = delstate->
deltids;
8136 Assert(nblocksfavorable >= 1);
8138 prefetch_distance =
Min(prefetch_distance, nblocksfavorable);
8142 index_delete_prefetch_buffer(rel, &prefetch_state, prefetch_distance);
8185 if (bottomup_final_block)
8194 if (nblocksaccessed >= 1 && actualfreespace == lastfreespace)
8196 lastfreespace = actualfreespace;
8222 Assert(nblocksaccessed > 0 || nblocksfavorable > 0);
8223 if (nblocksfavorable > 0)
8226 curtargetfreespace /= 2;
8245 index_delete_prefetch_buffer(rel, &prefetch_state, 1);
8271 &heapTuple, NULL,
true))
8282 if (actualfreespace >= curtargetfreespace)
8283 bottomup_final_block =
true;
8307 if (offnum > maxoff)
8344 &snapshotConflictHorizon);
8362 finalndeltids =
i + 1;
8374 delstate->
ndeltids = finalndeltids;
8376 return snapshotConflictHorizon;
8393 return (blk1 < blk2) ? -1 : 1;
8400 return (pos1 < pos2) ? -1 : 1;
8430 const int gaps[9] = {1968, 861, 336, 112, 48, 21, 7, 3, 1};
8434 "element size exceeds 8 bytes");
8436 for (
int g = 0; g <
lengthof(gaps); g++)
8438 for (
int hi = gaps[g],
i = hi;
i < ndeltids;
i++)
8445 deltids[
j] = deltids[
j - hi];
8518 int64 lastblock = -1;
8519 int nblocksfavorable = 0;
8521 Assert(nblockgroups >= 1);
8533 for (
int b = 0;
b < nblockgroups;
b++)
8539 if (lastblock != -1 &&
8549 Assert(nblocksfavorable >= 1);
8551 return nblocksfavorable;
8586 if (ntids1 > ntids2)
8588 if (ntids1 < ntids2)
8636 int nblockgroups = 0;
8638 int nblocksfavorable = 0;
8662 blockgroups[nblockgroups - 1].
ntids = 1;
8667 blockgroups[nblockgroups - 1].
ntids++;
8702 for (
int b = 0;
b < nblockgroups;
b++)
8724 for (
int b = 0;
b < nblockgroups;
b++)
8729 memcpy(reordereddeltids + ncopied, firstdtid,
8731 ncopied += group->
ntids;
8735 memcpy(delstate->
deltids, reordereddeltids,
8739 pfree(reordereddeltids);
8742 return nblocksfavorable;
8771 xlrec.
flags = vmflags;
8797 bool all_visible_cleared,
bool new_all_visible_cleared)
8842 if (oldbuf == newbuf && !need_tuple_data &&
8851 for (prefixlen = 0; prefixlen <
Min(oldlen, newlen); prefixlen++)
8853 if (newp[prefixlen] != oldp[prefixlen])
8865 for (suffixlen = 0; suffixlen <
Min(oldlen, newlen) - prefixlen; suffixlen++)
8867 if (newp[newlen - suffixlen - 1] != oldp[oldlen - suffixlen - 1])
8876 if (all_visible_cleared)
8878 if (new_all_visible_cleared)
8884 if (need_tuple_data)
8889 if (reln->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
8919 if (need_tuple_data)
8923 if (oldbuf != newbuf)
8931 if (prefixlen > 0 || suffixlen > 0)
8933 if (prefixlen > 0 && suffixlen > 0)
8935 prefix_suffix[0] = prefixlen;
8936 prefix_suffix[1] = suffixlen;
8939 else if (prefixlen > 0)
8987 if (need_tuple_data && old_key_tuple)
9101 char replident = relation->
rd_rel->relreplident;
9112 if (replident == REPLICA_IDENTITY_NOTHING)
9115 if (replident == REPLICA_IDENTITY_FULL)
9153 for (
int i = 0;
i < desc->
natts;
i++)
9257 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 BufferGetTag(Buffer buffer, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
int maintenance_io_concurrency
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define BUFFER_LOCK_UNLOCK
#define BUFFER_LOCK_SHARE
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static Block BufferGetBlock(Buffer buffer)
#define BUFFER_LOCK_EXCLUSIVE
static bool BufferIsValid(Buffer bufnum)
Size PageGetHeapFreeSpace(const PageData *page)
PageHeaderData * PageHeader
static bool PageIsAllVisible(const PageData *page)
static void PageClearAllVisible(Page page)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
#define SizeOfPageHeaderData
static void PageSetAllVisible(Page page)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
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)
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)
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
void FreeAccessStrategy(BufferAccessStrategy strategy)
Assert(PointerIsAligned(start, uint64))
static bool DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask, LockTupleMode lockmode, bool *current_is_member)
void heap_finish_speculative(Relation relation, ItemPointer tid)
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 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 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)
void simple_heap_delete(Relation relation, ItemPointer tid)
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)
TM_Result heap_delete(Relation relation, ItemPointer tid, CommandId cid, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, bool changingPart)
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)
static void index_delete_check_htid(TM_IndexDeleteOp *delstate, Page page, OffsetNumber maxoff, ItemPointer htid, TM_IndexStatus *istatus)
#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)
static int index_delete_sort_cmp(TM_IndexDelete *deltid1, TM_IndexDelete *deltid2)
TM_Result heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, CommandId cid, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes)
static bool ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, Relation rel, int *remaining, bool logLockFailure)
bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple)
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)
#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)
static bool heap_acquire_tuplock(Relation relation, ItemPointer tid, LockTupleMode mode, LockWaitPolicy wait_policy, bool *have_tuple_lock)
static TM_Result heap_lock_updated_tuple(Relation rel, HeapTuple tuple, ItemPointer ctid, TransactionId xid, LockTupleMode mode)
#define BOTTOMUP_MAX_NBLOCKS
void ReleaseBulkInsertStatePin(BulkInsertState bistate)
static void MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, Relation rel, ItemPointer ctid, XLTW_Oper oper, int *remaining)
#define FRM_MARK_COMMITTED
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)
static bool Do_MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, bool nowait, Relation rel, ItemPointer ctid, XLTW_Oper oper, int *remaining, bool logLockFailure)
void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup, TU_UpdateIndexes *update_indexes)
void heap_freeze_prepared_tuples(Buffer buffer, HeapTupleFreeze *tuples, int ntuples)
bool heap_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
void heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid, ItemPointer maxtid)
void heap_abort_speculative(Relation relation, ItemPointer 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 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 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 TM_Result heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, LockTupleMode mode)
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
static bool HEAP_XMAX_IS_SHR_LOCKED(int16 infomask)
#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_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)
static bool HEAP_XMAX_IS_KEYSHR_LOCKED(int16 infomask)
#define HEAP_XMAX_IS_MULTI
#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 void HeapTupleHeaderSetXmin(HeapTupleHeaderData *tup, TransactionId xid)
static bool HEAP_LOCKED_UPGRADED(uint16 infomask)
#define HEAP_XMAX_KEYSHR_LOCK
static bool HEAP_XMAX_IS_EXCL_LOCKED(int16 infomask)
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)
void CacheInvalidateHeapTupleInplace(Relation relation, HeapTuple tuple, HeapTuple newtuple)
void AcceptInvalidationMessages(void)
int inplaceGetInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
void PreInplace_Inval(void)
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(ItemPointer arg1, ItemPointer arg2)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer 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 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 XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, XLTW_Oper oper)
bool ConditionalXactLockTableWait(TransactionId xid, bool logLockFailure)
void LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
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 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
#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 CheckForSerializableConflictOut(Relation relation, TransactionId xid, Snapshot snapshot)
void CheckForSerializableConflictIn(Relation relation, ItemPointer tid, BlockNumber blkno)
void PredicateLockTID(Relation relation, ItemPointer tid, Snapshot snapshot, TransactionId tuple_xid)
void PredicateLockRelation(Relation relation, Snapshot snapshot)
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
void InvalidateCatalogSnapshot(void)
#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 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 TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
bool TransactionIdDidAbort(TransactionId transactionId)
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
#define InvalidTransactionId
#define TransactionIdEquals(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static bool HeapKeyTest(HeapTuple tuple, TupleDesc tupdesc, int nkeys, ScanKey keys)
#define VARATT_IS_EXTERNAL(PTR)
bool visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf)
bool visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer vmbuf, uint8 flags)
void visibilitymap_pin(Relation rel, BlockNumber heapBlk, Buffer *vmbuf)
uint8 visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf, XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid, uint8 flags)
#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()
#define InvalidXLogRecPtr
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)