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)])
222#ifdef USE_ASSERT_CHECKING
248 void *callback_private_data,
249 void *per_buffer_data)
286 void *callback_private_data,
287 void *per_buffer_data)
311 void *per_buffer_data)
394 allow_strat = allow_sync =
false;
417 else if (keep_startblock)
489 Assert(startBlk == 0 || startBlk < scan->rs_nblocks);
505 bool all_visible,
bool check_serializable)
529 if (check_serializable)
531 &loctup, buffer, snapshot);
561 bool check_serializable;
616 if (
likely(!check_serializable))
618 block, lines,
true,
false);
621 block, lines,
true,
true);
625 if (
likely(!check_serializable))
627 block, lines,
false,
false);
630 block, lines,
false,
true);
790 *linesleft = *lineoff;
939 for (; linesleft > 0; linesleft--, lineoff += dir)
1048 linesleft = scan->rs_ntuples;
1057 for (; linesleft > 0; linesleft--, lineindex += dir)
1062 Assert(lineindex <= scan->rs_ntuples);
1063 lineoff = scan->rs_vistuples[lineindex];
1077 scan->rs_cindex = lineindex;
1152 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
1153 errmsg(
"cannot query non-catalog table \"%s\" during logical decoding",
1188 if (parallel_scan != NULL)
1255 bool allow_strat,
bool allow_sync,
bool allow_pagemode)
1359 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1370 elog(
ERROR,
"unexpected heap_getnext call during logical decoding");
1727 bool *all_dead,
bool first_call)
1733 bool at_chain_start;
1740 *all_dead = first_call;
1744 at_chain_start = first_call;
1770 at_chain_start =
false;
1837 if (all_dead && *all_dead)
1855 at_chain_start =
false;
2095 bool all_visible_cleared =
false;
2145 all_visible_cleared =
true;
2196 if (all_visible_cleared)
2290 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2291 errmsg(
"cannot insert tuples in a parallel worker")));
2308 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
2309 relation->
rd_rel->relkind != RELKIND_MATVIEW)
2332 for (
int i = done;
i < ntuples;
i++)
2336 if (page_avail < tup_sz)
2341 page_avail -= tup_sz;
2373 bool starting_with_empty_page =
false;
2375 int npages_used = 0;
2388 for (
i = 0;
i < ntuples;
i++)
2425 while (ndone < ntuples)
2428 bool all_visible_cleared =
false;
2429 bool all_frozen_set =
false;
2444 if (ndone == 0 || !starting_with_empty_page)
2463 npages - npages_used);
2469 all_frozen_set =
true;
2484 if (needwal && need_cids)
2487 for (nthispage = 1; ndone + nthispage < ntuples; nthispage++)
2489 HeapTuple heaptup = heaptuples[ndone + nthispage];
2500 if (needwal && need_cids)
2513 all_visible_cleared =
true;
2519 else if (all_frozen_set)
2536 char *scratchptr = scratch.
data;
2544 init = starting_with_empty_page;
2560 tupledata = scratchptr;
2563 Assert(!(all_visible_cleared && all_frozen_set));
2566 if (all_visible_cleared)
2577 for (
i = 0;
i < nthispage;
i++)
2599 scratchptr += datalen;
2601 totaldatalen = scratchptr - tupledata;
2602 Assert((scratchptr - scratch.
data) < BLCKSZ);
2604 if (need_tuple_data)
2612 if (ndone + nthispage == ntuples)
2625 if (need_tuple_data)
2699 for (
i = 0;
i < ntuples;
i++)
2704 for (
i = 0;
i < ntuples;
i++)
2705 slots[
i]->tts_tid = heaptuples[
i]->t_self;
2757 const uint16 interesting =
2760 if ((new_infomask & interesting) != (old_infomask & interesting))
2793 bool have_tuple_lock =
false;
2795 bool all_visible_cleared =
false;
2797 bool old_key_copied =
false;
2810 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2811 errmsg(
"cannot delete tuples during a parallel operation")));
2857 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2858 errmsg(
"attempted to delete invisible tuple")));
2884 bool current_is_member =
false;
2895 if (!current_is_member)
2975 if (result !=
TM_Ok)
2993 if (result !=
TM_Ok)
3002 if (have_tuple_lock)
3042 &new_xmax, &new_infomask, &new_infomask2);
3057 all_visible_cleared =
true;
3100 if (all_visible_cleared)
3107 xlrec.
xmax = new_xmax;
3109 if (old_key_tuple != NULL)
3111 if (relation->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
3125 if (old_key_tuple != NULL)
3134 old_key_tuple->
t_len
3159 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3160 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3181 if (have_tuple_lock)
3186 if (old_key_tuple != NULL && old_key_copied)
3214 elog(
ERROR,
"tuple already updated by self");
3222 elog(
ERROR,
"tuple concurrently updated");
3226 elog(
ERROR,
"tuple concurrently deleted");
3230 elog(
ERROR,
"unrecognized heap_delete status: %u", result);
3264 bool old_key_copied =
false;
3275 bool have_tuple_lock =
false;
3277 bool use_hot_update =
false;
3278 bool summarized_update =
false;
3280 bool all_visible_cleared =
false;
3281 bool all_visible_cleared_new =
false;
3282 bool checked_lockers;
3283 bool locker_remains;
3284 bool id_has_external =
false;
3287 uint16 infomask_old_tuple,
3288 infomask2_old_tuple,
3290 infomask2_new_tuple;
3307 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3308 errmsg(
"cannot update tuples during a parallel operation")));
3310#ifdef USE_ASSERT_CHECKING
3311 check_lock_if_inplace_updateable_rel(relation, otid, newtup);
3337 interesting_attrs = NULL;
3389 Assert(!have_tuple_lock);
3428 newtup, &id_has_external);
3473 checked_lockers =
false;
3474 locker_remains =
false;
3484 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3485 errmsg(
"attempted to update invisible tuple")));
3491 bool can_continue =
false;
3536 bool current_is_member =
false;
3539 *lockmode, ¤t_is_member))
3547 if (!current_is_member)
3555 checked_lockers =
true;
3556 locker_remains = remain != 0;
3603 can_continue =
true;
3611 checked_lockers =
true;
3612 locker_remains =
true;
3613 can_continue =
true;
3622 checked_lockers =
true;
3623 locker_remains =
true;
3624 can_continue =
true;
3637 checked_lockers =
true;
3653 can_continue =
true;
3665 if (result !=
TM_Ok)
3683 if (result !=
TM_Ok)
3692 if (have_tuple_lock)
3733 xid, *lockmode,
true,
3734 &xmax_old_tuple, &infomask_old_tuple,
3735 &infomask2_old_tuple);
3746 (checked_lockers && !locker_remains))
3754 infomask2_new_tuple = 0;
3767 &infomask2_new_tuple);
3772 infomask2_new_tuple = 0;
3805 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3806 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3822 if (need_toast || newtupsize > pagefree)
3825 uint16 infomask_lock_old_tuple,
3826 infomask2_lock_old_tuple;
3827 bool cleared_all_frozen =
false;
3850 xid, *lockmode,
false,
3851 &xmax_lock_old_tuple, &infomask_lock_old_tuple,
3852 &infomask2_lock_old_tuple);
3881 cleared_all_frozen =
true;
3894 xlrec.
xmax = xmax_lock_old_tuple;
3949 if (newtupsize > pagefree)
3954 &vmbuffer_new, &vmbuffer,
3966 if (newtupsize > pagefree ||
4014 if (newbuf == buffer)
4023 use_hot_update =
true;
4033 summarized_update =
true;
4107 all_visible_cleared =
true;
4114 all_visible_cleared_new =
true;
4120 if (newbuf != buffer)
4140 newbuf, &oldtup, heaptup,
4142 all_visible_cleared,
4143 all_visible_cleared_new);
4144 if (newbuf != buffer)
4153 if (newbuf != buffer)
4168 if (newbuf != buffer)
4179 if (have_tuple_lock)
4188 if (heaptup != newtup)
4202 if (summarized_update)
4208 *update_indexes =
TU_All;
4210 if (old_key_tuple != NULL && old_key_copied)
4223#ifdef USE_ASSERT_CHECKING
4229check_lock_if_inplace_updateable_rel(
Relation relation,
4236 case RelationRelationId:
4237 case DatabaseRelationId:
4257 case RelationRelationId:
4261 Oid relid = classForm->oid;
4270 if (classForm->relkind == RELKIND_INDEX)
4283 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4291 case DatabaseRelationId:
4297 "missing lock on database \"%s\" (OID %u) @ TID (%u,%u)",
4315 Oid relid = classForm->oid;
4324 if (classForm->relkind == RELKIND_INDEX)
4336 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4351 bool isnull1,
bool isnull2)
4357 if (isnull1 != isnull2)
4384 Assert(attrnum <= tupdesc->natts);
4452 value1 =
heap_getattr(oldtup, attrnum, tupdesc, &isnull1);
4453 value2 =
heap_getattr(newtup, attrnum, tupdesc, &isnull2);
4456 value2, isnull1, isnull2))
4466 if (attrnum < 0 || isnull1 ||
4476 *has_external =
true;
4501 &tmfd, &lockmode, update_indexes);
4506 elog(
ERROR,
"tuple already updated by self");
4514 elog(
ERROR,
"tuple concurrently updated");
4518 elog(
ERROR,
"tuple concurrently deleted");
4522 elog(
ERROR,
"unrecognized heap_update status: %u", result);
4543 is_update ?
"true" :
"false");
4581 bool follow_updates,
4595 bool first_time =
true;
4596 bool skip_tuple_lock =
false;
4597 bool have_tuple_lock =
false;
4598 bool cleared_all_frozen =
false;
4685 for (
i = 0;
i < nmembers;
i++)
4710 skip_tuple_lock =
true;
4759 require_sleep =
true;
4793 if (follow_updates && updated)
4824 require_sleep =
false;
4853 require_sleep =
false;
4879 require_sleep =
false;
4892 require_sleep =
false;
4918 require_sleep =
false;
4937 else if (require_sleep)
4949 if (!skip_tuple_lock &&
4969 elog(
ERROR,
"invalid lock mode in heap_lock_tuple");
4972 switch (wait_policy)
4980 status, infomask, relation,
4991 status, infomask, relation,
4994 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
4995 errmsg(
"could not obtain lock on row in relation \"%s\"",
5014 switch (wait_policy)
5032 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5033 errmsg(
"could not obtain lock on row in relation \"%s\"",
5089 if (!require_sleep ||
5101 if (result !=
TM_Ok)
5163 &xid, &new_infomask, &new_infomask2);
5199 cleared_all_frozen =
true;
5258 if (have_tuple_lock)
5280 if (*have_tuple_lock)
5283 switch (wait_policy)
5297 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5298 errmsg(
"could not obtain lock on row in relation \"%s\"",
5302 *have_tuple_lock =
true;
5330 uint16 *result_infomask2)
5353 new_xmax = add_to_xmax;
5363 new_xmax = add_to_xmax;
5367 new_xmax = add_to_xmax;
5371 new_xmax = add_to_xmax;
5375 new_xmax = add_to_xmax;
5404 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5431 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5499 elog(
WARNING,
"LOCK_ONLY found for Xid in progress %u", xmax);
5501 old_infomask &= ~HEAP_XMAX_LOCK_ONLY;
5521 if (xmax == add_to_xmax)
5535 if (
mode < old_mode)
5546 add_to_xmax, new_status);
5586 *result_infomask = new_infomask;
5587 *result_infomask2 = new_infomask2;
5588 *result_xmax = new_xmax;
5712 bool cleared_all_frozen =
false;
5713 bool pinned_desired_page;
5751 pinned_desired_page =
true;
5754 pinned_desired_page =
false;
5834 for (
i = 0;
i < nmembers;
i++)
5867 if (result !=
TM_Ok)
5904 elog(
ERROR,
"invalid lock status in tuple");
5938 if (result !=
TM_Ok)
5948 &new_xmax, &new_infomask, &new_infomask2);
5953 cleared_all_frozen =
true;
5977 xlrec.
xmax = new_xmax;
6211 elog(
ERROR,
"attempted to kill a tuple inserted by another transaction");
6213 elog(
ERROR,
"attempted to kill a non-speculative tuple");
6240 prune_xid = relfrozenxid;
6356 void (*release_callback) (
void *),
void *
arg)
6362#ifdef USE_ASSERT_CHECKING
6364 check_inplace_rel_lock(oldtup_ptr);
6399 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6411 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6412 errmsg(
"tuple to be updated was already modified by an operation triggered by the current command")));
6432 release_callback(
arg);
6448 release_callback(
arg);
6456 ret = (result ==
TM_Ok);
6460 release_callback(
arg);
6501 bool RelcacheInitFileInval =
false;
6509 dst = (
char *) htup + htup->
t_hoff;
6515 &RelcacheInitFileInval);
6571 uintptr_t dst_offset_in_block;
6581 xlrec.
nmsgs = nmsgs;
6590 memcpy(copied_buffer.
data, origdata,
lower);
6592 dst_offset_in_block = dst - origdata;
6593 memcpy(copied_buffer.
data + dst_offset_in_block, src, newlen);
6607 memcpy(dst, src, newlen);
6651#define FRM_NOOP 0x0001
6652#define FRM_INVALIDATE_XMAX 0x0002
6653#define FRM_RETURN_IS_XID 0x0004
6654#define FRM_RETURN_IS_MULTI 0x0008
6655#define FRM_MARK_COMMITTED 0x0010
6716 bool update_committed;
6750 errmsg_internal(
"multixact %u from before multi freeze cutoff %u found to be still running",
6765 errmsg_internal(
"multixact %u contains update XID %u from before relfrozenxid %u",
6778 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
6826 need_replace =
false;
6828 for (
int i = 0;
i < nmembers;
i++)
6837 need_replace =
true;
6841 FreezePageRelfrozenXid = xid;
6873 has_lockers =
false;
6875 update_committed =
false;
6880 for (
int i = 0;
i < nmembers;
i++)
6899 errmsg_internal(
"multixact %u contains running locker XID %u from before removable cutoff %u",
6902 newmembers[nnewmembers++] = members[
i];
6943 update_committed =
true;
6962 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
6964 newmembers[nnewmembers++] = members[
i];
6973 if (nnewmembers == 0)
6988 Assert(nnewmembers == 1);
6990 if (update_committed)
6992 newxmax = update_xid;
7059 bool xmin_already_frozen =
false,
7060 xmax_already_frozen =
false;
7061 bool freeze_xmin =
false,
7062 replace_xvac =
false,
7063 replace_xmax =
false,
7064 freeze_xmax =
false;
7080 xmin_already_frozen =
true;
7173 frz->
xmax = newxmax;
7176 replace_xmax =
true;
7200 frz->
xmax = newxmax;
7201 replace_xmax =
true;
7243 xmax_already_frozen =
true;
7248 errmsg_internal(
"found raw xmax %u (infomask 0x%04x) not invalid and not multi",
7253 Assert(!xmin_already_frozen);
7272 Assert(!xmax_already_frozen && !freeze_xmax);
7279 Assert(!xmax_already_frozen && !replace_xmax);
7298 *totally_frozen = ((freeze_xmin || xmin_already_frozen) &&
7299 (freeze_xmax || xmax_already_frozen));
7302 xmax_already_frozen))
7315 return freeze_xmin || replace_xvac || replace_xmax || freeze_xmax;
7332 for (
int i = 0;
i < ntuples;
i++)
7384 for (
int i = 0;
i < ntuples;
i++)
7408 bool totally_frozen;
7419 pagefrz.freeze_required =
true;
7426 &pagefrz, &frz, &totally_frozen);
7454 bool has_update =
false;
7463 for (
i = 0;
i < nmembers;
i++)
7472 if (
mode > strongest)
7476 switch (members[
i].status)
7512 *new_infomask = bits;
7513 *new_infomask2 = bits2;
7546 for (
i = 0;
i < nmembers;
i++)
7554 update_xact = members[
i].
xid;
7555#ifndef USE_ASSERT_CHECKING
7600 bool result =
false;
7612 for (
i = 0;
i < nmembers;
i++)
7617 if (result && (current_is_member == NULL || *current_is_member))
7623 memxid = members[
i].
xid;
7626 if (current_is_member != NULL)
7627 *current_is_member =
true;
7696 uint16 infomask,
bool nowait,
7714 for (
i = 0;
i < nmembers;
i++)
7797 bool logLockFailure)
7872 bool freeze =
false;
7880 *NoFreezePageRelfrozenXid = xid;
7898 *NoFreezePageRelfrozenXid = xid;
7910 *NoFreezePageRelminMxid = multi;
7922 *NoFreezePageRelminMxid = multi;
7930 for (
int i = 0;
i < nmembers;
i++)
7932 xid = members[
i].
xid;
7935 *NoFreezePageRelfrozenXid = xid;
7950 *NoFreezePageRelfrozenXid = xid;
7983 *snapshotConflictHorizon = xvac;
7997 *snapshotConflictHorizon = xmax;
8013index_delete_prefetch_buffer(
Relation rel,
8014 IndexDeletePrefetchState *prefetch_state,
8017 BlockNumber cur_hblkno = prefetch_state->cur_hblkno;
8020 int ndeltids = prefetch_state->ndeltids;
8023 for (
i = prefetch_state->next_item;
8024 i < ndeltids && count < prefetch_count;
8042 prefetch_state->next_item =
i;
8043 prefetch_state->cur_hblkno = cur_hblkno;
8067 if (
unlikely(indexpagehoffnum > maxoff))
8069 (
errcode(ERRCODE_INDEX_CORRUPTED),
8070 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\"",
8079 (
errcode(ERRCODE_INDEX_CORRUPTED),
8080 errmsg_internal(
"heap tid from index tuple (%u,%u) points to unused heap page item at offset %u of block %u in index \"%s\"",
8095 (
errcode(ERRCODE_INDEX_CORRUPTED),
8096 errmsg_internal(
"heap tid from index tuple (%u,%u) points to heap-only tuple at offset %u of block %u in index \"%s\"",
8128 IndexDeletePrefetchState prefetch_state;
8129 int prefetch_distance;
8132 int finalndeltids = 0,
8133 nblocksaccessed = 0;
8136 int nblocksfavorable = 0;
8139 actualfreespace = 0;
8140 bool bottomup_final_block =
false;
8160 prefetch_state.next_item = 0;
8161 prefetch_state.ndeltids = delstate->
ndeltids;
8162 prefetch_state.deltids = delstate->
deltids;
8180 Assert(nblocksfavorable >= 1);
8182 prefetch_distance =
Min(prefetch_distance, nblocksfavorable);
8186 index_delete_prefetch_buffer(rel, &prefetch_state, prefetch_distance);
8229 if (bottomup_final_block)
8238 if (nblocksaccessed >= 1 && actualfreespace == lastfreespace)
8240 lastfreespace = actualfreespace;
8266 Assert(nblocksaccessed > 0 || nblocksfavorable > 0);
8267 if (nblocksfavorable > 0)
8270 curtargetfreespace /= 2;
8289 index_delete_prefetch_buffer(rel, &prefetch_state, 1);
8315 &heapTuple, NULL,
true))
8326 if (actualfreespace >= curtargetfreespace)
8327 bottomup_final_block =
true;
8351 if (offnum > maxoff)
8388 &snapshotConflictHorizon);
8406 finalndeltids =
i + 1;
8418 delstate->
ndeltids = finalndeltids;
8420 return snapshotConflictHorizon;
8437 return (blk1 < blk2) ? -1 : 1;
8444 return (pos1 < pos2) ? -1 : 1;
8474 const int gaps[9] = {1968, 861, 336, 112, 48, 21, 7, 3, 1};
8478 "element size exceeds 8 bytes");
8480 for (
int g = 0; g <
lengthof(gaps); g++)
8482 for (
int hi = gaps[g],
i = hi;
i < ndeltids;
i++)
8489 deltids[
j] = deltids[
j - hi];
8562 int64 lastblock = -1;
8563 int nblocksfavorable = 0;
8565 Assert(nblockgroups >= 1);
8577 for (
int b = 0;
b < nblockgroups;
b++)
8583 if (lastblock != -1 &&
8593 Assert(nblocksfavorable >= 1);
8595 return nblocksfavorable;
8630 if (ntids1 > ntids2)
8632 if (ntids1 < ntids2)
8680 int nblockgroups = 0;
8682 int nblocksfavorable = 0;
8706 blockgroups[nblockgroups - 1].
ntids = 1;
8711 blockgroups[nblockgroups - 1].
ntids++;
8746 for (
int b = 0;
b < nblockgroups;
b++)
8768 for (
int b = 0;
b < nblockgroups;
b++)
8773 memcpy(reordereddeltids + ncopied, firstdtid,
8775 ncopied += group->
ntids;
8779 memcpy(delstate->
deltids, reordereddeltids,
8783 pfree(reordereddeltids);
8786 return nblocksfavorable;
8815 xlrec.
flags = vmflags;
8841 bool all_visible_cleared,
bool new_all_visible_cleared)
8886 if (oldbuf == newbuf && !need_tuple_data &&
8895 for (prefixlen = 0; prefixlen <
Min(oldlen, newlen); prefixlen++)
8897 if (newp[prefixlen] != oldp[prefixlen])
8909 for (suffixlen = 0; suffixlen <
Min(oldlen, newlen) - prefixlen; suffixlen++)
8911 if (newp[newlen - suffixlen - 1] != oldp[oldlen - suffixlen - 1])
8920 if (all_visible_cleared)
8922 if (new_all_visible_cleared)
8928 if (need_tuple_data)
8933 if (reln->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
8963 if (need_tuple_data)
8967 if (oldbuf != newbuf)
8975 if (prefixlen > 0 || suffixlen > 0)
8977 if (prefixlen > 0 && suffixlen > 0)
8979 prefix_suffix[0] = prefixlen;
8980 prefix_suffix[1] = suffixlen;
8983 else if (prefixlen > 0)
9031 if (need_tuple_data && old_key_tuple)
9145 char replident = relation->
rd_rel->relreplident;
9156 if (replident == REPLICA_IDENTITY_NOTHING)
9159 if (replident == REPLICA_IDENTITY_FULL)
9197 for (
int i = 0;
i < desc->
natts;
i++)
9301 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)
#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)
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 void AssertHasSnapshotForToast(Relation rel)
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, arg)
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 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
#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
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
struct TableScanDescData::@50::@51 tidrange
TBMIterator rs_tbmiterator
ItemPointerData rs_mintid
ItemPointerData rs_maxtid
struct ScanKeyData * rs_key
struct SnapshotData * rs_snapshot
union TableScanDescData::@50 st
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)
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(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)