81 bool all_visible_cleared,
bool new_all_visible_cleared);
89 bool *have_tuple_lock);
161 #define LOCKMODE_from_mxstatus(status) \
162 (tupleLockExtraInfo[TUPLOCK_from_mxstatus((status))].hwlock)
169 #define LockTupleTuplock(rel, tup, mode) \
170 LockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock)
171 #define UnlockTupleTuplock(rel, tup, mode) \
172 UnlockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock)
173 #define ConditionalLockTupleTuplock(rel, tup, mode) \
174 ConditionalLockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock)
187 } IndexDeletePrefetchState;
191 #define BOTTOMUP_MAX_NBLOCKS 6
192 #define BOTTOMUP_TOLERANCE_NBLOCKS 3
220 #define TUPLOCK_from_mxstatus(status) \
221 (MultiXactStatusLock[(status)])
277 allow_strat = allow_sync =
false;
300 else if (keep_startblock)
363 Assert(startBlk == 0 || startBlk < scan->rs_nblocks);
388 Assert(block < scan->rs_nblocks);
474 &loctup, buffer, snapshot);
616 *linesleft = *lineoff;
775 for (; linesleft > 0; linesleft--, lineoff += dir)
792 tuple, scan->rs_cbuf,
806 scan->rs_coffset = lineoff;
888 linesleft = scan->rs_ntuples;
894 for (; linesleft > 0; linesleft--, lineindex += dir)
899 lineoff = scan->rs_vistuples[lineindex];
913 scan->rs_cindex = lineindex;
1003 if (parallel_scan != NULL)
1024 bool allow_strat,
bool allow_sync,
bool allow_pagemode)
1106 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1117 elog(
ERROR,
"unexpected heap_getnext call during logical decoding");
1475 bool *all_dead,
bool first_call)
1481 bool at_chain_start;
1488 *all_dead = first_call;
1492 at_chain_start = first_call;
1518 at_chain_start =
false;
1585 if (all_dead && *all_dead)
1603 at_chain_start =
false;
1832 bool all_visible_cleared =
false;
1880 all_visible_cleared =
true;
1931 if (all_visible_cleared)
2025 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2026 errmsg(
"cannot insert tuples in a parallel worker")));
2043 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
2044 relation->
rd_rel->relkind != RELKIND_MATVIEW)
2067 for (
int i = done;
i < ntuples;
i++)
2071 if (page_avail < tup_sz)
2076 page_avail -= tup_sz;
2108 bool starting_with_empty_page =
false;
2110 int npages_used = 0;
2121 for (
i = 0;
i < ntuples;
i++)
2158 while (ndone < ntuples)
2161 bool all_visible_cleared =
false;
2162 bool all_frozen_set =
false;
2177 if (ndone == 0 || !starting_with_empty_page)
2196 npages - npages_used);
2202 all_frozen_set =
true;
2217 if (needwal && need_cids)
2220 for (nthispage = 1; ndone + nthispage < ntuples; nthispage++)
2222 HeapTuple heaptup = heaptuples[ndone + nthispage];
2233 if (needwal && need_cids)
2246 all_visible_cleared =
true;
2252 else if (all_frozen_set)
2269 char *scratchptr = scratch.
data;
2277 init = starting_with_empty_page;
2293 tupledata = scratchptr;
2296 Assert(!(all_visible_cleared && all_frozen_set));
2299 if (all_visible_cleared)
2310 for (
i = 0;
i < nthispage;
i++)
2332 scratchptr += datalen;
2334 totaldatalen = scratchptr - tupledata;
2335 Assert((scratchptr - scratch.
data) < BLCKSZ);
2337 if (need_tuple_data)
2345 if (ndone + nthispage == ntuples)
2358 if (need_tuple_data)
2435 for (
i = 0;
i < ntuples;
i++)
2440 for (
i = 0;
i < ntuples;
i++)
2441 slots[
i]->tts_tid = heaptuples[
i]->t_self;
2493 const uint16 interesting =
2496 if ((new_infomask & interesting) != (old_infomask & interesting))
2529 bool have_tuple_lock =
false;
2531 bool all_visible_cleared =
false;
2533 bool old_key_copied =
false;
2544 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
2545 errmsg(
"cannot delete tuples during a parallel operation")));
2591 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2592 errmsg(
"attempted to delete invisible tuple")));
2618 bool current_is_member =
false;
2629 if (!current_is_member)
2715 if (result !=
TM_Ok)
2731 if (have_tuple_lock)
2771 &new_xmax, &new_infomask, &new_infomask2);
2786 all_visible_cleared =
true;
2829 if (all_visible_cleared)
2836 xlrec.
xmax = new_xmax;
2838 if (old_key_tuple != NULL)
2840 if (relation->
rd_rel->relreplident == REPLICA_IDENTITY_FULL)
2854 if (old_key_tuple != NULL)
2863 old_key_tuple->
t_len
2888 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
2889 relation->
rd_rel->relkind != RELKIND_MATVIEW)
2910 if (have_tuple_lock)
2915 if (old_key_tuple != NULL && old_key_copied)
2943 elog(
ERROR,
"tuple already updated by self");
2951 elog(
ERROR,
"tuple concurrently updated");
2955 elog(
ERROR,
"tuple concurrently deleted");
2959 elog(
ERROR,
"unrecognized heap_delete status: %u", result);
2993 bool old_key_copied =
false;
3004 bool have_tuple_lock =
false;
3006 bool use_hot_update =
false;
3007 bool summarized_update =
false;
3009 bool all_visible_cleared =
false;
3010 bool all_visible_cleared_new =
false;
3011 bool checked_lockers;
3012 bool locker_remains;
3013 bool id_has_external =
false;
3016 uint16 infomask_old_tuple,
3017 infomask2_old_tuple,
3019 infomask2_new_tuple;
3034 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3035 errmsg(
"cannot update tuples during a parallel operation")));
3060 interesting_attrs = NULL;
3106 newtup, &id_has_external);
3151 checked_lockers =
false;
3152 locker_remains =
false;
3162 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3163 errmsg(
"attempted to update invisible tuple")));
3169 bool can_continue =
false;
3214 bool current_is_member =
false;
3217 *lockmode, ¤t_is_member))
3225 if (!current_is_member)
3233 checked_lockers =
true;
3234 locker_remains = remain != 0;
3281 can_continue =
true;
3289 checked_lockers =
true;
3290 locker_remains =
true;
3291 can_continue =
true;
3300 checked_lockers =
true;
3301 locker_remains =
true;
3302 can_continue =
true;
3315 checked_lockers =
true;
3331 can_continue =
true;
3352 if (result !=
TM_Ok)
3368 if (have_tuple_lock)
3409 xid, *lockmode,
true,
3410 &xmax_old_tuple, &infomask_old_tuple,
3411 &infomask2_old_tuple);
3422 (checked_lockers && !locker_remains))
3430 infomask2_new_tuple = 0;
3443 &infomask2_new_tuple);
3448 infomask2_new_tuple = 0;
3481 if (relation->
rd_rel->relkind != RELKIND_RELATION &&
3482 relation->
rd_rel->relkind != RELKIND_MATVIEW)
3498 if (need_toast || newtupsize > pagefree)
3501 uint16 infomask_lock_old_tuple,
3502 infomask2_lock_old_tuple;
3503 bool cleared_all_frozen =
false;
3526 xid, *lockmode,
false,
3527 &xmax_lock_old_tuple, &infomask_lock_old_tuple,
3528 &infomask2_lock_old_tuple);
3557 cleared_all_frozen =
true;
3570 xlrec.
xmax = xmax_lock_old_tuple;
3625 if (newtupsize > pagefree)
3630 &vmbuffer_new, &vmbuffer,
3642 if (newtupsize > pagefree ||
3690 if (newbuf == buffer)
3699 use_hot_update =
true;
3709 summarized_update =
true;
3783 all_visible_cleared =
true;
3790 all_visible_cleared_new =
true;
3796 if (newbuf != buffer)
3816 newbuf, &oldtup, heaptup,
3818 all_visible_cleared,
3819 all_visible_cleared_new);
3820 if (newbuf != buffer)
3829 if (newbuf != buffer)
3844 if (newbuf != buffer)
3855 if (have_tuple_lock)
3864 if (heaptup != newtup)
3878 if (summarized_update)
3884 *update_indexes =
TU_All;
3886 if (old_key_tuple != NULL && old_key_copied)
3905 bool isnull1,
bool isnull2)
3913 if (isnull1 != isnull2)
3938 Assert(attrnum <= tupdesc->natts);
3940 return datumIsEqual(value1, value2, att->attbyval, att->attlen);
4006 value1 =
heap_getattr(oldtup, attrnum, tupdesc, &isnull1);
4007 value2 =
heap_getattr(newtup, attrnum, tupdesc, &isnull2);
4010 value2, isnull1, isnull2))
4020 if (attrnum < 0 || isnull1 ||
4030 *has_external =
true;
4055 &tmfd, &lockmode, update_indexes);
4060 elog(
ERROR,
"tuple already updated by self");
4068 elog(
ERROR,
"tuple concurrently updated");
4072 elog(
ERROR,
"tuple concurrently deleted");
4076 elog(
ERROR,
"unrecognized heap_update status: %u", result);
4097 is_update ?
"true" :
"false");
4136 bool follow_updates,
4150 bool first_time =
true;
4151 bool skip_tuple_lock =
false;
4152 bool have_tuple_lock =
false;
4153 bool cleared_all_frozen =
false;
4240 for (
i = 0;
i < nmembers;
i++)
4265 skip_tuple_lock =
true;
4314 require_sleep =
true;
4348 if (follow_updates && updated)
4379 require_sleep =
false;
4408 require_sleep =
false;
4434 require_sleep =
false;
4447 require_sleep =
false;
4473 require_sleep =
false;
4492 else if (require_sleep)
4504 if (!skip_tuple_lock &&
4524 elog(
ERROR,
"invalid lock mode in heap_lock_tuple");
4527 switch (wait_policy)
4535 status, infomask, relation,
4546 status, infomask, relation,
4549 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
4550 errmsg(
"could not obtain lock on row in relation \"%s\"",
4569 switch (wait_policy)
4587 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
4588 errmsg(
"could not obtain lock on row in relation \"%s\"",
4644 if (!require_sleep ||
4656 if (result !=
TM_Ok)
4718 &xid, &new_infomask, &new_infomask2);
4754 cleared_all_frozen =
true;
4813 if (have_tuple_lock)
4835 if (*have_tuple_lock)
4838 switch (wait_policy)
4852 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
4853 errmsg(
"could not obtain lock on row in relation \"%s\"",
4857 *have_tuple_lock =
true;
4885 uint16 *result_infomask2)
4908 new_xmax = add_to_xmax;
4918 new_xmax = add_to_xmax;
4922 new_xmax = add_to_xmax;
4926 new_xmax = add_to_xmax;
4930 new_xmax = add_to_xmax;
5054 elog(
WARNING,
"LOCK_ONLY found for Xid in progress %u", xmax);
5076 if (xmax == add_to_xmax)
5090 if (
mode < old_mode)
5101 add_to_xmax, new_status);
5141 *result_infomask = new_infomask;
5142 *result_infomask2 = new_infomask2;
5143 *result_xmax = new_xmax;
5267 bool cleared_all_frozen =
false;
5268 bool pinned_desired_page;
5306 pinned_desired_page =
true;
5309 pinned_desired_page =
false;
5389 for (
i = 0;
i < nmembers;
i++)
5422 if (result !=
TM_Ok)
5459 elog(
ERROR,
"invalid lock status in tuple");
5493 if (result !=
TM_Ok)
5503 &new_xmax, &new_infomask, &new_infomask2);
5508 cleared_all_frozen =
true;
5532 xlrec.
xmax = new_xmax;