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)
288 void *callback_private_data,
289 void *per_buffer_data)
313 void *per_buffer_data)
396 allow_strat = allow_sync =
false;
426 if (!keep_startblock)
504 Assert(startBlk == 0 || startBlk < scan->rs_nblocks);
520 bool all_visible,
bool check_serializable)
544 if (check_serializable)
546 &loctup, buffer, snapshot);
576 bool check_serializable;
631 if (
likely(!check_serializable))
633 block, lines,
true,
false);
636 block, lines,
true,
true);
640 if (
likely(!check_serializable))
642 block, lines,
false,
false);
645 block, lines,
false,
true);
805 *linesleft = *lineoff;
954 for (; linesleft > 0; linesleft--, lineoff += dir)
1063 linesleft = scan->rs_ntuples;
1072 for (; linesleft > 0; linesleft--, lineindex += dir)
1077 Assert(lineindex <= scan->rs_ntuples);
1078 lineoff = scan->rs_vistuples[lineindex];
1092 scan->rs_cindex = lineindex;
1167 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
1168 errmsg(
"cannot query non-catalog table \"%s\" during logical decoding",
1203 if (parallel_scan != NULL)
1270 bool allow_strat,
bool allow_sync,
bool allow_pagemode)
1374 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1385 elog(
ERROR,
"unexpected heap_getnext call during logical decoding");
1742 bool *all_dead,
bool first_call)
1748 bool at_chain_start;
1755 *all_dead = first_call;
1759 at_chain_start = first_call;
1785 at_chain_start =
false;
1852 if (all_dead && *all_dead)
1870 at_chain_start =
false;
2110 bool all_visible_cleared =
false;
2160 all_visible_cleared =
true;
2211 if (all_visible_cleared)
2305 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2306 errmsg(
"cannot insert tuples in a parallel worker")));
2323 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
2324 relation->
rd_rel->relkind != RELKIND_MATVIEW)
2347 for (
int i = done;
i < ntuples;
i++)
2351 if (page_avail < tup_sz)
2356 page_avail -= tup_sz;
2388 bool starting_with_empty_page =
false;
2390 int npages_used = 0;
2403 for (
i = 0;
i < ntuples;
i++)
2440 while (ndone < ntuples)
2443 bool all_visible_cleared =
false;
2444 bool all_frozen_set =
false;
2459 if (ndone == 0 || !starting_with_empty_page)
2478 npages - npages_used);
2485 all_frozen_set =
true;
2503 if (needwal && need_cids)
2506 for (nthispage = 1; ndone + nthispage < ntuples; nthispage++)
2508 HeapTuple heaptup = heaptuples[ndone + nthispage];
2519 if (needwal && need_cids)
2533 all_visible_cleared =
true;
2539 else if (all_frozen_set)
2563 char *scratchptr = scratch.
data;
2571 init = starting_with_empty_page;
2587 tupledata = scratchptr;
2590 Assert(!(all_visible_cleared && all_frozen_set));
2593 if (all_visible_cleared)
2610 for (
i = 0;
i < nthispage;
i++)
2632 scratchptr += datalen;
2634 totaldatalen = scratchptr - tupledata;
2635 Assert((scratchptr - scratch.
data) < BLCKSZ);
2637 if (need_tuple_data)
2645 if (ndone + nthispage == ntuples)
2658 if (need_tuple_data)
2725 for (
i = 0;
i < ntuples;
i++)
2730 for (
i = 0;
i < ntuples;
i++)
2731 slots[
i]->tts_tid = heaptuples[
i]->t_self;
2783 const uint16 interesting =
2786 if ((new_infomask & interesting) != (old_infomask & interesting))
2819 bool have_tuple_lock =
false;
2821 bool all_visible_cleared =
false;
2823 bool old_key_copied =
false;
2836 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2837 errmsg(
"cannot delete tuples during a parallel operation")));
2883 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2884 errmsg(
"attempted to delete invisible tuple")));
2910 bool current_is_member =
false;
2921 if (!current_is_member)
3001 if (result !=
TM_Ok)
3019 if (result !=
TM_Ok)
3028 if (have_tuple_lock)
3068 &new_xmax, &new_infomask, &new_infomask2);
3083 all_visible_cleared =
true;
3126 if (all_visible_cleared)
3133 xlrec.
xmax = new_xmax;
3135 if (old_key_tuple != NULL)
3137 if (relation->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
3151 if (old_key_tuple != NULL)
3160 old_key_tuple->
t_len
3185 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3186 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3207 if (have_tuple_lock)
3212 if (old_key_tuple != NULL && old_key_copied)
3240 elog(
ERROR,
"tuple already updated by self");
3248 elog(
ERROR,
"tuple concurrently updated");
3252 elog(
ERROR,
"tuple concurrently deleted");
3256 elog(
ERROR,
"unrecognized heap_delete status: %u", result);
3290 bool old_key_copied =
false;
3301 bool have_tuple_lock =
false;
3303 bool use_hot_update =
false;
3304 bool summarized_update =
false;
3306 bool all_visible_cleared =
false;
3307 bool all_visible_cleared_new =
false;
3308 bool checked_lockers;
3309 bool locker_remains;
3310 bool id_has_external =
false;
3313 uint16 infomask_old_tuple,
3314 infomask2_old_tuple,
3316 infomask2_new_tuple;
3333 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3334 errmsg(
"cannot update tuples during a parallel operation")));
3336#ifdef USE_ASSERT_CHECKING
3337 check_lock_if_inplace_updateable_rel(relation, otid, newtup);
3363 interesting_attrs = NULL;
3415 Assert(!have_tuple_lock);
3454 newtup, &id_has_external);
3499 checked_lockers =
false;
3500 locker_remains =
false;
3510 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3511 errmsg(
"attempted to update invisible tuple")));
3517 bool can_continue =
false;
3562 bool current_is_member =
false;
3565 *lockmode, ¤t_is_member))
3573 if (!current_is_member)
3581 checked_lockers =
true;
3582 locker_remains = remain != 0;
3629 can_continue =
true;
3637 checked_lockers =
true;
3638 locker_remains =
true;
3639 can_continue =
true;
3648 checked_lockers =
true;
3649 locker_remains =
true;
3650 can_continue =
true;
3663 checked_lockers =
true;
3679 can_continue =
true;
3691 if (result !=
TM_Ok)
3709 if (result !=
TM_Ok)
3718 if (have_tuple_lock)
3759 xid, *lockmode,
true,
3760 &xmax_old_tuple, &infomask_old_tuple,
3761 &infomask2_old_tuple);
3772 (checked_lockers && !locker_remains))
3780 infomask2_new_tuple = 0;
3793 &infomask2_new_tuple);
3798 infomask2_new_tuple = 0;
3831 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3832 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3848 if (need_toast || newtupsize > pagefree)
3851 uint16 infomask_lock_old_tuple,
3852 infomask2_lock_old_tuple;
3853 bool cleared_all_frozen =
false;
3876 xid, *lockmode,
false,
3877 &xmax_lock_old_tuple, &infomask_lock_old_tuple,
3878 &infomask2_lock_old_tuple);
3907 cleared_all_frozen =
true;
3920 xlrec.
xmax = xmax_lock_old_tuple;
3975 if (newtupsize > pagefree)
3980 &vmbuffer_new, &vmbuffer,
3992 if (newtupsize > pagefree ||
4040 if (newbuf == buffer)
4049 use_hot_update =
true;
4059 summarized_update =
true;
4133 all_visible_cleared =
true;
4140 all_visible_cleared_new =
true;
4146 if (newbuf != buffer)
4166 newbuf, &oldtup, heaptup,
4168 all_visible_cleared,
4169 all_visible_cleared_new);
4170 if (newbuf != buffer)
4179 if (newbuf != buffer)
4194 if (newbuf != buffer)
4205 if (have_tuple_lock)
4214 if (heaptup != newtup)
4228 if (summarized_update)
4234 *update_indexes =
TU_All;
4236 if (old_key_tuple != NULL && old_key_copied)
4249#ifdef USE_ASSERT_CHECKING
4255check_lock_if_inplace_updateable_rel(
Relation relation,
4262 case RelationRelationId:
4263 case DatabaseRelationId:
4283 case RelationRelationId:
4287 Oid relid = classForm->oid;
4296 if (classForm->relkind == RELKIND_INDEX)
4309 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4317 case DatabaseRelationId:
4323 "missing lock on database \"%s\" (OID %u) @ TID (%u,%u)",
4341 Oid relid = classForm->oid;
4350 if (classForm->relkind == RELKIND_INDEX)
4362 "missing lock for relation \"%s\" (OID %u, relkind %c) @ TID (%u,%u)",
4377 bool isnull1,
bool isnull2)
4383 if (isnull1 != isnull2)
4410 Assert(attrnum <= tupdesc->natts);
4478 value1 =
heap_getattr(oldtup, attrnum, tupdesc, &isnull1);
4479 value2 =
heap_getattr(newtup, attrnum, tupdesc, &isnull2);
4482 value2, isnull1, isnull2))
4492 if (attrnum < 0 || isnull1 ||
4502 *has_external =
true;
4527 &tmfd, &lockmode, update_indexes);
4532 elog(
ERROR,
"tuple already updated by self");
4540 elog(
ERROR,
"tuple concurrently updated");
4544 elog(
ERROR,
"tuple concurrently deleted");
4548 elog(
ERROR,
"unrecognized heap_update status: %u", result);
4569 is_update ?
"true" :
"false");
4607 bool follow_updates,
4621 bool first_time =
true;
4622 bool skip_tuple_lock =
false;
4623 bool have_tuple_lock =
false;
4624 bool cleared_all_frozen =
false;
4711 for (
i = 0;
i < nmembers;
i++)
4736 skip_tuple_lock =
true;
4785 require_sleep =
true;
4819 if (follow_updates && updated)
4850 require_sleep =
false;
4879 require_sleep =
false;
4905 require_sleep =
false;
4918 require_sleep =
false;
4944 require_sleep =
false;
4963 else if (require_sleep)
4975 if (!skip_tuple_lock &&
4995 elog(
ERROR,
"invalid lock mode in heap_lock_tuple");
4998 switch (wait_policy)
5006 status, infomask, relation,
5017 status, infomask, relation,
5020 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5021 errmsg(
"could not obtain lock on row in relation \"%s\"",
5040 switch (wait_policy)
5058 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5059 errmsg(
"could not obtain lock on row in relation \"%s\"",
5115 if (!require_sleep ||
5127 if (result !=
TM_Ok)
5189 &xid, &new_infomask, &new_infomask2);
5225 cleared_all_frozen =
true;
5284 if (have_tuple_lock)
5306 if (*have_tuple_lock)
5309 switch (wait_policy)
5323 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
5324 errmsg(
"could not obtain lock on row in relation \"%s\"",
5328 *have_tuple_lock =
true;
5356 uint16 *result_infomask2)
5379 new_xmax = add_to_xmax;
5389 new_xmax = add_to_xmax;
5393 new_xmax = add_to_xmax;
5397 new_xmax = add_to_xmax;
5401 new_xmax = add_to_xmax;
5430 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5457 old_infomask &= ~HEAP_XMAX_IS_MULTI;
5525 elog(
WARNING,
"LOCK_ONLY found for Xid in progress %u", xmax);
5527 old_infomask &= ~HEAP_XMAX_LOCK_ONLY;
5547 if (xmax == add_to_xmax)
5561 if (
mode < old_mode)
5572 add_to_xmax, new_status);
5612 *result_infomask = new_infomask;
5613 *result_infomask2 = new_infomask2;
5614 *result_xmax = new_xmax;
5738 bool cleared_all_frozen =
false;
5739 bool pinned_desired_page;
5777 pinned_desired_page =
true;
5780 pinned_desired_page =
false;
5860 for (
i = 0;
i < nmembers;
i++)
5893 if (result !=
TM_Ok)
5930 elog(
ERROR,
"invalid lock status in tuple");
5964 if (result !=
TM_Ok)
5974 &new_xmax, &new_infomask, &new_infomask2);
5979 cleared_all_frozen =
true;
6003 xlrec.
xmax = new_xmax;
6237 elog(
ERROR,
"attempted to kill a tuple inserted by another transaction");
6239 elog(
ERROR,
"attempted to kill a non-speculative tuple");
6266 prune_xid = relfrozenxid;
6382 void (*release_callback) (
void *),
void *
arg)
6388#ifdef USE_ASSERT_CHECKING
6390 check_inplace_rel_lock(oldtup_ptr);
6425 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6437 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
6438 errmsg(
"tuple to be updated was already modified by an operation triggered by the current command")));
6458 release_callback(
arg);
6474 release_callback(
arg);
6482 ret = (result ==
TM_Ok);
6486 release_callback(
arg);
6527 bool RelcacheInitFileInval =
false;
6535 dst = (
char *) htup + htup->
t_hoff;
6541 &RelcacheInitFileInval);
6597 uintptr_t dst_offset_in_block;
6607 xlrec.
nmsgs = nmsgs;
6616 memcpy(copied_buffer.
data, origdata,
lower);
6618 dst_offset_in_block = dst - origdata;
6619 memcpy(copied_buffer.
data + dst_offset_in_block, src, newlen);
6633 memcpy(dst, src, newlen);
6677#define FRM_NOOP 0x0001
6678#define FRM_INVALIDATE_XMAX 0x0002
6679#define FRM_RETURN_IS_XID 0x0004
6680#define FRM_RETURN_IS_MULTI 0x0008
6681#define FRM_MARK_COMMITTED 0x0010
6742 bool update_committed;
6776 errmsg_internal(
"multixact %u from before multi freeze cutoff %u found to be still running",
6791 errmsg_internal(
"multixact %u contains update XID %u from before relfrozenxid %u",
6804 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
6852 need_replace =
false;
6854 for (
int i = 0;
i < nmembers;
i++)
6863 need_replace =
true;
6867 FreezePageRelfrozenXid = xid;
6899 has_lockers =
false;
6901 update_committed =
false;
6906 for (
int i = 0;
i < nmembers;
i++)
6925 errmsg_internal(
"multixact %u contains running locker XID %u from before removable cutoff %u",
6928 newmembers[nnewmembers++] = members[
i];
6969 update_committed =
true;
6988 errmsg_internal(
"multixact %u contains committed update XID %u from before removable cutoff %u",
6990 newmembers[nnewmembers++] = members[
i];
6999 if (nnewmembers == 0)
7014 Assert(nnewmembers == 1);
7016 if (update_committed)
7018 newxmax = update_xid;
7085 bool xmin_already_frozen =
false,
7086 xmax_already_frozen =
false;
7087 bool freeze_xmin =
false,
7088 replace_xvac =
false,
7089 replace_xmax =
false,
7090 freeze_xmax =
false;
7106 xmin_already_frozen =
true;
7199 frz->
xmax = newxmax;
7202 replace_xmax =
true;
7226 frz->
xmax = newxmax;
7227 replace_xmax =
true;
7269 xmax_already_frozen =
true;
7274 errmsg_internal(
"found raw xmax %u (infomask 0x%04x) not invalid and not multi",
7279 Assert(!xmin_already_frozen);
7298 Assert(!xmax_already_frozen && !freeze_xmax);
7305 Assert(!xmax_already_frozen && !replace_xmax);
7324 *totally_frozen = ((freeze_xmin || xmin_already_frozen) &&
7325 (freeze_xmax || xmax_already_frozen));
7328 xmax_already_frozen))
7341 return freeze_xmin || replace_xvac || replace_xmax || freeze_xmax;
7358 for (
int i = 0;
i < ntuples;
i++)
7410 for (
int i = 0;
i < ntuples;
i++)
7434 bool totally_frozen;
7445 pagefrz.freeze_required =
true;
7452 &pagefrz, &frz, &totally_frozen);
7480 bool has_update =
false;
7489 for (
i = 0;
i < nmembers;
i++)
7498 if (
mode > strongest)
7502 switch (members[
i].status)
7538 *new_infomask = bits;
7539 *new_infomask2 = bits2;
7572 for (
i = 0;
i < nmembers;
i++)
7580 update_xact = members[
i].
xid;
7581#ifndef USE_ASSERT_CHECKING
7626 bool result =
false;
7638 for (
i = 0;
i < nmembers;
i++)
7643 if (result && (current_is_member == NULL || *current_is_member))
7649 memxid = members[
i].
xid;
7652 if (current_is_member != NULL)
7653 *current_is_member =
true;
7722 uint16 infomask,
bool nowait,
7740 for (
i = 0;
i < nmembers;
i++)
7823 bool logLockFailure)
7898 bool freeze =
false;
7906 *NoFreezePageRelfrozenXid = xid;
7924 *NoFreezePageRelfrozenXid = xid;
7936 *NoFreezePageRelminMxid = multi;
7948 *NoFreezePageRelminMxid = multi;
7956 for (
int i = 0;
i < nmembers;
i++)
7958 xid = members[
i].
xid;
7961 *NoFreezePageRelfrozenXid = xid;
7976 *NoFreezePageRelfrozenXid = xid;
8009 *snapshotConflictHorizon = xvac;
8023 *snapshotConflictHorizon = xmax;
8039index_delete_prefetch_buffer(
Relation rel,
8040 IndexDeletePrefetchState *prefetch_state,
8043 BlockNumber cur_hblkno = prefetch_state->cur_hblkno;
8046 int ndeltids = prefetch_state->ndeltids;
8049 for (
i = prefetch_state->next_item;
8050 i < ndeltids && count < prefetch_count;
8068 prefetch_state->next_item =
i;
8069 prefetch_state->cur_hblkno = cur_hblkno;
8093 if (
unlikely(indexpagehoffnum > maxoff))
8095 (
errcode(ERRCODE_INDEX_CORRUPTED),
8096 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\"",
8105 (
errcode(ERRCODE_INDEX_CORRUPTED),
8106 errmsg_internal(
"heap tid from index tuple (%u,%u) points to unused heap page item at offset %u of block %u in index \"%s\"",
8121 (
errcode(ERRCODE_INDEX_CORRUPTED),
8122 errmsg_internal(
"heap tid from index tuple (%u,%u) points to heap-only tuple at offset %u of block %u in index \"%s\"",
8154 IndexDeletePrefetchState prefetch_state;
8155 int prefetch_distance;
8158 int finalndeltids = 0,
8159 nblocksaccessed = 0;
8162 int nblocksfavorable = 0;
8165 actualfreespace = 0;
8166 bool bottomup_final_block =
false;
8186 prefetch_state.next_item = 0;
8187 prefetch_state.ndeltids = delstate->
ndeltids;
8188 prefetch_state.deltids = delstate->
deltids;
8206 Assert(nblocksfavorable >= 1);
8208 prefetch_distance =
Min(prefetch_distance, nblocksfavorable);
8212 index_delete_prefetch_buffer(rel, &prefetch_state, prefetch_distance);
8255 if (bottomup_final_block)
8264 if (nblocksaccessed >= 1 && actualfreespace == lastfreespace)
8266 lastfreespace = actualfreespace;
8292 Assert(nblocksaccessed > 0 || nblocksfavorable > 0);
8293 if (nblocksfavorable > 0)
8296 curtargetfreespace /= 2;
8315 index_delete_prefetch_buffer(rel, &prefetch_state, 1);
8341 &heapTuple, NULL,
true))
8352 if (actualfreespace >= curtargetfreespace)
8353 bottomup_final_block =
true;
8377 if (offnum > maxoff)
8414 &snapshotConflictHorizon);
8432 finalndeltids =
i + 1;
8444 delstate->
ndeltids = finalndeltids;
8446 return snapshotConflictHorizon;
8463 return (blk1 < blk2) ? -1 : 1;
8470 return (pos1 < pos2) ? -1 : 1;
8500 const int gaps[9] = {1968, 861, 336, 112, 48, 21, 7, 3, 1};
8504 "element size exceeds 8 bytes");
8506 for (
int g = 0; g <
lengthof(gaps); g++)
8508 for (
int hi = gaps[g],
i = hi;
i < ndeltids;
i++)
8515 deltids[
j] = deltids[
j - hi];
8588 int64 lastblock = -1;
8589 int nblocksfavorable = 0;
8591 Assert(nblockgroups >= 1);
8603 for (
int b = 0;
b < nblockgroups;
b++)
8609 if (lastblock != -1 &&
8619 Assert(nblocksfavorable >= 1);
8621 return nblocksfavorable;
8656 if (ntids1 > ntids2)
8658 if (ntids1 < ntids2)
8706 int nblockgroups = 0;
8708 int nblocksfavorable = 0;
8732 blockgroups[nblockgroups - 1].
ntids = 1;
8737 blockgroups[nblockgroups - 1].
ntids++;
8772 for (
int b = 0;
b < nblockgroups;
b++)
8794 for (
int b = 0;
b < nblockgroups;
b++)
8799 memcpy(reordereddeltids + ncopied, firstdtid,
8801 ncopied += group->
ntids;
8805 memcpy(delstate->
deltids, reordereddeltids,
8809 pfree(reordereddeltids);
8812 return nblocksfavorable;
8841 xlrec.
flags = vmflags;
8867 bool all_visible_cleared,
bool new_all_visible_cleared)
8912 if (oldbuf == newbuf && !need_tuple_data &&
8921 for (prefixlen = 0; prefixlen <
Min(oldlen, newlen); prefixlen++)
8923 if (newp[prefixlen] != oldp[prefixlen])
8935 for (suffixlen = 0; suffixlen <
Min(oldlen, newlen) - prefixlen; suffixlen++)
8937 if (newp[newlen - suffixlen - 1] != oldp[oldlen - suffixlen - 1])
8946 if (all_visible_cleared)
8948 if (new_all_visible_cleared)
8954 if (need_tuple_data)
8959 if (reln->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
8989 if (need_tuple_data)
8993 if (oldbuf != newbuf)
9001 if (prefixlen > 0 || suffixlen > 0)
9003 if (prefixlen > 0 && suffixlen > 0)
9005 prefix_suffix[0] = prefixlen;
9006 prefix_suffix[1] = suffixlen;
9009 else if (prefixlen > 0)
9057 if (need_tuple_data && old_key_tuple)
9171 char replident = relation->
rd_rel->relreplident;
9182 if (replident == REPLICA_IDENTITY_NOTHING)
9185 if (replident == REPLICA_IDENTITY_FULL)
9223 for (
int i = 0;
i < desc->
natts;
i++)
9327 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 startblock, BlockNumber numblocks)
BlockNumber table_block_parallelscan_nextpage(Relation rel, ParallelBlockTableScanWorker pbscanwork, ParallelBlockTableScanDesc pbscan)
bool synchronize_seqscans
bool tbm_iterate(TBMIterator *iterator, TBMIterateResult *tbmres)
bool TransactionIdDidCommit(TransactionId transactionId)
bool TransactionIdDidAbort(TransactionId transactionId)
static bool TransactionIdFollows(TransactionId id1, TransactionId id2)
#define InvalidTransactionId
static bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
static bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
#define TransactionIdEquals(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static bool HeapKeyTest(HeapTuple tuple, TupleDesc tupdesc, int nkeys, ScanKey keys)
static bool VARATT_IS_EXTERNAL(const void *PTR)
bool visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer vmbuf, uint8 flags)
void visibilitymap_pin(Relation rel, BlockNumber heapBlk, Buffer *vmbuf)
uint8 visibilitymap_set_vmbits(BlockNumber heapBlk, Buffer vmBuf, uint8 flags, const RelFileLocator rlocator)
#define VISIBILITYMAP_VALID_BITS
#define VISIBILITYMAP_ALL_FROZEN
#define VISIBILITYMAP_XLOG_CATALOG_REL
#define VISIBILITYMAP_ALL_VISIBLE
TransactionId GetTopTransactionId(void)
TransactionId CheckXidAlive
TransactionId GetTopTransactionIdIfAny(void)
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
bool IsInParallelMode(void)
TransactionId GetCurrentTransactionId(void)
CommandId GetCurrentCommandId(bool used)
#define IsolationIsSerializable()
#define XLOG_INCLUDE_ORIGIN
#define XLogHintBitIsNeeded()
#define XLogStandbyInfoActive()
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBufData(uint8 block_id, const void *data, uint32 len)
bool XLogCheckBufferNeedsBackup(Buffer buffer)
void XLogRegisterData(const void *data, uint32 len)
void XLogSetRecordFlags(uint8 flags)
void XLogRegisterBlock(uint8 block_id, RelFileLocator *rlocator, ForkNumber forknum, BlockNumber blknum, const PageData *page, uint8 flags)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)