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);
2470 all_frozen_set =
true;
2488 if (needwal && need_cids)
2491 for (nthispage = 1; ndone + nthispage < ntuples; nthispage++)
2493 HeapTuple heaptup = heaptuples[ndone + nthispage];
2504 if (needwal && need_cids)
2518 all_visible_cleared =
true;
2524 else if (all_frozen_set)
2548 char *scratchptr = scratch.
data;
2556 init = starting_with_empty_page;
2572 tupledata = scratchptr;
2575 Assert(!(all_visible_cleared && all_frozen_set));
2578 if (all_visible_cleared)
2595 for (
i = 0;
i < nthispage;
i++)
2617 scratchptr += datalen;
2619 totaldatalen = scratchptr - tupledata;
2620 Assert((scratchptr - scratch.
data) < BLCKSZ);
2622 if (need_tuple_data)
2630 if (ndone + nthispage == ntuples)
2643 if (need_tuple_data)
2710 for (
i = 0;
i < ntuples;
i++)
2715 for (
i = 0;
i < ntuples;
i++)
2716 slots[
i]->tts_tid = heaptuples[
i]->t_self;
2768 const uint16 interesting =
2771 if ((new_infomask & interesting) != (old_infomask & interesting))
2804 bool have_tuple_lock =
false;
2806 bool all_visible_cleared =
false;
2808 bool old_key_copied =
false;
2821 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2822 errmsg(
"cannot delete tuples during a parallel operation")));
2868 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2869 errmsg(
"attempted to delete invisible tuple")));
2895 bool current_is_member =
false;
2906 if (!current_is_member)
2986 if (result !=
TM_Ok)
3004 if (result !=
TM_Ok)
3013 if (have_tuple_lock)
3053 &new_xmax, &new_infomask, &new_infomask2);
3068 all_visible_cleared =
true;
3111 if (all_visible_cleared)
3118 xlrec.
xmax = new_xmax;
3120 if (old_key_tuple != NULL)
3122 if (relation->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
3136 if (old_key_tuple != NULL)
3145 old_key_tuple->
t_len
3170 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3171 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3192 if (have_tuple_lock)
3197 if (old_key_tuple != NULL && old_key_copied)
3225 elog(
ERROR,
"tuple already updated by self");
3233 elog(
ERROR,
"tuple concurrently updated");
3237 elog(
ERROR,
"tuple concurrently deleted");
3241 elog(
ERROR,
"unrecognized heap_delete status: %u", result);
3275 bool old_key_copied =
false;
3286 bool have_tuple_lock =
false;
3288 bool use_hot_update =
false;
3289 bool summarized_update =
false;
3291 bool all_visible_cleared =
false;
3292 bool all_visible_cleared_new =
false;
3293 bool checked_lockers;
3294 bool locker_remains;
3295 bool id_has_external =
false;
3298 uint16 infomask_old_tuple,
3299 infomask2_old_tuple,
3301 infomask2_new_tuple;
3318 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3319 errmsg(
"cannot update tuples during a parallel operation")));
3321#ifdef USE_ASSERT_CHECKING
3322 check_lock_if_inplace_updateable_rel(relation, otid, newtup);
3348 interesting_attrs = NULL;
3400 Assert(!have_tuple_lock);
3439 newtup, &id_has_external);
3484 checked_lockers =
false;
3485 locker_remains =
false;
3495 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3496 errmsg(
"attempted to update invisible tuple")));
3502 bool can_continue =
false;
3547 bool current_is_member =
false;
3550 *lockmode, ¤t_is_member))
3558 if (!current_is_member)
3566 checked_lockers =
true;
3567 locker_remains = remain != 0;
3614 can_continue =
true;
3622 checked_lockers =
true;
3623 locker_remains =
true;
3624 can_continue =
true;
3633 checked_lockers =
true;
3634 locker_remains =
true;
3635 can_continue =
true;
3648 checked_lockers =
true;
3664 can_continue =
true;
3676 if (result !=
TM_Ok)
3694 if (result !=
TM_Ok)
3703 if (have_tuple_lock)
3744 xid, *lockmode,
true,
3745 &xmax_old_tuple, &infomask_old_tuple,
3746 &infomask2_old_tuple);
3757 (checked_lockers && !locker_remains))
3765 infomask2_new_tuple = 0;
3778 &infomask2_new_tuple);
3783 infomask2_new_tuple = 0;
3816 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3817 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3833 if (need_toast || newtupsize > pagefree)
3836 uint16 infomask_lock_old_tuple,
3837 infomask2_lock_old_tuple;
3838 bool cleared_all_frozen =
false;
3861 xid, *lockmode,
false,
3862 &xmax_lock_old_tuple, &infomask_lock_old_tuple,
3863 &infomask2_lock_old_tuple);
3892 cleared_all_frozen =
true;
3905 xlrec.
xmax = xmax_lock_old_tuple;
3960 if (newtupsize > pagefree)
3965 &vmbuffer_new, &vmbuffer,
3977 if (newtupsize > pagefree ||
4025 if (newbuf == buffer)
4034 use_hot_update =
true;
4044 summarized_update =
true;
4118 all_visible_cleared =
true;
4125 all_visible_cleared_new =
true;
4131 if (newbuf != buffer)
4151 newbuf, &oldtup, heaptup,
4153 all_visible_cleared,
4154 all_visible_cleared_new);
4155 if (newbuf != buffer)
4164 if (newbuf != buffer)
4179 if (newbuf != buffer)
4190 if (have_tuple_lock)
4199 if (heaptup != newtup)
4213 if (summarized_update)
4219 *update_indexes =
TU_All;
4221 if (old_key_tuple != NULL && old_key_copied)
4234#ifdef USE_ASSERT_CHECKING
4240check_lock_if_inplace_updateable_rel(
Relation relation,
4247 case RelationRelationId:
4248 case DatabaseRelationId:
4268 case RelationRelationId:
4272 Oid relid = classForm->oid;
4281 if (classForm->relkind == RELKIND_INDEX)
4294 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4302 case DatabaseRelationId:
4308 "missing lock on database \"%s\" (OID %u) @ TID (%u,%u)",
4326 Oid relid = classForm->oid;
4335 if (classForm->relkind == RELKIND_INDEX)
4347 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4362 bool isnull1,
bool isnull2)
4368 if (isnull1 != isnull2)
4395 Assert(attrnum <= tupdesc->natts);
4463 value1 =
heap_getattr(oldtup, attrnum, tupdesc, &isnull1);
4464 value2 =
heap_getattr(newtup, attrnum, tupdesc, &isnull2);
4467 value2, isnull1, isnull2))
4477 if (attrnum < 0 || isnull1 ||
4487 *has_external =
true;
4512 &tmfd, &lockmode, update_indexes);
4517 elog(
ERROR,
"tuple already updated by self");
4525 elog(
ERROR,
"tuple concurrently updated");
4529 elog(
ERROR,
"tuple concurrently deleted");
4533 elog(
ERROR,
"unrecognized heap_update status: %u", result);
4554 is_update ?
"true" :
"false");
4592 bool follow_updates,
4606 bool first_time =
true;
4607 bool skip_tuple_lock =
false;
4608 bool have_tuple_lock =
false;
4609 bool cleared_all_frozen =
false;
4696 for (
i = 0;
i < nmembers;
i++)
4721 skip_tuple_lock =
true;
4770 require_sleep =
true;
4804 if (follow_updates && updated)
4835 require_sleep =
false;
4864 require_sleep =
false;
4890 require_sleep =
false;
4903 require_sleep =
false;
4929 require_sleep =
false;
4948 else if (require_sleep)
4960 if (!skip_tuple_lock &&
4980 elog(
ERROR,
"invalid lock mode in heap_lock_tuple");
4983 switch (wait_policy)
4991 status, infomask, relation,
5002 status, infomask, relation,
5005 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5006 errmsg(
"could not obtain lock on row in relation \"%s\"",
5025 switch (wait_policy)
5043 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5044 errmsg(
"could not obtain lock on row in relation \"%s\"",
5100 if (!require_sleep ||
5112 if (result !=
TM_Ok)
5174 &xid, &new_infomask, &new_infomask2);
5210 cleared_all_frozen =
true;
5269 if (have_tuple_lock)
5291 if (*have_tuple_lock)
5294 switch (wait_policy)
5308 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5309 errmsg(
"could not obtain lock on row in relation \"%s\"",
5313 *have_tuple_lock =
true;
5341 uint16 *result_infomask2)
5364 new_xmax = add_to_xmax;
5374 new_xmax = add_to_xmax;
5378 new_xmax = add_to_xmax;
5382 new_xmax = add_to_xmax;
5386 new_xmax = add_to_xmax;
5415 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5442 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5510 elog(
WARNING,
"LOCK_ONLY found for Xid in progress %u", xmax);
5512 old_infomask &= ~HEAP_XMAX_LOCK_ONLY;
5532 if (xmax == add_to_xmax)
5546 if (
mode < old_mode)
5557 add_to_xmax, new_status);
5597 *result_infomask = new_infomask;
5598 *result_infomask2 = new_infomask2;
5599 *result_xmax = new_xmax;
5723 bool cleared_all_frozen =
false;
5724 bool pinned_desired_page;
5762 pinned_desired_page =
true;
5765 pinned_desired_page =
false;
5845 for (
i = 0;
i < nmembers;
i++)
5878 if (result !=
TM_Ok)
5915 elog(
ERROR,
"invalid lock status in tuple");
5949 if (result !=
TM_Ok)
5959 &new_xmax, &new_infomask, &new_infomask2);
5964 cleared_all_frozen =
true;
5988 xlrec.
xmax = new_xmax;
6222 elog(
ERROR,
"attempted to kill a tuple inserted by another transaction");
6224 elog(
ERROR,
"attempted to kill a non-speculative tuple");
6251 prune_xid = relfrozenxid;
6367 void (*release_callback) (
void *),
void *
arg)
6373#ifdef USE_ASSERT_CHECKING
6375 check_inplace_rel_lock(oldtup_ptr);
6410 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6422 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6423 errmsg(
"tuple to be updated was already modified by an operation triggered by the current command")));
6443 release_callback(
arg);
6459 release_callback(
arg);
6467 ret = (result ==
TM_Ok);
6471 release_callback(
arg);
6512 bool RelcacheInitFileInval =
false;
6520 dst = (
char *) htup + htup->
t_hoff;
6526 &RelcacheInitFileInval);
6582 uintptr_t dst_offset_in_block;
6592 xlrec.
nmsgs = nmsgs;
6601 memcpy(copied_buffer.
data, origdata,
lower);
6603 dst_offset_in_block = dst - origdata;
6604 memcpy(copied_buffer.
data + dst_offset_in_block, src, newlen);
6618 memcpy(dst, src, newlen);
6662#define FRM_NOOP 0x0001
6663#define FRM_INVALIDATE_XMAX 0x0002
6664#define FRM_RETURN_IS_XID 0x0004
6665#define FRM_RETURN_IS_MULTI 0x0008
6666#define FRM_MARK_COMMITTED 0x0010
6727 bool update_committed;
6761 errmsg_internal(
"multixact %u from before multi freeze cutoff %u found to be still running",
6776 errmsg_internal(
"multixact %u contains update XID %u from before relfrozenxid %u",
6789 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
6837 need_replace =
false;
6839 for (
int i = 0;
i < nmembers;
i++)
6848 need_replace =
true;
6852 FreezePageRelfrozenXid = xid;
6884 has_lockers =
false;
6886 update_committed =
false;
6891 for (
int i = 0;
i < nmembers;
i++)
6910 errmsg_internal(
"multixact %u contains running locker XID %u from before removable cutoff %u",
6913 newmembers[nnewmembers++] = members[
i];
6954 update_committed =
true;
6973 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
6975 newmembers[nnewmembers++] = members[
i];
6984 if (nnewmembers == 0)
6999 Assert(nnewmembers == 1);
7001 if (update_committed)
7003 newxmax = update_xid;
7070 bool xmin_already_frozen =
false,
7071 xmax_already_frozen =
false;
7072 bool freeze_xmin =
false,
7073 replace_xvac =
false,
7074 replace_xmax =
false,
7075 freeze_xmax =
false;
7091 xmin_already_frozen =
true;
7184 frz->
xmax = newxmax;
7187 replace_xmax =
true;
7211 frz->
xmax = newxmax;
7212 replace_xmax =
true;
7254 xmax_already_frozen =
true;
7259 errmsg_internal(
"found raw xmax %u (infomask 0x%04x) not invalid and not multi",
7264 Assert(!xmin_already_frozen);
7283 Assert(!xmax_already_frozen && !freeze_xmax);
7290 Assert(!xmax_already_frozen && !replace_xmax);
7309 *totally_frozen = ((freeze_xmin || xmin_already_frozen) &&
7310 (freeze_xmax || xmax_already_frozen));
7313 xmax_already_frozen))
7326 return freeze_xmin || replace_xvac || replace_xmax || freeze_xmax;
7343 for (
int i = 0;
i < ntuples;
i++)
7395 for (
int i = 0;
i < ntuples;
i++)
7419 bool totally_frozen;
7430 pagefrz.freeze_required =
true;
7437 &pagefrz, &frz, &totally_frozen);
7465 bool has_update =
false;
7474 for (
i = 0;
i < nmembers;
i++)
7483 if (
mode > strongest)
7487 switch (members[
i].status)
7523 *new_infomask = bits;
7524 *new_infomask2 = bits2;
7557 for (
i = 0;
i < nmembers;
i++)
7565 update_xact = members[
i].
xid;
7566#ifndef USE_ASSERT_CHECKING
7611 bool result =
false;
7623 for (
i = 0;
i < nmembers;
i++)
7628 if (result && (current_is_member == NULL || *current_is_member))
7634 memxid = members[
i].
xid;
7637 if (current_is_member != NULL)
7638 *current_is_member =
true;
7707 uint16 infomask,
bool nowait,
7725 for (
i = 0;
i < nmembers;
i++)
7808 bool logLockFailure)
7883 bool freeze =
false;
7891 *NoFreezePageRelfrozenXid = xid;
7909 *NoFreezePageRelfrozenXid = xid;
7921 *NoFreezePageRelminMxid = multi;
7933 *NoFreezePageRelminMxid = multi;
7941 for (
int i = 0;
i < nmembers;
i++)
7943 xid = members[
i].
xid;
7946 *NoFreezePageRelfrozenXid = xid;
7961 *NoFreezePageRelfrozenXid = xid;
7994 *snapshotConflictHorizon = xvac;
8008 *snapshotConflictHorizon = xmax;
8024index_delete_prefetch_buffer(
Relation rel,
8025 IndexDeletePrefetchState *prefetch_state,
8028 BlockNumber cur_hblkno = prefetch_state->cur_hblkno;
8031 int ndeltids = prefetch_state->ndeltids;
8034 for (
i = prefetch_state->next_item;
8035 i < ndeltids && count < prefetch_count;
8053 prefetch_state->next_item =
i;
8054 prefetch_state->cur_hblkno = cur_hblkno;
8078 if (
unlikely(indexpagehoffnum > maxoff))
8080 (
errcode(ERRCODE_INDEX_CORRUPTED),
8081 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\"",
8090 (
errcode(ERRCODE_INDEX_CORRUPTED),
8091 errmsg_internal(
"heap tid from index tuple (%u,%u) points to unused heap page item at offset %u of block %u in index \"%s\"",
8106 (
errcode(ERRCODE_INDEX_CORRUPTED),
8107 errmsg_internal(
"heap tid from index tuple (%u,%u) points to heap-only tuple at offset %u of block %u in index \"%s\"",
8139 IndexDeletePrefetchState prefetch_state;
8140 int prefetch_distance;
8143 int finalndeltids = 0,
8144 nblocksaccessed = 0;
8147 int nblocksfavorable = 0;
8150 actualfreespace = 0;
8151 bool bottomup_final_block =
false;
8171 prefetch_state.next_item = 0;
8172 prefetch_state.ndeltids = delstate->
ndeltids;
8173 prefetch_state.deltids = delstate->
deltids;
8191 Assert(nblocksfavorable >= 1);
8193 prefetch_distance =
Min(prefetch_distance, nblocksfavorable);
8197 index_delete_prefetch_buffer(rel, &prefetch_state, prefetch_distance);
8240 if (bottomup_final_block)
8249 if (nblocksaccessed >= 1 && actualfreespace == lastfreespace)
8251 lastfreespace = actualfreespace;
8277 Assert(nblocksaccessed > 0 || nblocksfavorable > 0);
8278 if (nblocksfavorable > 0)
8281 curtargetfreespace /= 2;
8300 index_delete_prefetch_buffer(rel, &prefetch_state, 1);
8326 &heapTuple, NULL,
true))
8337 if (actualfreespace >= curtargetfreespace)
8338 bottomup_final_block =
true;
8362 if (offnum > maxoff)
8399 &snapshotConflictHorizon);
8417 finalndeltids =
i + 1;
8429 delstate->
ndeltids = finalndeltids;
8431 return snapshotConflictHorizon;
8448 return (blk1 < blk2) ? -1 : 1;
8455 return (pos1 < pos2) ? -1 : 1;
8485 const int gaps[9] = {1968, 861, 336, 112, 48, 21, 7, 3, 1};
8489 "element size exceeds 8 bytes");
8491 for (
int g = 0; g <
lengthof(gaps); g++)
8493 for (
int hi = gaps[g],
i = hi;
i < ndeltids;
i++)
8500 deltids[
j] = deltids[
j - hi];
8573 int64 lastblock = -1;
8574 int nblocksfavorable = 0;
8576 Assert(nblockgroups >= 1);
8588 for (
int b = 0;
b < nblockgroups;
b++)
8594 if (lastblock != -1 &&
8604 Assert(nblocksfavorable >= 1);
8606 return nblocksfavorable;
8641 if (ntids1 > ntids2)
8643 if (ntids1 < ntids2)
8691 int nblockgroups = 0;
8693 int nblocksfavorable = 0;
8717 blockgroups[nblockgroups - 1].
ntids = 1;
8722 blockgroups[nblockgroups - 1].
ntids++;
8757 for (
int b = 0;
b < nblockgroups;
b++)
8779 for (
int b = 0;
b < nblockgroups;
b++)
8784 memcpy(reordereddeltids + ncopied, firstdtid,
8786 ncopied += group->
ntids;
8790 memcpy(delstate->
deltids, reordereddeltids,
8794 pfree(reordereddeltids);
8797 return nblocksfavorable;
8826 xlrec.
flags = vmflags;
8852 bool all_visible_cleared,
bool new_all_visible_cleared)
8897 if (oldbuf == newbuf && !need_tuple_data &&
8906 for (prefixlen = 0; prefixlen <
Min(oldlen, newlen); prefixlen++)
8908 if (newp[prefixlen] != oldp[prefixlen])
8920 for (suffixlen = 0; suffixlen <
Min(oldlen, newlen) - prefixlen; suffixlen++)
8922 if (newp[newlen - suffixlen - 1] != oldp[oldlen - suffixlen - 1])
8931 if (all_visible_cleared)
8933 if (new_all_visible_cleared)
8939 if (need_tuple_data)
8944 if (reln->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
8974 if (need_tuple_data)
8978 if (oldbuf != newbuf)
8986 if (prefixlen > 0 || suffixlen > 0)
8988 if (prefixlen > 0 && suffixlen > 0)
8990 prefix_suffix[0] = prefixlen;
8991 prefix_suffix[1] = suffixlen;
8994 else if (prefixlen > 0)
9042 if (need_tuple_data && old_key_tuple)
9156 char replident = relation->
rd_rel->relreplident;
9167 if (replident == REPLICA_IDENTITY_NOTHING)
9170 if (replident == REPLICA_IDENTITY_FULL)
9208 for (
int i = 0;
i < desc->
natts;
i++)
9312 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)
bool BufferIsDirty(Buffer buffer)
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 void * 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))
void simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup, TU_UpdateIndexes *update_indexes)
static bool DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask, LockTupleMode lockmode, bool *current_is_member)
void heap_insert(Relation relation, HeapTuple tup, CommandId cid, int options, BulkInsertState bistate)
static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup)
XLogRecPtr log_heap_visible(Relation rel, Buffer heap_buffer, Buffer vm_buffer, TransactionId snapshotConflictHorizon, uint8 vmflags)
static void compute_new_xmax_infomask(TransactionId xmax, uint16 old_infomask, uint16 old_infomask2, TransactionId add_to_xmax, LockTupleMode mode, bool is_update, TransactionId *result_xmax, uint16 *result_infomask, uint16 *result_infomask2)
struct IndexDeleteCounts IndexDeleteCounts
static void heap_fetch_next_buffer(HeapScanDesc scan, ScanDirection dir)
static TM_Result heap_lock_updated_tuple_rec(Relation rel, const ItemPointerData *tid, TransactionId xid, LockTupleMode mode)
bool heap_inplace_lock(Relation relation, HeapTuple oldtup_ptr, Buffer buffer, void(*release_callback)(void *), void *arg)
bool heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tuple, Buffer *userbuf, bool keep_buf)
#define BOTTOMUP_TOLERANCE_NBLOCKS
static HeapTuple heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, CommandId cid, int options)
static BlockNumber heap_scan_stream_read_next_parallel(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
static int bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate)
static bool heap_acquire_tuplock(Relation relation, const ItemPointerData *tid, LockTupleMode mode, LockWaitPolicy wait_policy, bool *have_tuple_lock)
static int heap_multi_insert_pages(HeapTuple *heaptuples, int done, int ntuples, Size saveFreeSpace)
static pg_attribute_always_inline int page_collect_tuples(HeapScanDesc scan, Snapshot snapshot, Page page, Buffer buffer, BlockNumber block, int lines, bool all_visible, bool check_serializable)
static BlockNumber heap_scan_stream_read_next_serial(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask, uint16 *new_infomask2)
void heap_finish_speculative(Relation relation, const ItemPointerData *tid)
void HeapTupleHeaderAdvanceConflictHorizon(HeapTupleHeader tuple, TransactionId *snapshotConflictHorizon)
bool heap_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
#define LOCKMODE_from_mxstatus(status)
void heap_endscan(TableScanDesc sscan)
#define FRM_RETURN_IS_XID
#define TUPLOCK_from_mxstatus(status)
void heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params, bool allow_strat, bool allow_sync, bool allow_pagemode)
void heap_inplace_unlock(Relation relation, HeapTuple oldtup, Buffer buffer)
TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, CommandId cid, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes)
static int index_delete_sort_cmp(TM_IndexDelete *deltid1, TM_IndexDelete *deltid2)
static bool ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, Relation rel, int *remaining, bool logLockFailure)
bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple)
TM_Result heap_delete(Relation relation, const ItemPointerData *tid, CommandId cid, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, bool changingPart)
static TransactionId FreezeMultiXactId(MultiXactId multi, uint16 t_infomask, const struct VacuumCutoffs *cutoffs, uint16 *flags, HeapPageFreeze *pagefrz)
static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, bool *copy)
static pg_noinline BlockNumber heapgettup_initial_block(HeapScanDesc scan, ScanDirection dir)
static TM_Result heap_lock_updated_tuple(Relation rel, HeapTuple tuple, const ItemPointerData *ctid, TransactionId xid, LockTupleMode mode)
#define LockTupleTuplock(rel, tup, mode)
bool heap_tuple_should_freeze(HeapTupleHeader tuple, const struct VacuumCutoffs *cutoffs, TransactionId *NoFreezePageRelfrozenXid, MultiXactId *NoFreezePageRelminMxid)
bool heap_freeze_tuple(HeapTupleHeader tuple, TransactionId relfrozenxid, TransactionId relminmxid, TransactionId FreezeLimit, TransactionId MultiXactCutoff)
void heap_inplace_update_and_unlock(Relation relation, HeapTuple oldtup, HeapTuple tuple, Buffer buffer)
static BlockNumber heapgettup_advance_block(HeapScanDesc scan, BlockNumber block, ScanDirection dir)
static TransactionId MultiXactIdGetUpdateXid(TransactionId xmax, uint16 t_infomask)
#define BOTTOMUP_MAX_NBLOCKS
void ReleaseBulkInsertStatePin(BulkInsertState bistate)
#define FRM_MARK_COMMITTED
static void index_delete_check_htid(TM_IndexDeleteOp *delstate, Page page, OffsetNumber maxoff, const ItemPointerData *htid, TM_IndexStatus *istatus)
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
bool heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, Snapshot snapshot, HeapTuple heapTuple, bool *all_dead, bool first_call)
void heap_freeze_prepared_tuples(Buffer buffer, HeapTupleFreeze *tuples, int ntuples)
bool heap_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot)
static void MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, Relation rel, const ItemPointerData *ctid, XLTW_Oper oper, int *remaining)
void heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid, ItemPointer maxtid)
void heap_abort_speculative(Relation relation, const ItemPointerData *tid)
static BlockNumber bitmapheap_stream_read_next(ReadStream *pgsr, void *private_data, void *per_buffer_data)
TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot, int nkeys, ScanKey key, ParallelTableScanDesc parallel_scan, uint32 flags)
static void heapgettup(HeapScanDesc scan, ScanDirection dir, int nkeys, ScanKey key)
static Page heapgettup_continue_page(HeapScanDesc scan, ScanDirection dir, int *linesleft, OffsetNumber *lineoff)
static uint8 compute_infobits(uint16 infomask, uint16 infomask2)
#define FRM_RETURN_IS_MULTI
#define FRM_INVALIDATE_XMAX
static bool heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, bool isnull1, bool isnull2)
static void index_delete_sort(TM_IndexDeleteOp *delstate)
void heap_prepare_pagescan(TableScanDesc sscan)
static Bitmapset * HeapDetermineColumnsInfo(Relation relation, Bitmapset *interesting_cols, Bitmapset *external_cols, HeapTuple oldtup, HeapTuple newtup, bool *has_external)
static const int MultiXactStatusLock[MaxMultiXactStatus+1]
void simple_heap_insert(Relation relation, HeapTuple tup)
static bool xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask)
#define UnlockTupleTuplock(rel, tup, mode)
static TM_Result test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, LockTupleMode mode, HeapTuple tup, bool *needwait)
bool heap_prepare_freeze_tuple(HeapTupleHeader tuple, const struct VacuumCutoffs *cutoffs, HeapPageFreeze *pagefrz, HeapTupleFreeze *frz, bool *totally_frozen)
static void AssertHasSnapshotForToast(Relation rel)
void simple_heap_delete(Relation relation, const ItemPointerData *tid)
static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf, Buffer newbuf, HeapTuple oldtup, HeapTuple newtup, HeapTuple old_key_tuple, bool all_visible_cleared, bool new_all_visible_cleared)
TransactionId HeapTupleGetUpdateXid(const HeapTupleHeaderData *tup)
TransactionId heap_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate)
void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, int options, BulkInsertState bistate)
#define ConditionalLockTupleTuplock(rel, tup, mode, log)
static void initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock)
static int bottomup_nblocksfavorable(IndexDeleteCounts *blockgroups, int nblockgroups, TM_IndexDelete *deltids)
static void heapgettup_pagemode(HeapScanDesc scan, ScanDirection dir, int nkeys, ScanKey key)
TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, bool follow_updates, Buffer *buffer, TM_FailureData *tmfd)
static void UpdateXmaxHintBits(HeapTupleHeader tuple, Buffer buffer, TransactionId xid)
static bool Do_MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, bool nowait, Relation rel, const ItemPointerData *ctid, XLTW_Oper oper, int *remaining, bool logLockFailure)
static int bottomup_sort_and_shrink_cmp(const void *arg1, const void *arg2)
void heap_get_latest_tid(TableScanDesc sscan, ItemPointer tid)
void heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, BlockNumber numBlks)
void HeapCheckForSerializableConflictOut(bool visible, Relation relation, HeapTuple tuple, Buffer buffer, Snapshot snapshot)
static Page heapgettup_start_page(HeapScanDesc scan, ScanDirection dir, int *linesleft, OffsetNumber *lineoff)
static MultiXactStatus get_mxact_status_for_lock(LockTupleMode mode, bool is_update)
void heap_pre_freeze_checks(Buffer buffer, HeapTupleFreeze *tuples, int ntuples)
BulkInsertState GetBulkInsertState(void)
void FreeBulkInsertState(BulkInsertState bistate)
static const struct @15 tupleLockExtraInfo[MaxLockTupleMode+1]
#define HEAP_INSERT_SPECULATIVE
#define HEAP_FREEZE_CHECK_XMAX_ABORTED
struct HeapScanDescData * HeapScanDesc
@ HEAPTUPLE_RECENTLY_DEAD
@ HEAPTUPLE_INSERT_IN_PROGRESS
@ HEAPTUPLE_DELETE_IN_PROGRESS
struct BitmapHeapScanDescData * BitmapHeapScanDesc
#define HEAP_INSERT_FROZEN
static void heap_execute_freeze_tuple(HeapTupleHeader tuple, HeapTupleFreeze *frz)
#define HEAP_FREEZE_CHECK_XMIN_COMMITTED
#define HEAP_INSERT_NO_LOGICAL
struct BulkInsertStateData * BulkInsertState
const TableAmRoutine * GetHeapamTableAmRoutine(void)
void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid)
bool HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, Buffer buffer)
bool HeapTupleIsSurelyDead(HeapTuple htup, GlobalVisState *vistest)
HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, Buffer buffer)
bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
TM_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, Buffer buffer)
#define XLH_INSERT_ON_TOAST_RELATION
#define SizeOfHeapMultiInsert
#define XLOG_HEAP2_MULTI_INSERT
#define XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED
#define SizeOfHeapVisible
#define XLOG_HEAP_HOT_UPDATE
#define XLH_INSERT_IS_SPECULATIVE
#define XLH_LOCK_ALL_FROZEN_CLEARED
#define XLH_DELETE_CONTAINS_OLD_KEY
#define XLH_UPDATE_CONTAINS_NEW_TUPLE
#define XLH_INSERT_LAST_IN_MULTI
#define XLH_INSERT_ALL_FROZEN_SET
#define XLHL_XMAX_KEYSHR_LOCK
#define XLH_DELETE_ALL_VISIBLE_CLEARED
#define XLH_UPDATE_CONTAINS_OLD_TUPLE
#define SizeOfHeapLockUpdated
#define XLHL_XMAX_IS_MULTI
#define XLH_INSERT_ALL_VISIBLE_CLEARED
#define XLH_DELETE_IS_PARTITION_MOVE
#define MinSizeOfHeapInplace
#define XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED
#define XLHL_XMAX_LOCK_ONLY
#define XLOG_HEAP_INPLACE
#define XLOG_HEAP2_LOCK_UPDATED
#define XLH_UPDATE_SUFFIX_FROM_OLD
#define XLH_UPDATE_PREFIX_FROM_OLD
#define SizeOfMultiInsertTuple
#define XLHL_XMAX_EXCL_LOCK
#define XLOG_HEAP2_NEW_CID
#define XLH_DELETE_CONTAINS_OLD_TUPLE
#define XLH_DELETE_IS_SUPER
#define XLH_UPDATE_CONTAINS_OLD_KEY
#define XLHL_KEYS_UPDATED
#define XLOG_HEAP2_VISIBLE
#define XLH_INSERT_CONTAINS_NEW_TUPLE
#define XLOG_HEAP_INIT_PAGE
#define SizeOfHeapConfirm
#define XLOG_HEAP_CONFIRM
void heap_toast_delete(Relation rel, HeapTuple oldtup, bool is_speculative)
HeapTuple heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup, int options)
HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc)
#define TOAST_TUPLE_THRESHOLD
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
void heap_freetuple(HeapTuple htup)
void RelationPutHeapTuple(Relation relation, Buffer buffer, HeapTuple tuple, bool token)
Buffer RelationGetBufferForTuple(Relation relation, Size len, Buffer otherBuffer, int options, BulkInsertState bistate, Buffer *vmbuffer, Buffer *vmbuffer_other, int num_pages)
HeapTupleHeaderData * HeapTupleHeader
#define HEAP_XMAX_SHR_LOCK
static bool HeapTupleIsHotUpdated(const HeapTupleData *tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static bool HeapTupleHeaderXminFrozen(const HeapTupleHeaderData *tup)
#define HeapTupleHeaderGetNatts(tup)
static void HeapTupleHeaderSetXminFrozen(HeapTupleHeaderData *tup)
#define SizeofHeapTupleHeader
#define HEAP_KEYS_UPDATED
static bool HEAP_XMAX_IS_SHR_LOCKED(uint16 infomask)
static bool HEAP_XMAX_IS_LOCKED_ONLY(uint16 infomask)
static bool HeapTupleHeaderXminInvalid(const HeapTupleHeaderData *tup)
static void HeapTupleClearHotUpdated(const HeapTupleData *tuple)
static bool HeapTupleHasExternal(const HeapTupleData *tuple)
static TransactionId HeapTupleHeaderGetXvac(const HeapTupleHeaderData *tup)
static void HeapTupleHeaderSetCmax(HeapTupleHeaderData *tup, CommandId cid, bool iscombo)
#define HEAP_XMAX_LOCK_ONLY
static void HeapTupleHeaderClearHotUpdated(HeapTupleHeaderData *tup)
static void HeapTupleHeaderSetCmin(HeapTupleHeaderData *tup, CommandId cid)
static CommandId HeapTupleHeaderGetRawCommandId(const HeapTupleHeaderData *tup)
static TransactionId HeapTupleHeaderGetRawXmax(const HeapTupleHeaderData *tup)
static bool HeapTupleHeaderIsHeapOnly(const HeapTupleHeaderData *tup)
static bool HeapTupleIsHeapOnly(const HeapTupleData *tuple)
static void HeapTupleSetHeapOnly(const HeapTupleData *tuple)
#define HEAP_XMAX_IS_MULTI
static bool HEAP_XMAX_IS_KEYSHR_LOCKED(uint16 infomask)
#define HEAP_XMAX_COMMITTED
static TransactionId HeapTupleHeaderGetXmin(const HeapTupleHeaderData *tup)
static bool HeapTupleHeaderIndicatesMovedPartitions(const HeapTupleHeaderData *tup)
static void HeapTupleSetHotUpdated(const HeapTupleData *tuple)
#define HEAP_XMAX_EXCL_LOCK
static bool HeapTupleHeaderIsHotUpdated(const HeapTupleHeaderData *tup)
#define HEAP_XMAX_INVALID
static TransactionId HeapTupleHeaderGetRawXmin(const HeapTupleHeaderData *tup)
static void * GETSTRUCT(const HeapTupleData *tuple)
static void HeapTupleClearHeapOnly(const HeapTupleData *tuple)
#define MaxHeapAttributeNumber
static bool HeapTupleHeaderIsSpeculative(const HeapTupleHeaderData *tup)
static TransactionId HeapTupleHeaderGetUpdateXid(const HeapTupleHeaderData *tup)
#define MaxHeapTuplesPerPage
static bool HEAP_XMAX_IS_EXCL_LOCKED(uint16 infomask)
static void HeapTupleHeaderSetXmin(HeapTupleHeaderData *tup, TransactionId xid)
static bool HEAP_LOCKED_UPGRADED(uint16 infomask)
#define HEAP_XMAX_KEYSHR_LOCK
static void HeapTupleHeaderSetMovedPartitions(HeapTupleHeaderData *tup)
static void HeapTupleHeaderSetXmax(HeapTupleHeaderData *tup, TransactionId xid)
static bool HeapTupleHeaderXminCommitted(const HeapTupleHeaderData *tup)
#define IsParallelWorker()
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
#define INJECTION_POINT(name, arg)
void 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(const ItemPointerData *arg1, const ItemPointerData *arg2)
bool ItemPointerEquals(const ItemPointerData *pointer1, const ItemPointerData *pointer2)
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
static void ItemPointerSetInvalid(ItemPointerData *pointer)
static void ItemPointerSetOffsetNumber(ItemPointerData *pointer, OffsetNumber offsetNumber)
static void ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static 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 CheckForSerializableConflictIn(Relation relation, const ItemPointerData *tid, BlockNumber blkno)
void CheckForSerializableConflictOut(Relation relation, TransactionId xid, Snapshot snapshot)
void PredicateLockRelation(Relation relation, Snapshot snapshot)
void PredicateLockTID(Relation relation, const ItemPointerData *tid, Snapshot snapshot, TransactionId tuple_xid)
bool CheckForSerializableConflictOutNeeded(Relation relation, Snapshot snapshot)
#define DELAY_CHKPT_START
GlobalVisState * GlobalVisTestFor(Relation rel)
bool TransactionIdIsInProgress(TransactionId xid)
void heap_page_prune_opt(Relation relation, Buffer buffer)
void read_stream_reset(ReadStream *stream)
Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
ReadStream * read_stream_begin_relation(int flags, BufferAccessStrategy strategy, Relation rel, ForkNumber forknum, ReadStreamBlockNumberCB callback, void *callback_private_data, size_t per_buffer_data_size)
void read_stream_end(ReadStream *stream)
#define READ_STREAM_USE_BATCHING
BlockNumber(* ReadStreamBlockNumberCB)(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
#define READ_STREAM_DEFAULT
#define READ_STREAM_SEQUENTIAL
#define RelationGetRelid(relation)
#define RelationIsLogicallyLogged(relation)
#define RelationGetTargetPageFreeSpace(relation, defaultff)
#define RelationGetDescr(relation)
#define RelationGetNumberOfAttributes(relation)
#define RelationGetRelationName(relation)
#define RelationIsAccessibleInLogicalDecoding(relation)
#define RelationNeedsWAL(relation)
#define RelationUsesLocalBuffers(relation)
#define HEAP_DEFAULT_FILLFACTOR
void RelationDecrementReferenceCount(Relation rel)
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
void RelationIncrementReferenceCount(Relation rel)
@ INDEX_ATTR_BITMAP_HOT_BLOCKING
@ INDEX_ATTR_BITMAP_SUMMARIZED
@ INDEX_ATTR_BITMAP_IDENTITY_KEY
struct ParallelBlockTableScanDescData * ParallelBlockTableScanDesc
#define ScanDirectionIsForward(direction)
#define ScanDirectionIsBackward(direction)
void UnregisterSnapshot(Snapshot snapshot)
TransactionId TransactionXmin
bool HaveRegisteredOrActiveSnapshot(void)
void InvalidateCatalogSnapshot(void)
#define IsHistoricMVCCSnapshot(snapshot)
#define InitNonVacuumableSnapshot(snapshotdata, vistestp)
#define IsMVCCSnapshot(snapshot)
int get_tablespace_maintenance_io_concurrency(Oid spcid)
BufferAccessStrategy strategy
uint32 already_extended_by
MultiXactId NoFreezePageRelminMxid
TransactionId FreezePageRelfrozenXid
MultiXactId FreezePageRelminMxid
TransactionId NoFreezePageRelfrozenXid
BufferAccessStrategy rs_strategy
ParallelBlockTableScanWorkerData * rs_parallelworkerdata
BlockNumber rs_startblock
OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]
ReadStream * rs_read_stream
BlockNumber rs_prefetch_block
TableScanDescData rs_base
const struct TableAmRoutine * rd_tableam
RelFileLocator rd_locator
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 TransactionIdDidAbort(TransactionId transactionId)
static bool TransactionIdFollows(TransactionId id1, TransactionId id2)
#define InvalidTransactionId
static bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
static bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
#define TransactionIdEquals(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static bool HeapKeyTest(HeapTuple tuple, TupleDesc tupdesc, int nkeys, ScanKey keys)
static bool VARATT_IS_EXTERNAL(const void *PTR)
bool visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer vmbuf, uint8 flags)
void visibilitymap_pin(Relation rel, BlockNumber heapBlk, Buffer *vmbuf)
uint8 visibilitymap_set_vmbits(BlockNumber heapBlk, Buffer vmBuf, uint8 flags, const RelFileLocator rlocator)
#define VISIBILITYMAP_VALID_BITS
#define VISIBILITYMAP_ALL_FROZEN
#define VISIBILITYMAP_XLOG_CATALOG_REL
#define VISIBILITYMAP_ALL_VISIBLE
TransactionId GetTopTransactionId(void)
TransactionId CheckXidAlive
TransactionId GetTopTransactionIdIfAny(void)
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
bool IsInParallelMode(void)
TransactionId GetCurrentTransactionId(void)
CommandId GetCurrentCommandId(bool used)
#define IsolationIsSerializable()
#define XLOG_INCLUDE_ORIGIN
#define XLogHintBitIsNeeded()
#define XLogStandbyInfoActive()
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBufData(uint8 block_id, const void *data, uint32 len)
bool XLogCheckBufferNeedsBackup(Buffer buffer)
void XLogRegisterData(const void *data, uint32 len)
void XLogSetRecordFlags(uint8 flags)
void XLogRegisterBlock(uint8 block_id, RelFileLocator *rlocator, ForkNumber forknum, BlockNumber blknum, const PageData *page, uint8 flags)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)