agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH v16 7/8] Row pattern recognition patch (tests). 60+ messages / 2 participants [nested] [flat]
* [PATCH v16 7/8] Row pattern recognition patch (tests). @ 2024-04-12 06:49 Tatsuo Ishii <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Tatsuo Ishii @ 2024-04-12 06:49 UTC (permalink / raw) --- src/test/regress/expected/rpr.out | 821 +++++++++++++++++++++++++++++ src/test/regress/parallel_schedule | 2 +- src/test/regress/sql/rpr.sql | 392 ++++++++++++++ 3 files changed, 1214 insertions(+), 1 deletion(-) create mode 100644 src/test/regress/expected/rpr.out create mode 100644 src/test/regress/sql/rpr.sql diff --git a/src/test/regress/expected/rpr.out b/src/test/regress/expected/rpr.out new file mode 100644 index 0000000000..e8998ebf45 --- /dev/null +++ b/src/test/regress/expected/rpr.out @@ -0,0 +1,821 @@ +-- +-- Test for row pattern definition clause +-- +CREATE TEMP TABLE stock ( + company TEXT, + tdate DATE, + price INTEGER +); +INSERT INTO stock VALUES ('company1', '2023-07-01', 100); +INSERT INTO stock VALUES ('company1', '2023-07-02', 200); +INSERT INTO stock VALUES ('company1', '2023-07-03', 150); +INSERT INTO stock VALUES ('company1', '2023-07-04', 140); +INSERT INTO stock VALUES ('company1', '2023-07-05', 150); +INSERT INTO stock VALUES ('company1', '2023-07-06', 90); +INSERT INTO stock VALUES ('company1', '2023-07-07', 110); +INSERT INTO stock VALUES ('company1', '2023-07-08', 130); +INSERT INTO stock VALUES ('company1', '2023-07-09', 120); +INSERT INTO stock VALUES ('company1', '2023-07-10', 130); +INSERT INTO stock VALUES ('company2', '2023-07-01', 50); +INSERT INTO stock VALUES ('company2', '2023-07-02', 2000); +INSERT INTO stock VALUES ('company2', '2023-07-03', 1500); +INSERT INTO stock VALUES ('company2', '2023-07-04', 1400); +INSERT INTO stock VALUES ('company2', '2023-07-05', 1500); +INSERT INTO stock VALUES ('company2', '2023-07-06', 60); +INSERT INTO stock VALUES ('company2', '2023-07-07', 1100); +INSERT INTO stock VALUES ('company2', '2023-07-08', 1300); +INSERT INTO stock VALUES ('company2', '2023-07-09', 1200); +INSERT INTO stock VALUES ('company2', '2023-07-10', 1300); +SELECT * FROM stock; + company | tdate | price +----------+------------+------- + company1 | 07-01-2023 | 100 + company1 | 07-02-2023 | 200 + company1 | 07-03-2023 | 150 + company1 | 07-04-2023 | 140 + company1 | 07-05-2023 | 150 + company1 | 07-06-2023 | 90 + company1 | 07-07-2023 | 110 + company1 | 07-08-2023 | 130 + company1 | 07-09-2023 | 120 + company1 | 07-10-2023 | 130 + company2 | 07-01-2023 | 50 + company2 | 07-02-2023 | 2000 + company2 | 07-03-2023 | 1500 + company2 | 07-04-2023 | 1400 + company2 | 07-05-2023 | 1500 + company2 | 07-06-2023 | 60 + company2 | 07-07-2023 | 1100 + company2 | 07-08-2023 | 1300 + company2 | 07-09-2023 | 1200 + company2 | 07-10-2023 | 1300 +(20 rows) + +-- basic test using PREV +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w, + nth_value(tdate, 2) OVER w AS nth_second + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + company | tdate | price | first_value | last_value | nth_second +----------+------------+-------+-------------+------------+------------ + company1 | 07-01-2023 | 100 | 100 | 140 | 07-02-2023 + company1 | 07-02-2023 | 200 | | | + company1 | 07-03-2023 | 150 | | | + company1 | 07-04-2023 | 140 | | | + company1 | 07-05-2023 | 150 | | | + company1 | 07-06-2023 | 90 | 90 | 120 | 07-07-2023 + company1 | 07-07-2023 | 110 | | | + company1 | 07-08-2023 | 130 | | | + company1 | 07-09-2023 | 120 | | | + company1 | 07-10-2023 | 130 | | | + company2 | 07-01-2023 | 50 | 50 | 1400 | 07-02-2023 + company2 | 07-02-2023 | 2000 | | | + company2 | 07-03-2023 | 1500 | | | + company2 | 07-04-2023 | 1400 | | | + company2 | 07-05-2023 | 1500 | | | + company2 | 07-06-2023 | 60 | 60 | 1200 | 07-07-2023 + company2 | 07-07-2023 | 1100 | | | + company2 | 07-08-2023 | 1300 | | | + company2 | 07-09-2023 | 1200 | | | + company2 | 07-10-2023 | 1300 | | | +(20 rows) + +-- basic test using PREV. UP appears twice +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w, + nth_value(tdate, 2) OVER w AS nth_second + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+ UP+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + company | tdate | price | first_value | last_value | nth_second +----------+------------+-------+-------------+------------+------------ + company1 | 07-01-2023 | 100 | 100 | 150 | 07-02-2023 + company1 | 07-02-2023 | 200 | | | + company1 | 07-03-2023 | 150 | | | + company1 | 07-04-2023 | 140 | | | + company1 | 07-05-2023 | 150 | | | + company1 | 07-06-2023 | 90 | 90 | 130 | 07-07-2023 + company1 | 07-07-2023 | 110 | | | + company1 | 07-08-2023 | 130 | | | + company1 | 07-09-2023 | 120 | | | + company1 | 07-10-2023 | 130 | | | + company2 | 07-01-2023 | 50 | 50 | 1500 | 07-02-2023 + company2 | 07-02-2023 | 2000 | | | + company2 | 07-03-2023 | 1500 | | | + company2 | 07-04-2023 | 1400 | | | + company2 | 07-05-2023 | 1500 | | | + company2 | 07-06-2023 | 60 | 60 | 1300 | 07-07-2023 + company2 | 07-07-2023 | 1100 | | | + company2 | 07-08-2023 | 1300 | | | + company2 | 07-09-2023 | 1200 | | | + company2 | 07-10-2023 | 1300 | | | +(20 rows) + +-- basic test using PREV. Use '*' +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w, + nth_value(tdate, 2) OVER w AS nth_second + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP* DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + company | tdate | price | first_value | last_value | nth_second +----------+------------+-------+-------------+------------+------------ + company1 | 07-01-2023 | 100 | 100 | 140 | 07-02-2023 + company1 | 07-02-2023 | 200 | | | + company1 | 07-03-2023 | 150 | | | + company1 | 07-04-2023 | 140 | | | + company1 | 07-05-2023 | 150 | 150 | 90 | 07-06-2023 + company1 | 07-06-2023 | 90 | | | + company1 | 07-07-2023 | 110 | 110 | 120 | 07-08-2023 + company1 | 07-08-2023 | 130 | | | + company1 | 07-09-2023 | 120 | | | + company1 | 07-10-2023 | 130 | | | + company2 | 07-01-2023 | 50 | 50 | 1400 | 07-02-2023 + company2 | 07-02-2023 | 2000 | | | + company2 | 07-03-2023 | 1500 | | | + company2 | 07-04-2023 | 1400 | | | + company2 | 07-05-2023 | 1500 | 1500 | 60 | 07-06-2023 + company2 | 07-06-2023 | 60 | | | + company2 | 07-07-2023 | 1100 | 1100 | 1200 | 07-08-2023 + company2 | 07-08-2023 | 1300 | | | + company2 | 07-09-2023 | 1200 | | | + company2 | 07-10-2023 | 1300 | | | +(20 rows) + +-- basic test with none greedy pattern +SELECT company, tdate, price, count(*) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (A A A) + DEFINE + A AS price >= 140 AND price <= 150 +); + company | tdate | price | count +----------+------------+-------+------- + company1 | 07-01-2023 | 100 | 0 + company1 | 07-02-2023 | 200 | 0 + company1 | 07-03-2023 | 150 | 3 + company1 | 07-04-2023 | 140 | + company1 | 07-05-2023 | 150 | + company1 | 07-06-2023 | 90 | 0 + company1 | 07-07-2023 | 110 | 0 + company1 | 07-08-2023 | 130 | 0 + company1 | 07-09-2023 | 120 | 0 + company1 | 07-10-2023 | 130 | 0 + company2 | 07-01-2023 | 50 | 0 + company2 | 07-02-2023 | 2000 | 0 + company2 | 07-03-2023 | 1500 | 0 + company2 | 07-04-2023 | 1400 | 0 + company2 | 07-05-2023 | 1500 | 0 + company2 | 07-06-2023 | 60 | 0 + company2 | 07-07-2023 | 1100 | 0 + company2 | 07-08-2023 | 1300 | 0 + company2 | 07-09-2023 | 1200 | 0 + company2 | 07-10-2023 | 1300 | 0 +(20 rows) + +-- last_value() should remain consistent +SELECT company, tdate, price, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + company | tdate | price | last_value +----------+------------+-------+------------ + company1 | 07-01-2023 | 100 | 140 + company1 | 07-02-2023 | 200 | + company1 | 07-03-2023 | 150 | + company1 | 07-04-2023 | 140 | + company1 | 07-05-2023 | 150 | + company1 | 07-06-2023 | 90 | 120 + company1 | 07-07-2023 | 110 | + company1 | 07-08-2023 | 130 | + company1 | 07-09-2023 | 120 | + company1 | 07-10-2023 | 130 | + company2 | 07-01-2023 | 50 | 1400 + company2 | 07-02-2023 | 2000 | + company2 | 07-03-2023 | 1500 | + company2 | 07-04-2023 | 1400 | + company2 | 07-05-2023 | 1500 | + company2 | 07-06-2023 | 60 | 1200 + company2 | 07-07-2023 | 1100 | + company2 | 07-08-2023 | 1300 | + company2 | 07-09-2023 | 1200 | + company2 | 07-10-2023 | 1300 | +(20 rows) + +-- omit "START" in DEFINE but it is ok because "START AS TRUE" is +-- implicitly defined. per spec. +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w, + nth_value(tdate, 2) OVER w AS nth_second + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + company | tdate | price | first_value | last_value | nth_second +----------+------------+-------+-------------+------------+------------ + company1 | 07-01-2023 | 100 | 100 | 140 | 07-02-2023 + company1 | 07-02-2023 | 200 | | | + company1 | 07-03-2023 | 150 | | | + company1 | 07-04-2023 | 140 | | | + company1 | 07-05-2023 | 150 | | | + company1 | 07-06-2023 | 90 | 90 | 120 | 07-07-2023 + company1 | 07-07-2023 | 110 | | | + company1 | 07-08-2023 | 130 | | | + company1 | 07-09-2023 | 120 | | | + company1 | 07-10-2023 | 130 | | | + company2 | 07-01-2023 | 50 | 50 | 1400 | 07-02-2023 + company2 | 07-02-2023 | 2000 | | | + company2 | 07-03-2023 | 1500 | | | + company2 | 07-04-2023 | 1400 | | | + company2 | 07-05-2023 | 1500 | | | + company2 | 07-06-2023 | 60 | 60 | 1200 | 07-07-2023 + company2 | 07-07-2023 | 1100 | | | + company2 | 07-08-2023 | 1300 | | | + company2 | 07-09-2023 | 1200 | | | + company2 | 07-10-2023 | 1300 | | | +(20 rows) + +-- the first row start with less than or equal to 100 +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (LOWPRICE UP+ DOWN+) + DEFINE + LOWPRICE AS price <= 100, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + company | tdate | price | first_value | last_value +----------+------------+-------+-------------+------------ + company1 | 07-01-2023 | 100 | 100 | 140 + company1 | 07-02-2023 | 200 | | + company1 | 07-03-2023 | 150 | | + company1 | 07-04-2023 | 140 | | + company1 | 07-05-2023 | 150 | | + company1 | 07-06-2023 | 90 | 90 | 120 + company1 | 07-07-2023 | 110 | | + company1 | 07-08-2023 | 130 | | + company1 | 07-09-2023 | 120 | | + company1 | 07-10-2023 | 130 | | + company2 | 07-01-2023 | 50 | 50 | 1400 + company2 | 07-02-2023 | 2000 | | + company2 | 07-03-2023 | 1500 | | + company2 | 07-04-2023 | 1400 | | + company2 | 07-05-2023 | 1500 | | + company2 | 07-06-2023 | 60 | 60 | 1200 + company2 | 07-07-2023 | 1100 | | + company2 | 07-08-2023 | 1300 | | + company2 | 07-09-2023 | 1200 | | + company2 | 07-10-2023 | 1300 | | +(20 rows) + +-- second row raises 120% +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (LOWPRICE UP+ DOWN+) + DEFINE + LOWPRICE AS price <= 100, + UP AS price > PREV(price) * 1.2, + DOWN AS price < PREV(price) +); + company | tdate | price | first_value | last_value +----------+------------+-------+-------------+------------ + company1 | 07-01-2023 | 100 | 100 | 140 + company1 | 07-02-2023 | 200 | | + company1 | 07-03-2023 | 150 | | + company1 | 07-04-2023 | 140 | | + company1 | 07-05-2023 | 150 | | + company1 | 07-06-2023 | 90 | | + company1 | 07-07-2023 | 110 | | + company1 | 07-08-2023 | 130 | | + company1 | 07-09-2023 | 120 | | + company1 | 07-10-2023 | 130 | | + company2 | 07-01-2023 | 50 | 50 | 1400 + company2 | 07-02-2023 | 2000 | | + company2 | 07-03-2023 | 1500 | | + company2 | 07-04-2023 | 1400 | | + company2 | 07-05-2023 | 1500 | | + company2 | 07-06-2023 | 60 | | + company2 | 07-07-2023 | 1100 | | + company2 | 07-08-2023 | 1300 | | + company2 | 07-09-2023 | 1200 | | + company2 | 07-10-2023 | 1300 | | +(20 rows) + +-- using NEXT +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UPDOWN) + DEFINE + START AS TRUE, + UPDOWN AS price > PREV(price) AND price > NEXT(price) +); + company | tdate | price | first_value | last_value +----------+------------+-------+-------------+------------ + company1 | 07-01-2023 | 100 | 100 | 200 + company1 | 07-02-2023 | 200 | | + company1 | 07-03-2023 | 150 | | + company1 | 07-04-2023 | 140 | 140 | 150 + company1 | 07-05-2023 | 150 | | + company1 | 07-06-2023 | 90 | | + company1 | 07-07-2023 | 110 | 110 | 130 + company1 | 07-08-2023 | 130 | | + company1 | 07-09-2023 | 120 | | + company1 | 07-10-2023 | 130 | | + company2 | 07-01-2023 | 50 | 50 | 2000 + company2 | 07-02-2023 | 2000 | | + company2 | 07-03-2023 | 1500 | | + company2 | 07-04-2023 | 1400 | 1400 | 1500 + company2 | 07-05-2023 | 1500 | | + company2 | 07-06-2023 | 60 | | + company2 | 07-07-2023 | 1100 | 1100 | 1300 + company2 | 07-08-2023 | 1300 | | + company2 | 07-09-2023 | 1200 | | + company2 | 07-10-2023 | 1300 | | +(20 rows) + +-- using AFTER MATCH SKIP TO NEXT ROW +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP TO NEXT ROW + INITIAL + PATTERN (START UPDOWN) + DEFINE + START AS TRUE, + UPDOWN AS price > PREV(price) AND price > NEXT(price) +); + company | tdate | price | first_value | last_value +----------+------------+-------+-------------+------------ + company1 | 07-01-2023 | 100 | 100 | 200 + company1 | 07-02-2023 | 200 | | + company1 | 07-03-2023 | 150 | | + company1 | 07-04-2023 | 140 | 140 | 150 + company1 | 07-05-2023 | 150 | | + company1 | 07-06-2023 | 90 | | + company1 | 07-07-2023 | 110 | 110 | 130 + company1 | 07-08-2023 | 130 | | + company1 | 07-09-2023 | 120 | | + company1 | 07-10-2023 | 130 | | + company2 | 07-01-2023 | 50 | 50 | 2000 + company2 | 07-02-2023 | 2000 | | + company2 | 07-03-2023 | 1500 | | + company2 | 07-04-2023 | 1400 | 1400 | 1500 + company2 | 07-05-2023 | 1500 | | + company2 | 07-06-2023 | 60 | | + company2 | 07-07-2023 | 1100 | 1100 | 1300 + company2 | 07-08-2023 | 1300 | | + company2 | 07-09-2023 | 1200 | | + company2 | 07-10-2023 | 1300 | | +(20 rows) + +-- match everything +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP PAST LAST ROW + INITIAL + PATTERN (A+) + DEFINE + A AS TRUE +); + company | tdate | price | first_value | last_value +----------+------------+-------+-------------+------------ + company1 | 07-01-2023 | 100 | 100 | 130 + company1 | 07-02-2023 | 200 | | + company1 | 07-03-2023 | 150 | | + company1 | 07-04-2023 | 140 | | + company1 | 07-05-2023 | 150 | | + company1 | 07-06-2023 | 90 | | + company1 | 07-07-2023 | 110 | | + company1 | 07-08-2023 | 130 | | + company1 | 07-09-2023 | 120 | | + company1 | 07-10-2023 | 130 | | + company2 | 07-01-2023 | 50 | 50 | 1300 + company2 | 07-02-2023 | 2000 | | + company2 | 07-03-2023 | 1500 | | + company2 | 07-04-2023 | 1400 | | + company2 | 07-05-2023 | 1500 | | + company2 | 07-06-2023 | 60 | | + company2 | 07-07-2023 | 1100 | | + company2 | 07-08-2023 | 1300 | | + company2 | 07-09-2023 | 1200 | | + company2 | 07-10-2023 | 1300 | | +(20 rows) + +-- backtracking with reclassification of rows +-- using AFTER MATCH SKIP PAST LAST ROW +SELECT company, tdate, price, first_value(tdate) OVER w, last_value(tdate) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP PAST LAST ROW + INITIAL + PATTERN (A+ B+) + DEFINE + A AS price > 100, + B AS price > 100 +); + company | tdate | price | first_value | last_value +----------+------------+-------+-------------+------------ + company1 | 07-01-2023 | 100 | | + company1 | 07-02-2023 | 200 | 07-02-2023 | 07-05-2023 + company1 | 07-03-2023 | 150 | | + company1 | 07-04-2023 | 140 | | + company1 | 07-05-2023 | 150 | | + company1 | 07-06-2023 | 90 | | + company1 | 07-07-2023 | 110 | 07-07-2023 | 07-10-2023 + company1 | 07-08-2023 | 130 | | + company1 | 07-09-2023 | 120 | | + company1 | 07-10-2023 | 130 | | + company2 | 07-01-2023 | 50 | | + company2 | 07-02-2023 | 2000 | 07-02-2023 | 07-05-2023 + company2 | 07-03-2023 | 1500 | | + company2 | 07-04-2023 | 1400 | | + company2 | 07-05-2023 | 1500 | | + company2 | 07-06-2023 | 60 | | + company2 | 07-07-2023 | 1100 | 07-07-2023 | 07-10-2023 + company2 | 07-08-2023 | 1300 | | + company2 | 07-09-2023 | 1200 | | + company2 | 07-10-2023 | 1300 | | +(20 rows) + +-- backtracking with reclassification of rows +-- using AFTER MATCH SKIP TO NEXT ROW +SELECT company, tdate, price, first_value(tdate) OVER w, last_value(tdate) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP TO NEXT ROW + INITIAL + PATTERN (A+ B+) + DEFINE + A AS price > 100, + B AS price > 100 +); + company | tdate | price | first_value | last_value +----------+------------+-------+-------------+------------ + company1 | 07-01-2023 | 100 | | + company1 | 07-02-2023 | 200 | 07-02-2023 | 07-05-2023 + company1 | 07-03-2023 | 150 | 07-03-2023 | 07-05-2023 + company1 | 07-04-2023 | 140 | 07-04-2023 | 07-05-2023 + company1 | 07-05-2023 | 150 | | + company1 | 07-06-2023 | 90 | | + company1 | 07-07-2023 | 110 | 07-07-2023 | 07-10-2023 + company1 | 07-08-2023 | 130 | 07-08-2023 | 07-10-2023 + company1 | 07-09-2023 | 120 | 07-09-2023 | 07-10-2023 + company1 | 07-10-2023 | 130 | | + company2 | 07-01-2023 | 50 | | + company2 | 07-02-2023 | 2000 | 07-02-2023 | 07-05-2023 + company2 | 07-03-2023 | 1500 | 07-03-2023 | 07-05-2023 + company2 | 07-04-2023 | 1400 | 07-04-2023 | 07-05-2023 + company2 | 07-05-2023 | 1500 | | + company2 | 07-06-2023 | 60 | | + company2 | 07-07-2023 | 1100 | 07-07-2023 | 07-10-2023 + company2 | 07-08-2023 | 1300 | 07-08-2023 | 07-10-2023 + company2 | 07-09-2023 | 1200 | 07-09-2023 | 07-10-2023 + company2 | 07-10-2023 | 1300 | | +(20 rows) + +-- ROWS BETWEEN CURRENT ROW AND offset FOLLOWING +SELECT company, tdate, price, first_value(tdate) OVER w, last_value(tdate) OVER w, + count(*) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING + AFTER MATCH SKIP PAST LAST ROW + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + company | tdate | price | first_value | last_value | count +----------+------------+-------+-------------+------------+------- + company1 | 07-01-2023 | 100 | 07-01-2023 | 07-03-2023 | 3 + company1 | 07-02-2023 | 200 | | | + company1 | 07-03-2023 | 150 | | | + company1 | 07-04-2023 | 140 | 07-04-2023 | 07-06-2023 | 3 + company1 | 07-05-2023 | 150 | | | + company1 | 07-06-2023 | 90 | | | + company1 | 07-07-2023 | 110 | 07-07-2023 | 07-09-2023 | 3 + company1 | 07-08-2023 | 130 | | | + company1 | 07-09-2023 | 120 | | | + company1 | 07-10-2023 | 130 | | | 0 + company2 | 07-01-2023 | 50 | 07-01-2023 | 07-03-2023 | 3 + company2 | 07-02-2023 | 2000 | | | + company2 | 07-03-2023 | 1500 | | | + company2 | 07-04-2023 | 1400 | 07-04-2023 | 07-06-2023 | 3 + company2 | 07-05-2023 | 1500 | | | + company2 | 07-06-2023 | 60 | | | + company2 | 07-07-2023 | 1100 | 07-07-2023 | 07-09-2023 | 3 + company2 | 07-08-2023 | 1300 | | | + company2 | 07-09-2023 | 1200 | | | + company2 | 07-10-2023 | 1300 | | | 0 +(20 rows) + +-- +-- Aggregates +-- +-- using AFTER MATCH SKIP PAST LAST ROW +SELECT company, tdate, price, + first_value(price) OVER w, + last_value(price) OVER w, + max(price) OVER w, + min(price) OVER w, + sum(price) OVER w, + avg(price) OVER w, + count(price) OVER w +FROM stock +WINDOW w AS ( +PARTITION BY company +ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +AFTER MATCH SKIP PAST LAST ROW +INITIAL +PATTERN (START UP+ DOWN+) +DEFINE +START AS TRUE, +UP AS price > PREV(price), +DOWN AS price < PREV(price) +); + company | tdate | price | first_value | last_value | max | min | sum | avg | count +----------+------------+-------+-------------+------------+------+-----+------+-----------------------+------- + company1 | 07-01-2023 | 100 | 100 | 140 | 200 | 100 | 590 | 147.5000000000000000 | 4 + company1 | 07-02-2023 | 200 | | | | | | | + company1 | 07-03-2023 | 150 | | | | | | | + company1 | 07-04-2023 | 140 | | | | | | | + company1 | 07-05-2023 | 150 | | | | | | | 0 + company1 | 07-06-2023 | 90 | 90 | 120 | 130 | 90 | 450 | 112.5000000000000000 | 4 + company1 | 07-07-2023 | 110 | | | | | | | + company1 | 07-08-2023 | 130 | | | | | | | + company1 | 07-09-2023 | 120 | | | | | | | + company1 | 07-10-2023 | 130 | | | | | | | 0 + company2 | 07-01-2023 | 50 | 50 | 1400 | 2000 | 50 | 4950 | 1237.5000000000000000 | 4 + company2 | 07-02-2023 | 2000 | | | | | | | + company2 | 07-03-2023 | 1500 | | | | | | | + company2 | 07-04-2023 | 1400 | | | | | | | + company2 | 07-05-2023 | 1500 | | | | | | | 0 + company2 | 07-06-2023 | 60 | 60 | 1200 | 1300 | 60 | 3660 | 915.0000000000000000 | 4 + company2 | 07-07-2023 | 1100 | | | | | | | + company2 | 07-08-2023 | 1300 | | | | | | | + company2 | 07-09-2023 | 1200 | | | | | | | + company2 | 07-10-2023 | 1300 | | | | | | | 0 +(20 rows) + +-- using AFTER MATCH SKIP TO NEXT ROW +SELECT company, tdate, price, + first_value(price) OVER w, + last_value(price) OVER w, + max(price) OVER w, + min(price) OVER w, + sum(price) OVER w, + avg(price) OVER w, + count(price) OVER w +FROM stock +WINDOW w AS ( +PARTITION BY company +ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +AFTER MATCH SKIP TO NEXT ROW +INITIAL +PATTERN (START UP+ DOWN+) +DEFINE +START AS TRUE, +UP AS price > PREV(price), +DOWN AS price < PREV(price) +); + company | tdate | price | first_value | last_value | max | min | sum | avg | count +----------+------------+-------+-------------+------------+------+------+------+-----------------------+------- + company1 | 07-01-2023 | 100 | 100 | 140 | 200 | 100 | 590 | 147.5000000000000000 | 4 + company1 | 07-02-2023 | 200 | | | | | | | 0 + company1 | 07-03-2023 | 150 | | | | | | | 0 + company1 | 07-04-2023 | 140 | 140 | 90 | 150 | 90 | 380 | 126.6666666666666667 | 3 + company1 | 07-05-2023 | 150 | | | | | | | 0 + company1 | 07-06-2023 | 90 | 90 | 120 | 130 | 90 | 450 | 112.5000000000000000 | 4 + company1 | 07-07-2023 | 110 | 110 | 120 | 130 | 110 | 360 | 120.0000000000000000 | 3 + company1 | 07-08-2023 | 130 | | | | | | | 0 + company1 | 07-09-2023 | 120 | | | | | | | 0 + company1 | 07-10-2023 | 130 | | | | | | | 0 + company2 | 07-01-2023 | 50 | 50 | 1400 | 2000 | 50 | 4950 | 1237.5000000000000000 | 4 + company2 | 07-02-2023 | 2000 | | | | | | | 0 + company2 | 07-03-2023 | 1500 | | | | | | | 0 + company2 | 07-04-2023 | 1400 | 1400 | 60 | 1500 | 60 | 2960 | 986.6666666666666667 | 3 + company2 | 07-05-2023 | 1500 | | | | | | | 0 + company2 | 07-06-2023 | 60 | 60 | 1200 | 1300 | 60 | 3660 | 915.0000000000000000 | 4 + company2 | 07-07-2023 | 1100 | 1100 | 1200 | 1300 | 1100 | 3600 | 1200.0000000000000000 | 3 + company2 | 07-08-2023 | 1300 | | | | | | | 0 + company2 | 07-09-2023 | 1200 | | | | | | | 0 + company2 | 07-10-2023 | 1300 | | | | | | | 0 +(20 rows) + +-- JOIN case +CREATE TEMP TABLE t1 (i int, v1 int); +CREATE TEMP TABLE t2 (j int, v2 int); +INSERT INTO t1 VALUES(1,10); +INSERT INTO t1 VALUES(1,11); +INSERT INTO t1 VALUES(1,12); +INSERT INTO t2 VALUES(2,10); +INSERT INTO t2 VALUES(2,11); +INSERT INTO t2 VALUES(2,12); +SELECT * FROM t1, t2 WHERE t1.v1 <= 11 AND t2.v2 <= 11; + i | v1 | j | v2 +---+----+---+---- + 1 | 10 | 2 | 10 + 1 | 10 | 2 | 11 + 1 | 11 | 2 | 10 + 1 | 11 | 2 | 11 +(4 rows) + +SELECT *, count(*) OVER w FROM t1, t2 +WINDOW w AS ( + PARTITION BY t1.i + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (A) + DEFINE + A AS v1 <= 11 AND v2 <= 11 +); + i | v1 | j | v2 | count +---+----+---+----+------- + 1 | 10 | 2 | 10 | 1 + 1 | 10 | 2 | 11 | 1 + 1 | 10 | 2 | 12 | 0 + 1 | 11 | 2 | 10 | 1 + 1 | 11 | 2 | 11 | 1 + 1 | 11 | 2 | 12 | 0 + 1 | 12 | 2 | 10 | 0 + 1 | 12 | 2 | 11 | 0 + 1 | 12 | 2 | 12 | 0 +(9 rows) + +-- WITH case +WITH wstock AS ( + SELECT * FROM stock WHERE tdate < '2023-07-08' +) +SELECT tdate, price, +first_value(tdate) OVER w, +count(*) OVER w + FROM wstock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + tdate | price | first_value | count +------------+-------+-------------+------- + 07-01-2023 | 100 | 07-01-2023 | 4 + 07-02-2023 | 200 | | + 07-03-2023 | 150 | | + 07-04-2023 | 140 | | + 07-05-2023 | 150 | | 0 + 07-06-2023 | 90 | | 0 + 07-07-2023 | 110 | | 0 + 07-01-2023 | 50 | 07-01-2023 | 4 + 07-02-2023 | 2000 | | + 07-03-2023 | 1500 | | + 07-04-2023 | 1400 | | + 07-05-2023 | 1500 | | 0 + 07-06-2023 | 60 | | 0 + 07-07-2023 | 1100 | | 0 +(14 rows) + +-- +-- Error cases +-- +-- row pattern definition variable name must not appear more than once +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ORDER BY tdate + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price), + UP AS price > PREV(price) +); +ERROR: syntax error at or near "ORDER" +LINE 6: ORDER BY tdate + ^ +-- pattern variable name must appear in DEFINE +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+ END) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); +ERROR: syntax error at or near "END" +LINE 8: PATTERN (START UP+ DOWN+ END) + ^ +-- FRAME must start at current row when row patttern recognition is used +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); +ERROR: FRAME must start at current row when row patttern recognition is used +-- SEEK is not supported +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP TO NEXT ROW + SEEK + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); +ERROR: SEEK is not supported +LINE 8: SEEK + ^ +HINT: Use INITIAL. diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 675c567617..0ca2713c3d 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -98,7 +98,7 @@ test: publication subscription # Another group of parallel tests # select_views depends on create_view # ---------- -test: select_views portals_p2 foreign_key cluster dependency guc bitmapops combocid tsearch tsdicts foreign_data window xmlmap functional_deps advisory_lock indirect_toast equivclass +test: select_views portals_p2 foreign_key cluster dependency guc bitmapops combocid tsearch tsdicts foreign_data window xmlmap functional_deps advisory_lock indirect_toast equivclass rpr # ---------- # Another group of parallel tests (JSON related) diff --git a/src/test/regress/sql/rpr.sql b/src/test/regress/sql/rpr.sql new file mode 100644 index 0000000000..0a69cc0e11 --- /dev/null +++ b/src/test/regress/sql/rpr.sql @@ -0,0 +1,392 @@ +-- +-- Test for row pattern definition clause +-- + +CREATE TEMP TABLE stock ( + company TEXT, + tdate DATE, + price INTEGER +); +INSERT INTO stock VALUES ('company1', '2023-07-01', 100); +INSERT INTO stock VALUES ('company1', '2023-07-02', 200); +INSERT INTO stock VALUES ('company1', '2023-07-03', 150); +INSERT INTO stock VALUES ('company1', '2023-07-04', 140); +INSERT INTO stock VALUES ('company1', '2023-07-05', 150); +INSERT INTO stock VALUES ('company1', '2023-07-06', 90); +INSERT INTO stock VALUES ('company1', '2023-07-07', 110); +INSERT INTO stock VALUES ('company1', '2023-07-08', 130); +INSERT INTO stock VALUES ('company1', '2023-07-09', 120); +INSERT INTO stock VALUES ('company1', '2023-07-10', 130); +INSERT INTO stock VALUES ('company2', '2023-07-01', 50); +INSERT INTO stock VALUES ('company2', '2023-07-02', 2000); +INSERT INTO stock VALUES ('company2', '2023-07-03', 1500); +INSERT INTO stock VALUES ('company2', '2023-07-04', 1400); +INSERT INTO stock VALUES ('company2', '2023-07-05', 1500); +INSERT INTO stock VALUES ('company2', '2023-07-06', 60); +INSERT INTO stock VALUES ('company2', '2023-07-07', 1100); +INSERT INTO stock VALUES ('company2', '2023-07-08', 1300); +INSERT INTO stock VALUES ('company2', '2023-07-09', 1200); +INSERT INTO stock VALUES ('company2', '2023-07-10', 1300); + +SELECT * FROM stock; + +-- basic test using PREV +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w, + nth_value(tdate, 2) OVER w AS nth_second + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- basic test using PREV. UP appears twice +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w, + nth_value(tdate, 2) OVER w AS nth_second + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+ UP+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- basic test using PREV. Use '*' +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w, + nth_value(tdate, 2) OVER w AS nth_second + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP* DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- basic test with none greedy pattern +SELECT company, tdate, price, count(*) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (A A A) + DEFINE + A AS price >= 140 AND price <= 150 +); + +-- last_value() should remain consistent +SELECT company, tdate, price, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- omit "START" in DEFINE but it is ok because "START AS TRUE" is +-- implicitly defined. per spec. +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w, + nth_value(tdate, 2) OVER w AS nth_second + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- the first row start with less than or equal to 100 +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (LOWPRICE UP+ DOWN+) + DEFINE + LOWPRICE AS price <= 100, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- second row raises 120% +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (LOWPRICE UP+ DOWN+) + DEFINE + LOWPRICE AS price <= 100, + UP AS price > PREV(price) * 1.2, + DOWN AS price < PREV(price) +); + +-- using NEXT +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UPDOWN) + DEFINE + START AS TRUE, + UPDOWN AS price > PREV(price) AND price > NEXT(price) +); + +-- using AFTER MATCH SKIP TO NEXT ROW +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP TO NEXT ROW + INITIAL + PATTERN (START UPDOWN) + DEFINE + START AS TRUE, + UPDOWN AS price > PREV(price) AND price > NEXT(price) +); + +-- match everything + +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP PAST LAST ROW + INITIAL + PATTERN (A+) + DEFINE + A AS TRUE +); + +-- backtracking with reclassification of rows +-- using AFTER MATCH SKIP PAST LAST ROW +SELECT company, tdate, price, first_value(tdate) OVER w, last_value(tdate) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP PAST LAST ROW + INITIAL + PATTERN (A+ B+) + DEFINE + A AS price > 100, + B AS price > 100 +); + +-- backtracking with reclassification of rows +-- using AFTER MATCH SKIP TO NEXT ROW +SELECT company, tdate, price, first_value(tdate) OVER w, last_value(tdate) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP TO NEXT ROW + INITIAL + PATTERN (A+ B+) + DEFINE + A AS price > 100, + B AS price > 100 +); + +-- ROWS BETWEEN CURRENT ROW AND offset FOLLOWING +SELECT company, tdate, price, first_value(tdate) OVER w, last_value(tdate) OVER w, + count(*) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING + AFTER MATCH SKIP PAST LAST ROW + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- +-- Aggregates +-- + +-- using AFTER MATCH SKIP PAST LAST ROW +SELECT company, tdate, price, + first_value(price) OVER w, + last_value(price) OVER w, + max(price) OVER w, + min(price) OVER w, + sum(price) OVER w, + avg(price) OVER w, + count(price) OVER w +FROM stock +WINDOW w AS ( +PARTITION BY company +ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +AFTER MATCH SKIP PAST LAST ROW +INITIAL +PATTERN (START UP+ DOWN+) +DEFINE +START AS TRUE, +UP AS price > PREV(price), +DOWN AS price < PREV(price) +); + +-- using AFTER MATCH SKIP TO NEXT ROW +SELECT company, tdate, price, + first_value(price) OVER w, + last_value(price) OVER w, + max(price) OVER w, + min(price) OVER w, + sum(price) OVER w, + avg(price) OVER w, + count(price) OVER w +FROM stock +WINDOW w AS ( +PARTITION BY company +ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +AFTER MATCH SKIP TO NEXT ROW +INITIAL +PATTERN (START UP+ DOWN+) +DEFINE +START AS TRUE, +UP AS price > PREV(price), +DOWN AS price < PREV(price) +); + +-- JOIN case +CREATE TEMP TABLE t1 (i int, v1 int); +CREATE TEMP TABLE t2 (j int, v2 int); +INSERT INTO t1 VALUES(1,10); +INSERT INTO t1 VALUES(1,11); +INSERT INTO t1 VALUES(1,12); +INSERT INTO t2 VALUES(2,10); +INSERT INTO t2 VALUES(2,11); +INSERT INTO t2 VALUES(2,12); + +SELECT * FROM t1, t2 WHERE t1.v1 <= 11 AND t2.v2 <= 11; + +SELECT *, count(*) OVER w FROM t1, t2 +WINDOW w AS ( + PARTITION BY t1.i + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (A) + DEFINE + A AS v1 <= 11 AND v2 <= 11 +); + +-- WITH case +WITH wstock AS ( + SELECT * FROM stock WHERE tdate < '2023-07-08' +) +SELECT tdate, price, +first_value(tdate) OVER w, +count(*) OVER w + FROM wstock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- +-- Error cases +-- + +-- row pattern definition variable name must not appear more than once +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ORDER BY tdate + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price), + UP AS price > PREV(price) +); + +-- pattern variable name must appear in DEFINE +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+ END) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- FRAME must start at current row when row patttern recognition is used +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + INITIAL + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); + +-- SEEK is not supported +SELECT company, tdate, price, first_value(price) OVER w, last_value(price) OVER w + FROM stock + WINDOW w AS ( + PARTITION BY company + ORDER BY tdate + ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + AFTER MATCH SKIP TO NEXT ROW + SEEK + PATTERN (START UP+ DOWN+) + DEFINE + START AS TRUE, + UP AS price > PREV(price), + DOWN AS price < PREV(price) +); -- 2.25.1 ----Next_Part(Fri_Apr_12_16_09_08_2024_262)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="v16-0008-Allow-to-print-raw-parse-tree.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v3 1/2] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 882deda6b95..1b873f55c70 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2850,8 +2850,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, bits32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2864,6 +2864,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3278,9 +3279,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3319,7 +3322,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, bits32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4573,7 +4576,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 7c2194b152b..dd03c8c29a6 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -311,21 +311,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + bits32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, bits32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -337,7 +339,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index dfda1af412e..50206ae782f 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -318,9 +318,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -367,7 +367,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 4cd5e262e0f..9f763f756b0 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + bits32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 53e86c0d6e1..80bcda02cb7 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -384,13 +384,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, bits32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, bits32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, bits32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 3b017e043a0..3c82b80d45d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -269,6 +269,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -536,17 +541,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + bits32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + bits32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1479,12 +1485,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + bits32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1524,12 +1530,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, bits32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --pusslgqfg74lfylu Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v3-0002-Define-heap_insert-to-obey-tableam.h-option-bits-.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
* [PATCH v47 2/9] give options bitmask to table_delete/table_update @ 2026-03-30 11:27 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 60+ messages in thread From: Álvaro Herrera @ 2026-03-30 11:27 UTC (permalink / raw) --- src/backend/access/heap/heapam.c | 16 ++++++++++------ src/backend/access/heap/heapam_handler.c | 13 ++++++++----- src/backend/access/table/tableam.c | 6 +++--- src/backend/executor/nodeModifyTable.c | 9 +++++++-- src/include/access/heapam.h | 7 ++++--- src/include/access/tableam.h | 23 +++++++++++++++-------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d34136d2e94..0645b2d5f58 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) */ TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid, TransactionId new_xmax; uint16 new_infomask, new_infomask2; + bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0; bool have_tuple_lock = false; bool iscombo; bool all_visible_cleared = false; @@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) TM_FailureData tmfd; result = heap_delete(relation, tid, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), + 0, + InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { case TM_SelfModified: @@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid) */ TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup LockTupleMode lockmode; result = heap_update(relation, otid, tup, - GetCurrentCommandId(true), InvalidSnapshot, + GetCurrentCommandId(true), 0, + InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); switch (result) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index cdd153c6b6d..69debeff516 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, static TM_Result heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { /* * Currently Deleting of index tuples are handled at vacuum, in case if * the storage itself is cleaning the dead tuples by itself, it is the * time to call the index tuple deletion also. */ - return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); + return heap_delete(relation, tid, cid, options, crosscheck, wait, + tmfd); } static TM_Result heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, slot->tts_tableOid = RelationGetRelid(relation); tuple->t_tableOid = slot->tts_tableOid; - result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + result = heap_update(relation, otid, tuple, cid, options, + crosscheck, wait, tmfd, lockmode, update_indexes); ItemPointerCopy(&tuple->t_self, &slot->tts_tid); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 86481d7c029..68ff0966f1c 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) result = table_tuple_delete(rel, tid, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , - &tmfd, false /* changingPart */ ); + &tmfd); switch (result) { @@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid, result = table_tuple_update(rel, otid, slot, GetCurrentCommandId(true), - snapshot, InvalidSnapshot, + 0, snapshot, InvalidSnapshot, true /* wait for commit */ , &tmfd, &lockmode, update_indexes); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 582bcc367c0..76728f08734 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + uint32 options = 0; + + if (changingPart) + options |= TABLE_DELETE_CHANGING_PARTITION; return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid, estate->es_output_cid, + options, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , - &context->tmfd, - changingPart); + &context->tmfd); } /* @@ -2331,6 +2335,7 @@ lreplace: */ result = table_tuple_update(resultRelationDesc, tupleid, slot, estate->es_output_cid, + 0, estate->es_snapshot, estate->es_crosscheck_snapshot, true /* wait for commit */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 6018dacf0f7..77560b22877 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, uint32 options, BulkInsertState bistate); extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, - CommandId cid, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart); + CommandId cid, uint32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd); extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, + CommandId cid, uint32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index ab2e7fc1dfe..6cdd949f58d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -287,6 +287,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "options" flag bits for table_tuple_delete */ +#define TABLE_DELETE_CHANGING_PARTITION (1 << 0) + +/* "options" flag bits for table_tuple_update */ +/* XXX none at present */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -558,17 +563,18 @@ typedef struct TableAmRoutine TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, - bool changingPart); + TM_FailureData *tmfd); /* see table_tuple_update() for reference about parameters */ TM_Result (*tuple_update) (Relation rel, ItemPointer otid, TupleTableSlot *slot, CommandId cid, + uint32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -1533,12 +1539,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, - Snapshot snapshot, Snapshot crosscheck, bool wait, - TM_FailureData *tmfd, bool changingPart) + uint32 options, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { - return rel->rd_tableam->tuple_delete(rel, tid, cid, + return rel->rd_tableam->tuple_delete(rel, tid, cid, options, snapshot, crosscheck, - wait, tmfd, changingPart); + wait, tmfd); } /* @@ -1578,12 +1584,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, */ static inline TM_Result table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, - CommandId cid, Snapshot snapshot, Snapshot crosscheck, + CommandId cid, uint32 options, + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { return rel->rd_tableam->tuple_update(rel, otid, slot, - cid, snapshot, crosscheck, + cid, options, snapshot, crosscheck, wait, tmfd, lockmode, update_indexes); } -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0003-Add-CONCURRENTLY-option-to-REPACK-command.patch" ^ permalink raw reply [nested|flat] 60+ messages in thread
end of thread, other threads:[~2026-03-30 11:27 UTC | newest] Thread overview: 60+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2024-04-12 06:49 [PATCH v16 7/8] Row pattern recognition patch (tests). Tatsuo Ishii <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v3 1/2] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]> 2026-03-30 11:27 [PATCH v47 2/9] give options bitmask to table_delete/table_update Álvaro Herrera <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox