agora inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH 1/2] fetch_first_with_ties_v7
70+ messages / 4 participants
[nested] [flat]

* [PATCH 1/2] fetch_first_with_ties_v7
@ 2019-03-30 23:04 Tomas Vondra <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Tomas Vondra @ 2019-03-30 23:04 UTC (permalink / raw)

---
 doc/src/sgml/ref/select.sgml            |  9 ++-
 src/backend/executor/nodeLimit.c        | 91 ++++++++++++++++++++++---
 src/backend/nodes/copyfuncs.c           |  7 ++
 src/backend/nodes/equalfuncs.c          |  2 +
 src/backend/nodes/outfuncs.c            | 31 +++++++++
 src/backend/nodes/readfuncs.c           |  6 ++
 src/backend/optimizer/plan/createplan.c | 44 +++++++++++-
 src/backend/optimizer/plan/planner.c    |  1 +
 src/backend/optimizer/util/pathnode.c   | 16 +++++
 src/backend/parser/analyze.c            |  3 +
 src/backend/parser/gram.y               | 49 +++++++++----
 src/include/nodes/execnodes.h           |  3 +
 src/include/nodes/nodes.h               | 12 ++++
 src/include/nodes/parsenodes.h          |  2 +
 src/include/nodes/pathnodes.h           |  1 +
 src/include/nodes/plannodes.h           |  5 ++
 src/include/optimizer/pathnode.h        |  1 +
 src/include/optimizer/planmain.h        |  3 +-
 src/test/regress/expected/limit.out     | 35 ++++++++++
 src/test/regress/sql/limit.sql          | 17 +++++
 20 files changed, 307 insertions(+), 31 deletions(-)

diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml
index 06d611b64c..b3b045ea87 100644
--- a/doc/src/sgml/ref/select.sgml
+++ b/doc/src/sgml/ref/select.sgml
@@ -44,7 +44,7 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replac
     [ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
     [ LIMIT { <replaceable class="parameter">count</replaceable> | ALL } ]
     [ OFFSET <replaceable class="parameter">start</replaceable> [ ROW | ROWS ] ]
-    [ FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } ONLY ]
+    [ FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } [ ONLY | WITH TIES ] ]
     [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ]
 
 <phrase>where <replaceable class="parameter">from_item</replaceable> can be one of:</phrase>
@@ -1430,7 +1430,7 @@ OFFSET <replaceable class="parameter">start</replaceable>
     which <productname>PostgreSQL</productname> also supports.  It is:
 <synopsis>
 OFFSET <replaceable class="parameter">start</replaceable> { ROW | ROWS }
-FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } ONLY
+FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } [ ONLY | WITH TIES ]
 </synopsis>
     In this syntax, the <replaceable class="parameter">start</replaceable>
     or <replaceable class="parameter">count</replaceable> value is required by
@@ -1440,7 +1440,10 @@ FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] {
     ambiguity.
     If <replaceable class="parameter">count</replaceable> is
     omitted in a <literal>FETCH</literal> clause, it defaults to 1.
-    <literal>ROW</literal>
+    <literal>ROW</literal> .
+    <literal>WITH TIES</literal> option is used to return two or more rows
+    that tie for last place in the limit results set according to <literal>ORDER BY</literal>
+    clause (<literal>ORDER BY</literal> clause must be specified in this case).
     and <literal>ROWS</literal> as well as <literal>FIRST</literal>
     and <literal>NEXT</literal> are noise words that don't influence
     the effects of these clauses.
diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c
index baa669abe8..e8aed10177 100644
--- a/src/backend/executor/nodeLimit.c
+++ b/src/backend/executor/nodeLimit.c
@@ -41,6 +41,7 @@ static TupleTableSlot *			/* return: a tuple or NULL */
 ExecLimit(PlanState *pstate)
 {
 	LimitState *node = castNode(LimitState, pstate);
+	ExprContext *econtext = node->ps.ps_ExprContext;
 	ScanDirection direction;
 	TupleTableSlot *slot;
 	PlanState  *outerPlan;
@@ -131,7 +132,8 @@ ExecLimit(PlanState *pstate)
 				 * the state machine state to record having done so.
 				 */
 				if (!node->noCount &&
-					node->position - node->offset >= node->count)
+					node->position - node->offset >= node->count &&
+					node->limitOption == WITH_ONLY)
 				{
 					node->lstate = LIMIT_WINDOWEND;
 
@@ -144,18 +146,64 @@ ExecLimit(PlanState *pstate)
 
 					return NULL;
 				}
+				else if (!node->noCount &&
+						 node->position - node->offset >= node->count &&
+						 node->limitOption == WITH_TIES)
+				{
+					/*
+					 * Get next tuple from subplan, if any.
+					 */
+					slot = ExecProcNode(outerPlan);
+					if (TupIsNull(slot))
+					{
+						node->lstate = LIMIT_SUBPLANEOF;
+						return NULL;
+					}
+					/*
+					 * Test if the new tuple and the last tuple match.
+					 * If so we return the tuple.
+					 */
+					econtext->ecxt_innertuple = slot;
+					econtext->ecxt_outertuple = node->last_slot;
+					if (ExecQualAndReset(node->eqfunction, econtext))
+					{
+						ExecCopySlot(node->last_slot, slot);
+						node->subSlot = slot;
+						node->position++;
+					}
+					else
+					{
+						node->lstate = LIMIT_WINDOWEND;
+
+						/*
+						* If we know we won't need to back up, we can release
+						* resources at this point.
+						*/
+						if (!(node->ps.state->es_top_eflags & EXEC_FLAG_BACKWARD))
+							(void) ExecShutdownNode(outerPlan);
+
+						return NULL;
+					}
 
-				/*
-				 * Get next tuple from subplan, if any.
-				 */
-				slot = ExecProcNode(outerPlan);
-				if (TupIsNull(slot))
+				}
+				else
 				{
-					node->lstate = LIMIT_SUBPLANEOF;
-					return NULL;
+					/*
+					 * Get next tuple from subplan, if any.
+					 */
+					slot = ExecProcNode(outerPlan);
+					if (TupIsNull(slot))
+					{
+						node->lstate = LIMIT_SUBPLANEOF;
+						return NULL;
+					}
+					if (node->limitOption == WITH_TIES)
+					{
+						ExecCopySlot(node->last_slot, slot);
+					}
+					node->subSlot = slot;
+					node->position++;
 				}
-				node->subSlot = slot;
-				node->position++;
 			}
 			else
 			{
@@ -311,7 +359,8 @@ recompute_limits(LimitState *node)
 	 * must update the child node anyway, in case this is a rescan and the
 	 * previous time we got a different result.
 	 */
-	ExecSetTupleBound(compute_tuples_needed(node), outerPlanState(node));
+	if(node->limitOption == WITH_ONLY)
+		ExecSetTupleBound(compute_tuples_needed(node), outerPlanState(node));
 }
 
 /*
@@ -374,6 +423,7 @@ ExecInitLimit(Limit *node, EState *estate, int eflags)
 										   (PlanState *) limitstate);
 	limitstate->limitCount = ExecInitExpr((Expr *) node->limitCount,
 										  (PlanState *) limitstate);
+	limitstate->limitOption = node->limitOption;
 
 	/*
 	 * Initialize result type.
@@ -390,6 +440,25 @@ ExecInitLimit(Limit *node, EState *estate, int eflags)
 	 */
 	limitstate->ps.ps_ProjInfo = NULL;
 
+	/*
+	 * Initialize the equality evaluation, to detect ties.
+	 */
+	if (node->limitOption == WITH_TIES)
+	{
+		TupleDesc       scanDesc;
+		const TupleTableSlotOps *ops;
+		scanDesc = limitstate->ps.ps_ResultTupleDesc;
+		ops = ExecGetResultSlotOps(outerPlanState(limitstate), NULL);
+		limitstate->last_slot = ExecInitExtraTupleSlot(estate, scanDesc, ops);
+		limitstate->eqfunction =
+			execTuplesMatchPrepare(ExecGetResultType(outerPlanState(limitstate)),
+								   node->numCols,
+								   node->uniqColIdx,
+								   node->uniqOperators,
+								   node->uniqCollations,
+								   &limitstate->ps);
+	}
+
 	return limitstate;
 }
 
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 8f51315bee..b14150ac5f 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -1143,6 +1143,11 @@ _copyLimit(const Limit *from)
 	 */
 	COPY_NODE_FIELD(limitOffset);
 	COPY_NODE_FIELD(limitCount);
+	COPY_SCALAR_FIELD(limitOption);
+	COPY_SCALAR_FIELD(numCols);
+	COPY_POINTER_FIELD(uniqColIdx, from->numCols * sizeof(AttrNumber));
+	COPY_POINTER_FIELD(uniqOperators, from->numCols * sizeof(Oid));
+	COPY_POINTER_FIELD(uniqCollations, from->numCols * sizeof(Oid));
 
 	return newnode;
 }
@@ -3033,6 +3038,7 @@ _copyQuery(const Query *from)
 	COPY_NODE_FIELD(sortClause);
 	COPY_NODE_FIELD(limitOffset);
 	COPY_NODE_FIELD(limitCount);
+	COPY_SCALAR_FIELD(limitOption);
 	COPY_NODE_FIELD(rowMarks);
 	COPY_NODE_FIELD(setOperations);
 	COPY_NODE_FIELD(constraintDeps);
@@ -3117,6 +3123,7 @@ _copySelectStmt(const SelectStmt *from)
 	COPY_NODE_FIELD(sortClause);
 	COPY_NODE_FIELD(limitOffset);
 	COPY_NODE_FIELD(limitCount);
+	COPY_SCALAR_FIELD(limitOption);
 	COPY_NODE_FIELD(lockingClause);
 	COPY_NODE_FIELD(withClause);
 	COPY_SCALAR_FIELD(op);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 68b51f3de7..02b59aac83 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -975,6 +975,7 @@ _equalQuery(const Query *a, const Query *b)
 	COMPARE_NODE_FIELD(sortClause);
 	COMPARE_NODE_FIELD(limitOffset);
 	COMPARE_NODE_FIELD(limitCount);
+	COMPARE_SCALAR_FIELD(limitOption);
 	COMPARE_NODE_FIELD(rowMarks);
 	COMPARE_NODE_FIELD(setOperations);
 	COMPARE_NODE_FIELD(constraintDeps);
@@ -1049,6 +1050,7 @@ _equalSelectStmt(const SelectStmt *a, const SelectStmt *b)
 	COMPARE_NODE_FIELD(sortClause);
 	COMPARE_NODE_FIELD(limitOffset);
 	COMPARE_NODE_FIELD(limitCount);
+	COMPARE_SCALAR_FIELD(limitOption);
 	COMPARE_NODE_FIELD(lockingClause);
 	COMPARE_NODE_FIELD(withClause);
 	COMPARE_SCALAR_FIELD(op);
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 3282be0e4b..2d2ea588d2 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -901,12 +901,41 @@ _outLockRows(StringInfo str, const LockRows *node)
 static void
 _outLimit(StringInfo str, const Limit *node)
 {
+	int			i;
 	WRITE_NODE_TYPE("LIMIT");
 
 	_outPlanInfo(str, (const Plan *) node);
 
 	WRITE_NODE_FIELD(limitOffset);
 	WRITE_NODE_FIELD(limitCount);
+	WRITE_ENUM_FIELD(limitOption, LimitOption);
+	WRITE_INT_FIELD(numCols);
+	if (node->numCols > 0)
+	{
+		appendStringInfoString(str, " :uniqColIdx");
+		for (i = 0; i < node->numCols; i++)
+			appendStringInfo(str, " %d", node->uniqColIdx[i]);
+
+		appendStringInfoString(str, " :uniqOperators");
+		for (i = 0; i < node->numCols; i++)
+			appendStringInfo(str, " %u", node->uniqOperators[i]);
+
+		appendStringInfoString(str, " :uniqCollations");
+		for (i = 0; i < node->numCols; i++)
+			appendStringInfo(str, " %u", node->uniqOperators[i]);
+	}
+	else
+	{
+		appendStringInfoString(str, " :uniqColIdx");
+		appendStringInfo(str, " NULL");
+
+		appendStringInfoString(str, " :uniqOperators");
+		appendStringInfo(str, " NULL");
+
+		appendStringInfoString(str, " :uniqCollations");
+		appendStringInfo(str, " NULL");
+	}
+
 }
 
 static void
@@ -2699,6 +2728,7 @@ _outSelectStmt(StringInfo str, const SelectStmt *node)
 	WRITE_NODE_FIELD(sortClause);
 	WRITE_NODE_FIELD(limitOffset);
 	WRITE_NODE_FIELD(limitCount);
+	WRITE_ENUM_FIELD(limitOption, LimitOption);
 	WRITE_NODE_FIELD(lockingClause);
 	WRITE_NODE_FIELD(withClause);
 	WRITE_ENUM_FIELD(op, SetOperation);
@@ -2909,6 +2939,7 @@ _outQuery(StringInfo str, const Query *node)
 	WRITE_NODE_FIELD(sortClause);
 	WRITE_NODE_FIELD(limitOffset);
 	WRITE_NODE_FIELD(limitCount);
+	WRITE_ENUM_FIELD(limitOption, LimitOption);
 	WRITE_NODE_FIELD(rowMarks);
 	WRITE_NODE_FIELD(setOperations);
 	WRITE_NODE_FIELD(constraintDeps);
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 3b96492b36..6d65ba8d59 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -278,6 +278,7 @@ _readQuery(void)
 	READ_NODE_FIELD(sortClause);
 	READ_NODE_FIELD(limitOffset);
 	READ_NODE_FIELD(limitCount);
+	READ_ENUM_FIELD(limitOption, LimitOption);
 	READ_NODE_FIELD(rowMarks);
 	READ_NODE_FIELD(setOperations);
 	READ_NODE_FIELD(constraintDeps);
@@ -2333,6 +2334,11 @@ _readLimit(void)
 
 	READ_NODE_FIELD(limitOffset);
 	READ_NODE_FIELD(limitCount);
+	READ_ENUM_FIELD(limitOption, LimitOption);
+	READ_INT_FIELD(numCols);
+	READ_ATTRNUMBER_ARRAY(uniqColIdx, local_node->numCols);
+	READ_OID_ARRAY(uniqOperators, local_node->numCols);
+	READ_OID_ARRAY(uniqCollations, local_node->numCols);
 
 	READ_DONE();
 }
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index cc222cb06c..7b087fd228 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -2201,7 +2201,9 @@ create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path)
 
 		plan = (Plan *) make_limit(plan,
 								   subparse->limitOffset,
-								   subparse->limitCount);
+								   subparse->limitCount,
+								   subparse->limitOption,
+								   0, NULL, NULL, NULL);
 
 		/* Must apply correct cost/width data to Limit node */
 		plan->startup_cost = mminfo->path->startup_cost;
@@ -2508,13 +2510,43 @@ create_limit_plan(PlannerInfo *root, LimitPath *best_path, int flags)
 {
 	Limit	   *plan;
 	Plan	   *subplan;
+	int			numsortkeys = 0;
+	AttrNumber *sortColIdx = NULL;
+	Oid		   *sortOperators = NULL;
+	Oid		   *sortCollations = NULL;
 
 	/* Limit doesn't project, so tlist requirements pass through */
 	subplan = create_plan_recurse(root, best_path->subpath, flags);
 
+	if (best_path->limitOption == WITH_TIES)
+	{
+		Query	   *parse = root->parse;
+		ListCell   *l;
+
+		numsortkeys = list_length(parse->sortClause);
+		sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
+		sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
+		sortCollations = (Oid *) palloc(numsortkeys * sizeof(Oid));
+
+		numsortkeys = 0;
+		foreach(l, parse->sortClause)
+		{
+			SortGroupClause *sortcl = (SortGroupClause *) lfirst(l);
+			TargetEntry *tle = get_sortgroupclause_tle(sortcl, parse->targetList);
+
+			sortColIdx[numsortkeys] = tle->resno;
+			sortOperators[numsortkeys] = sortcl->eqop;
+			sortCollations[numsortkeys] = exprCollation((Node *) tle->expr);
+			numsortkeys++;
+		}
+
+	}
+
 	plan = make_limit(subplan,
 					  best_path->limitOffset,
-					  best_path->limitCount);
+					  best_path->limitCount,
+					  best_path->limitOption,
+					  numsortkeys, sortColIdx, sortOperators, sortCollations);
 
 	copy_generic_path_info(&plan->plan, (Path *) best_path);
 
@@ -6399,7 +6431,8 @@ make_lockrows(Plan *lefttree, List *rowMarks, int epqParam)
  *	  Build a Limit plan node
  */
 Limit *
-make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount)
+make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount, LimitOption limitOption,
+			int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations)
 {
 	Limit	   *node = makeNode(Limit);
 	Plan	   *plan = &node->plan;
@@ -6411,6 +6444,11 @@ make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount)
 
 	node->limitOffset = limitOffset;
 	node->limitCount = limitCount;
+	node->limitOption = limitOption;
+	node->numCols = ordNumCols;
+	node->uniqColIdx = ordColIdx;
+	node->uniqOperators = ordOperators;
+	node->uniqCollations = ordCollations;
 
 	return node;
 }
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 031e709718..326f6e77d7 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -2173,6 +2173,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
 			path = (Path *) create_limit_path(root, final_rel, path,
 											  parse->limitOffset,
 											  parse->limitCount,
+											  parse->limitOption,
 											  offset_est, count_est);
 		}
 
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 56de8fc370..5bc5924f7a 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -3554,6 +3554,7 @@ LimitPath *
 create_limit_path(PlannerInfo *root, RelOptInfo *rel,
 				  Path *subpath,
 				  Node *limitOffset, Node *limitCount,
+				  LimitOption limitOption,
 				  int64 offset_est, int64 count_est)
 {
 	LimitPath  *pathnode = makeNode(LimitPath);
@@ -3575,6 +3576,7 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
 	pathnode->subpath = subpath;
 	pathnode->limitOffset = limitOffset;
 	pathnode->limitCount = limitCount;
+	pathnode->limitOption = limitOption;
 
 	/*
 	 * Adjust the output rows count and costs according to the offset/limit.
@@ -3616,6 +3618,20 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
 			count_rows = (double) count_est;
 		else
 			count_rows = clamp_row_est(subpath->rows * 0.10);
+		if (limitOption == WITH_TIES)
+		{
+			double	numGroups;
+			double	avgGroupSize;
+			List	*groupExprs;
+
+			groupExprs = get_sortgrouplist_exprs(root->parse->sortClause,
+												  root->parse->targetList);
+
+			numGroups = estimate_num_groups(root, groupExprs, subpath->rows,
+											NULL);
+			avgGroupSize = subpath->rows / numGroups;
+			count_rows = Max(avgGroupSize, count_est + (avgGroupSize/2));
+		}
 		if (count_rows > pathnode->path.rows)
 			count_rows = pathnode->path.rows;
 		if (subpath->rows > 0)
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 400558b552..1d9bf30e20 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -1292,6 +1292,7 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
 											EXPR_KIND_OFFSET, "OFFSET");
 	qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
 										   EXPR_KIND_LIMIT, "LIMIT");
+	qry->limitOption = stmt->limitOption;
 
 	/* transform window clauses after we have seen all window functions */
 	qry->windowClause = transformWindowDefinitions(pstate,
@@ -1540,6 +1541,7 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
 											EXPR_KIND_OFFSET, "OFFSET");
 	qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
 										   EXPR_KIND_LIMIT, "LIMIT");
+	qry->limitOption = stmt->limitOption;
 
 	if (stmt->lockingClause)
 		ereport(ERROR,
@@ -1774,6 +1776,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
 											EXPR_KIND_OFFSET, "OFFSET");
 	qry->limitCount = transformLimitClause(pstate, limitCount,
 										   EXPR_KIND_LIMIT, "LIMIT");
+	qry->limitOption = stmt->limitOption;
 
 	qry->rtable = pstate->p_rtable;
 	qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 01521789e8..de6d2c3267 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -165,6 +165,7 @@ static List *makeOrderedSetArgs(List *directargs, List *orderedargs,
 static void insertSelectOptions(SelectStmt *stmt,
 								List *sortClause, List *lockingClause,
 								Node *limitOffset, Node *limitCount,
+								void *limitOption,
 								WithClause *withClause,
 								core_yyscan_t yyscanner);
 static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
@@ -393,7 +394,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 				target_list opt_target_list insert_column_list set_target_list
 				set_clause_list set_clause
 				def_list operator_def_list indirection opt_indirection
-				reloption_list group_clause TriggerFuncArgs select_limit
+				reloption_list group_clause TriggerFuncArgs select_limit limit_clause
 				opt_select_limit opclass_item_list opclass_drop_list
 				opclass_purpose opt_opfamily transaction_mode_list_or_empty
 				OptTableFuncElementList TableFuncElementList opt_type_modifiers
@@ -455,7 +456,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 				comment_type_any_name comment_type_name
 				security_label_type_any_name security_label_type_name
 
-%type <node>	fetch_args limit_clause select_limit_value
+%type <node>	fetch_args select_limit_value
 				offset_clause select_offset_value
 				select_fetch_first_value I_or_F_const
 %type <ival>	row_or_rows first_or_next
@@ -11209,7 +11210,7 @@ select_no_parens:
 			| select_clause sort_clause
 				{
 					insertSelectOptions((SelectStmt *) $1, $2, NIL,
-										NULL, NULL, NULL,
+										NULL, NULL, NULL, NULL,
 										yyscanner);
 					$$ = $1;
 				}
@@ -11217,6 +11218,7 @@ select_no_parens:
 				{
 					insertSelectOptions((SelectStmt *) $1, $2, $3,
 										list_nth($4, 0), list_nth($4, 1),
+										(list_nth($4, 2)),
 										NULL,
 										yyscanner);
 					$$ = $1;
@@ -11225,6 +11227,7 @@ select_no_parens:
 				{
 					insertSelectOptions((SelectStmt *) $1, $2, $4,
 										list_nth($3, 0), list_nth($3, 1),
+										(list_nth($3, 2)),
 										NULL,
 										yyscanner);
 					$$ = $1;
@@ -11233,7 +11236,7 @@ select_no_parens:
 				{
 					insertSelectOptions((SelectStmt *) $2, NULL, NIL,
 										NULL, NULL,
-										$1,
+										NULL,$1,
 										yyscanner);
 					$$ = $2;
 				}
@@ -11241,7 +11244,7 @@ select_no_parens:
 				{
 					insertSelectOptions((SelectStmt *) $2, $3, NIL,
 										NULL, NULL,
-										$1,
+										NULL,$1,
 										yyscanner);
 					$$ = $2;
 				}
@@ -11249,6 +11252,7 @@ select_no_parens:
 				{
 					insertSelectOptions((SelectStmt *) $2, $3, $4,
 										list_nth($5, 0), list_nth($5, 1),
+										list_nth($5, 2),
 										$1,
 										yyscanner);
 					$$ = $2;
@@ -11257,6 +11261,7 @@ select_no_parens:
 				{
 					insertSelectOptions((SelectStmt *) $2, $3, $5,
 										list_nth($4, 0), list_nth($4, 1),
+										list_nth($4, 2),
 										$1,
 										yyscanner);
 					$$ = $2;
@@ -11550,20 +11555,20 @@ sortby:		a_expr USING qual_all_Op opt_nulls_order
 
 
 select_limit:
-			limit_clause offset_clause			{ $$ = list_make2($2, $1); }
-			| offset_clause limit_clause		{ $$ = list_make2($1, $2); }
-			| limit_clause						{ $$ = list_make2(NULL, $1); }
-			| offset_clause						{ $$ = list_make2($1, NULL); }
+			limit_clause offset_clause			{ $$ = list_make3($2, list_nth($1, 0), list_nth($1, 1)); }
+			| offset_clause limit_clause		{ $$ = list_make3($1, list_nth($2, 0), list_nth($2, 1)); }
+			| limit_clause						{ $$ = list_make3(NULL, list_nth($1, 0), list_nth($1, 1)); }
+			| offset_clause						{ $$ = list_make3($1, NULL, NULL); }
 		;
 
 opt_select_limit:
 			select_limit						{ $$ = $1; }
-			| /* EMPTY */						{ $$ = list_make2(NULL,NULL); }
+			| /* EMPTY */						{ $$ = list_make3(NULL, NULL, NULL); }
 		;
 
 limit_clause:
 			LIMIT select_limit_value
-				{ $$ = $2; }
+				{ $$ = list_make2($2, NULL); }
 			| LIMIT select_limit_value ',' select_offset_value
 				{
 					/* Disabled because it was too confusing, bjm 2002-02-18 */
@@ -11581,9 +11586,11 @@ limit_clause:
 			 * we can see the ONLY token in the lookahead slot.
 			 */
 			| FETCH first_or_next select_fetch_first_value row_or_rows ONLY
-				{ $$ = $3; }
+				{ $$ = list_make2($3, makeString("WITH_ONLY")); }
+			| FETCH first_or_next select_fetch_first_value row_or_rows WITH TIES
+				{ $$ = list_make2($3, makeString("WITH_TIES")); }
 			| FETCH first_or_next row_or_rows ONLY
-				{ $$ = makeIntConst(1, -1); }
+				{ $$ = list_make2(makeIntConst(1, -1), NULL); }
 		;
 
 offset_clause:
@@ -15840,6 +15847,7 @@ static void
 insertSelectOptions(SelectStmt *stmt,
 					List *sortClause, List *lockingClause,
 					Node *limitOffset, Node *limitCount,
+					void *limitOption,
 					WithClause *withClause,
 					core_yyscan_t yyscanner)
 {
@@ -15878,6 +15886,21 @@ insertSelectOptions(SelectStmt *stmt,
 					 parser_errposition(exprLocation(limitCount))));
 		stmt->limitCount = limitCount;
 	}
+	if (limitOption)
+	{
+		if (stmt->limitOption)
+			ereport(ERROR,
+					(errcode(ERRCODE_SYNTAX_ERROR),
+					 errmsg("multiple limit options not allowed")));
+		if (!stmt->sortClause && strcmp(strVal(limitOption), "WITH_TIES") == 0)
+			ereport(ERROR,
+					(errcode(ERRCODE_SYNTAX_ERROR),
+					 errmsg("WITH TIES options can not be specified without ORDER BY clause")));
+		if (strcmp(strVal(limitOption), "WITH_ONLY") == 0)
+			stmt->limitOption = WITH_ONLY;
+		else
+			stmt->limitOption = WITH_TIES;
+	}
 	if (withClause)
 	{
 		if (stmt->withClause)
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index dbd7ed0363..d469c1364e 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2294,12 +2294,15 @@ typedef struct LimitState
 	PlanState	ps;				/* its first field is NodeTag */
 	ExprState  *limitOffset;	/* OFFSET parameter, or NULL if none */
 	ExprState  *limitCount;		/* COUNT parameter, or NULL if none */
+	LimitOption	limitOption;	/* limit specification type */
 	int64		offset;			/* current OFFSET value */
 	int64		count;			/* current COUNT, if any */
 	bool		noCount;		/* if true, ignore count */
 	LimitStateCond lstate;		/* state machine status, as above */
 	int64		position;		/* 1-based index of last tuple returned */
 	TupleTableSlot *subSlot;	/* tuple last obtained from subplan */
+	ExprState  *eqfunction;		/* tuple equality qual in case of WITH TIES option */
+	TupleTableSlot *last_slot;	/* slot for evaluation of ties */
 } LimitState;
 
 #endif							/* EXECNODES_H */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index ffb4cd4bcc..e5f72188f5 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -821,4 +821,16 @@ typedef enum OnConflictAction
 	ONCONFLICT_UPDATE			/* ON CONFLICT ... DO UPDATE */
 } OnConflictAction;
 
+/*
+ * LimitOption -
+ *	LIMIT option of query
+ *
+ * This is needed in both parsenodes.h and plannodes.h, so put it here...
+ */
+typedef enum LimitOption
+{
+	WITH_ONLY,			/* FETCH FIRST... ONLY */
+	WITH_TIES			/* FETCH FIRST... WITH TIES */
+} LimitOption;
+
 #endif							/* NODES_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 94c0b7a9dd..4b7357910f 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -159,6 +159,7 @@ typedef struct Query
 
 	Node	   *limitOffset;	/* # of result tuples to skip (int8 expr) */
 	Node	   *limitCount;		/* # of result tuples to return (int8 expr) */
+	LimitOption	limitOption;	/* limit type [WITH TIES | WITH ONLY] */
 
 	List	   *rowMarks;		/* a list of RowMarkClause's */
 
@@ -1595,6 +1596,7 @@ typedef struct SelectStmt
 	List	   *sortClause;		/* sort clause (a list of SortBy's) */
 	Node	   *limitOffset;	/* # of result tuples to skip */
 	Node	   *limitCount;		/* # of result tuples to return */
+	LimitOption	limitOption;	/* limit type */
 	List	   *lockingClause;	/* FOR UPDATE (list of LockingClause's) */
 	WithClause *withClause;		/* WITH clause */
 
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 88c8973f3c..a88781122a 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -1785,6 +1785,7 @@ typedef struct LimitPath
 	Path	   *subpath;		/* path representing input source */
 	Node	   *limitOffset;	/* OFFSET parameter, or NULL if none */
 	Node	   *limitCount;		/* COUNT parameter, or NULL if none */
+	LimitOption	limitOption;	/* FETCH FIRST with ties or exact number */
 } LimitPath;
 
 
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 24740c31e3..ff61e057a2 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -953,6 +953,11 @@ typedef struct Limit
 	Plan		plan;
 	Node	   *limitOffset;	/* OFFSET parameter, or NULL if none */
 	Node	   *limitCount;		/* COUNT parameter, or NULL if none */
+	LimitOption	limitOption;	/* fetch first with ties or exact number */
+	int			numCols;		/* number of columns to check for Similarity  */
+	AttrNumber *uniqColIdx;		/* their indexes in the target list */
+	Oid		   *uniqOperators;	/* equality operators to compare with */
+	Oid		   *uniqCollations;	/* collations for equality comparisons */
 } Limit;
 
 
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index 9e79e1cd63..33838952d0 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -264,6 +264,7 @@ extern ModifyTablePath *create_modifytable_path(PlannerInfo *root,
 extern LimitPath *create_limit_path(PlannerInfo *root, RelOptInfo *rel,
 				  Path *subpath,
 				  Node *limitOffset, Node *limitCount,
+				  LimitOption limitOption,
 				  int64 offset_est, int64 count_est);
 
 extern Path *reparameterize_path(PlannerInfo *root, Path *path,
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index 6d10bf3ee8..52d86bd6fb 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -56,7 +56,8 @@ extern Agg *make_agg(List *tlist, List *qual,
 		 int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations,
 		 List *groupingSets, List *chain,
 		 double dNumGroups, Plan *lefttree);
-extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount);
+extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount,
+		 LimitOption limitOption,int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations);
 
 /*
  * prototypes for plan/initsplan.c
diff --git a/src/test/regress/expected/limit.out b/src/test/regress/expected/limit.out
index c18f547cbd..199725ec7f 100644
--- a/src/test/regress/expected/limit.out
+++ b/src/test/regress/expected/limit.out
@@ -503,3 +503,38 @@ select sum(tenthous) as s1, sum(tenthous) + random()*0 as s2
  45020 | 45020
 (3 rows)
 
+--
+-- FETCH FIRST
+-- Check the WITH TIES clause
+--
+SELECT  thousand
+		FROM onek WHERE thousand < 5
+		ORDER BY thousand FETCH FIRST 2 ROW WITH TIES;
+ thousand 
+----------
+        0
+        0
+        0
+        0
+        0
+        0
+        0
+        0
+        0
+        0
+(10 rows)
+
+SELECT  thousand
+		FROM onek WHERE thousand < 5
+		ORDER BY thousand FETCH FIRST 2 ROW ONLY;
+ thousand 
+----------
+        0
+        0
+(2 rows)
+
+-- should fail
+SELECT ''::text AS two, unique1, unique2, stringu1
+		FROM onek WHERE unique1 > 50
+		FETCH FIRST 2 ROW WITH TIES;
+ERROR:  WITH TIES options can not be specified without ORDER BY clause
diff --git a/src/test/regress/sql/limit.sql b/src/test/regress/sql/limit.sql
index 2a313d80ca..8009b746cb 100644
--- a/src/test/regress/sql/limit.sql
+++ b/src/test/regress/sql/limit.sql
@@ -141,3 +141,20 @@ select sum(tenthous) as s1, sum(tenthous) + random()*0 as s2
 
 select sum(tenthous) as s1, sum(tenthous) + random()*0 as s2
   from tenk1 group by thousand order by thousand limit 3;
+
+--
+-- FETCH FIRST
+-- Check the WITH TIES clause
+--
+
+SELECT  thousand
+		FROM onek WHERE thousand < 5
+		ORDER BY thousand FETCH FIRST 2 ROW WITH TIES;
+
+SELECT  thousand
+		FROM onek WHERE thousand < 5
+		ORDER BY thousand FETCH FIRST 2 ROW ONLY;
+-- should fail
+SELECT ''::text AS two, unique1, unique2, stringu1
+		FROM onek WHERE unique1 > 50
+		FETCH FIRST 2 ROW WITH TIES;
-- 
2.20.1


--WIyZ46R2i8wDzkSu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0002-fixes-and-comments.patch"



^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH v39 3/8] Allow to prolong life span of transition tables until transaction end
@ 2019-12-20 01:09 Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:09 UTC (permalink / raw)

Originally, tuplestores of AFTER trigger's transition tables were
freed for each query depth. For our IVM implementation, we would like
to prolong life of the tuplestores because we have to preserve them
for a whole query assuming that some base tables might be changed
in some trigger functions.
---
 src/backend/commands/trigger.c | 80 ++++++++++++++++++++++++++++++++--
 src/include/commands/trigger.h |  2 +
 2 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 401baddbfc6..dc746bccc8e 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -3844,6 +3844,10 @@ typedef struct AfterTriggerEventList
  * end of the list, so it is relatively easy to discard them.  The event
  * list chunks themselves are stored in event_cxt.
  *
+ * prolonged_tuplestored is a list of transition table tuplestores whose
+ * life are prolonged to the end of the outmost query instead of each nested
+ * query.
+ *
  * query_depth is the current depth of nested AfterTriggerBeginQuery calls
  * (-1 when the stack is empty).
  *
@@ -3909,6 +3913,7 @@ typedef struct AfterTriggersData
 	SetConstraintState state;	/* the active S C state */
 	AfterTriggerEventList events;	/* deferred-event list */
 	MemoryContext event_cxt;	/* memory context for events, if any */
+	List   *prolonged_tuplestores;	/* list of prolonged tuplestores */
 
 	/* per-query-level data: */
 	AfterTriggersQueryData *query_stack;	/* array of structs shown below */
@@ -3957,6 +3962,7 @@ struct AfterTriggersTableData
 	bool		closed;			/* true when no longer OK to add tuples */
 	bool		before_trig_done;	/* did we already queue BS triggers? */
 	bool		after_trig_done;	/* did we already queue AS triggers? */
+	bool		prolonged;			/* are transition tables prolonged? */
 	AfterTriggerEventList after_trig_events;	/* if so, saved list pointer */
 
 	/* "old" transition table for UPDATE/DELETE, if any */
@@ -4003,6 +4009,7 @@ static void TransitionTableAddTuple(EState *estate,
 									TupleTableSlot *original_insert_tuple,
 									Tuplestorestate *tuplestore);
 static void AfterTriggerFreeQuery(AfterTriggersQueryData *qs);
+static void release_or_prolong_tuplestore(Tuplestorestate *ts, bool prolonged);
 static SetConstraintState SetConstraintStateCreate(int numalloc);
 static SetConstraintState SetConstraintStateCopy(SetConstraintState origstate);
 static SetConstraintState SetConstraintStateAddItem(SetConstraintState state,
@@ -4898,6 +4905,45 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
 }
 
 
+/*
+ * SetTransitionTablePreserved
+ *
+ * Prolong lifespan of transition tables corresponding specified relid and
+ * command type to the end of the outmost query instead of each nested query.
+ * This enables to use nested AFTER trigger's transition tables from outer
+ * query's triggers.  Currently, only immediate incremental view maintenance
+ * uses this.
+ */
+void
+SetTransitionTablePreserved(Oid relid, CmdType cmdType)
+{
+	AfterTriggersTableData *table;
+	AfterTriggersQueryData *qs;
+	bool		found = false;
+	ListCell   *lc;
+
+	/* Check state, like AfterTriggerSaveEvent. */
+	if (afterTriggers.query_depth < 0)
+		elog(ERROR, "SetTransitionTablePreserved() called outside of query");
+
+	qs = &afterTriggers.query_stack[afterTriggers.query_depth];
+
+	foreach(lc, qs->tables)
+	{
+		table = (AfterTriggersTableData *) lfirst(lc);
+		if (table->relid == relid && table->cmdType == cmdType &&
+			table->closed)
+		{
+			table->prolonged = true;
+			found = true;
+		}
+	}
+
+	if (!found)
+		elog(ERROR,"could not find table with OID %d and command type %d", relid, cmdType);
+}
+
+
 /*
  * GetAfterTriggersTableData
  *
@@ -5138,6 +5184,7 @@ AfterTriggerBeginXact(void)
 	afterTriggers.firing_depth = 0;
 	afterTriggers.batch_callbacks = NIL;
 	afterTriggers.firing_batch_callbacks = false;
+	afterTriggers.prolonged_tuplestores = NIL;
 
 	/*
 	 * Verify that there is no leftover state remaining.  If these assertions
@@ -5312,11 +5359,11 @@ AfterTriggerFreeQuery(AfterTriggersQueryData *qs)
 		ts = table->old_tuplestore;
 		table->old_tuplestore = NULL;
 		if (ts)
-			tuplestore_end(ts);
+			release_or_prolong_tuplestore(ts, table->prolonged);
 		ts = table->new_tuplestore;
 		table->new_tuplestore = NULL;
 		if (ts)
-			tuplestore_end(ts);
+			release_or_prolong_tuplestore(ts, table->prolonged);
 		if (table->storeslot)
 		{
 			TupleTableSlot *slot = table->storeslot;
@@ -5334,8 +5381,33 @@ AfterTriggerFreeQuery(AfterTriggersQueryData *qs)
 	qs->tables = NIL;
 	list_free_deep(tables);
 
-	list_free_deep(qs->batch_callbacks);
-	qs->batch_callbacks = NIL;
+	/* Release prolonged tuplestores at the end of the outmost query */
+	if (afterTriggers.query_depth == 0)
+	{
+		foreach(lc, afterTriggers.prolonged_tuplestores)
+		{
+			ts = (Tuplestorestate *) lfirst(lc);
+			if (ts)
+				tuplestore_end(ts);
+		}
+		afterTriggers.prolonged_tuplestores = NIL;
+	}
+}
+
+/*
+ * Release the tuplestore, or append it to the prolonged tuplestores list.
+ */
+static void
+release_or_prolong_tuplestore(Tuplestorestate *ts, bool prolonged)
+{
+	if (prolonged && afterTriggers.query_depth > 0)
+	{
+		MemoryContext oldcxt = MemoryContextSwitchTo(CurTransactionContext);
+		afterTriggers.prolonged_tuplestores = lappend(afterTriggers.prolonged_tuplestores, ts);
+		MemoryContextSwitchTo(oldcxt);
+	}
+	else
+		tuplestore_end(ts);
 }
 
 
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 0c3d485abf4..f0f052cc759 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -269,6 +269,8 @@ extern void AfterTriggerEndSubXact(bool isCommit);
 extern void AfterTriggerSetState(ConstraintsSetStmt *stmt);
 extern bool AfterTriggerPendingOnRel(Oid relid);
 
+extern void SetTransitionTablePreserved(Oid relid, CmdType cmdType);
+
 
 /*
  * in utils/adt/ri_triggers.c
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0002-Add-relisivm-column-to-pg_class-system-catalog.patch"
Content-Disposition: attachment;
 filename="v39-0002-Add-relisivm-column-to-pg_class-system-catalog.patch"
Content-Transfer-Encoding: 7bit



^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH 28/33] v15 doc review: Ignore BRIN indexes when checking for HOT udpates - commit 5753d4ee320b3f6fb2ff734667a1ce1d9d8615a1
@ 2021-12-29 22:40 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Justin Pryzby @ 2021-12-29 22:40 UTC (permalink / raw)

---
 doc/src/sgml/indexam.sgml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml
index 84de9310712..d4163c96e9f 100644
--- a/doc/src/sgml/indexam.sgml
+++ b/doc/src/sgml/indexam.sgml
@@ -253,7 +253,7 @@ typedef struct IndexAmRoutine
    access method blocks <acronym>HOT</acronym> when an indexed attribute is
    updated. Access methods without pointers to individual tuples (like
    <acronym>BRIN</acronym>) may allow <acronym>HOT</acronym> even in this
-   case. This does not apply to attributes referenced in index predicates,
+   case. This does not apply to attributes referenced in index predicates;
    an update of such attribute always disables <acronym>HOT</acronym>.
   </para>
 
-- 
2.17.1


--924gEkU1VlJlwnwX
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
 filename="0029-v15-doc-review-Some-additional-information-about-whe.patch"



^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread

* [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests
@ 2026-04-22 09:22 Álvaro Herrera <[email protected]>
  0 siblings, 0 replies; 70+ messages in thread

From: Álvaro Herrera @ 2026-04-22 09:22 UTC (permalink / raw)

These tests sometimes run with wal_level=minimal, which does not allow
to run REPACK (CONCURRENTLY).  Move them to test_decoding, which is
ensured to run with high enough wal_level.

Discussion: https://postgr.es/m/[email protected]
---
 contrib/test_decoding/Makefile            |  2 +-
 contrib/test_decoding/expected/repack.out | 30 +++++++++++++++++++++++
 contrib/test_decoding/meson.build         |  1 +
 contrib/test_decoding/sql/repack.sql      | 25 +++++++++++++++++++
 src/test/regress/expected/cluster.out     | 29 +++-------------------
 src/test/regress/sql/cluster.sql          | 13 +++-------
 6 files changed, 65 insertions(+), 35 deletions(-)
 create mode 100644 contrib/test_decoding/expected/repack.out
 create mode 100644 contrib/test_decoding/sql/repack.sql

diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index acbcaed2feb..0111124399a 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -5,7 +5,7 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
 
 REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	decoding_into_rel binary prepared replorigin time messages \
-	spill slot truncate stream stats twophase twophase_stream
+	repack spill slot truncate stream stats twophase twophase_stream
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
 	twophase_snapshot slot_creation_error catalog_change_snapshot \
diff --git a/contrib/test_decoding/expected/repack.out b/contrib/test_decoding/expected/repack.out
new file mode 100644
index 00000000000..70039d824af
--- /dev/null
+++ b/contrib/test_decoding/expected/repack.out
@@ -0,0 +1,30 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+  relname  | ?column? 
+-----------+----------
+ ptnowner  | t
+ ptnowner1 | t
+ ptnowner2 | t
+(3 rows)
+
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/contrib/test_decoding/meson.build b/contrib/test_decoding/meson.build
index cf5b74cf1ab..ac655853d26 100644
--- a/contrib/test_decoding/meson.build
+++ b/contrib/test_decoding/meson.build
@@ -34,6 +34,7 @@ tests += {
       'replorigin',
       'time',
       'messages',
+      'repack',
       'spill',
       'slot',
       'truncate',
diff --git a/contrib/test_decoding/sql/repack.sql b/contrib/test_decoding/sql/repack.sql
new file mode 100644
index 00000000000..bf66bb441ac
--- /dev/null
+++ b/contrib/test_decoding/sql/repack.sql
@@ -0,0 +1,25 @@
+-- Test REPACK (CONCURRENTLY).
+-- This isn't strictly about decoding, but it involves logical decoding
+-- and requires to be run under higher than minimal wal_level, so we can't
+-- have it in the main regression test suite.
+
+
+-- Ownership of partitions is checked
+CREATE TABLE ptnowner(i int unique not null) PARTITION BY LIST (i);
+CREATE INDEX ptnowner_i_idx ON ptnowner(i);
+CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
+CREATE ROLE regress_ptnowner;
+CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
+ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
+REPACK (CONCURRENTLY) ptnowner1;
+RESET SESSION AUTHORIZATION;
+ALTER TABLE ptnowner OWNER TO regress_ptnowner;
+CREATE TEMP TABLE ptnowner_oldnodes AS
+  SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
+  JOIN pg_class AS c ON c.oid=tree.relid;
+SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
+  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
+DROP TABLE ptnowner;
+DROP ROLE regress_ptnowner;
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..b767316cf6b 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -552,8 +552,6 @@ ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 ERROR:  permission denied for table ptnowner
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -562,30 +560,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
 WARNING:  permission denied to execute CLUSTER on "ptnowner2", skipping it
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
-ERROR:  cannot process relation "ptnowner1"
-HINT:  Relation "ptnowner1" has no identity index.
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-  relname  | ?column? 
------------+----------
- ptnowner  | t
- ptnowner1 | f
- ptnowner2 | t
-(3 rows)
-
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 -- Test CLUSTER with external tuplesorting
@@ -731,6 +706,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
 -- checking if it handles table hierarchies identically as well.
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..a22c75282ee 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -262,8 +262,6 @@ CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
 ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
-ALTER TABLE ptnowner1 REPLICA IDENTITY USING INDEX ptnowner1_i_key;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
 ALTER TABLE ptnowner OWNER TO regress_ptnowner;
 CREATE TEMP TABLE ptnowner_oldnodes AS
@@ -271,14 +269,7 @@ CREATE TEMP TABLE ptnowner_oldnodes AS
   JOIN pg_class AS c ON c.oid=tree.relid;
 SET SESSION AUTHORIZATION regress_ptnowner;
 CLUSTER ptnowner USING ptnowner_i_idx;
--- still can't repack without a replica identity
-ALTER TABLE ptnowner1 REPLICA IDENTITY DEFAULT;
-REPACK (CONCURRENTLY) ptnowner1;
 RESET SESSION AUTHORIZATION;
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
-SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
-  JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
 DROP TABLE ptnowner;
 DROP ROLE regress_ptnowner;
 
@@ -346,6 +337,10 @@ COMMIT;
 --
 -- REPACK
 --
+-- Note we cannot test working REPACK (CONCURRENTLY) here, because the
+-- tests could be run with wal_level=minimal, so those tests are
+-- elsewhere.
+--
 ----------------------------------------------------------------------
 
 -- REPACK handles individual tables identically to CLUSTER, but it's worth
-- 
2.47.3


--5vljmhsecqh6fok5--





^ permalink  raw  reply  [nested|flat] 70+ messages in thread


end of thread, other threads:[~2026-04-22 09:22 UTC | newest]

Thread overview: 70+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2019-03-30 23:04 [PATCH 1/2] fetch_first_with_ties_v7 Tomas Vondra <[email protected]>
2019-12-20 01:09 [PATCH v39 3/8] Allow to prolong life span of transition tables until transaction end Yugo Nagata <[email protected]>
2021-12-29 22:40 [PATCH 28/33] v15 doc review: Ignore BRIN indexes when checking for HOT udpates - commit 5753d4ee320b3f6fb2ff734667a1ce1d9d8615a1 Justin Pryzby <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Álvaro Herrera <[email protected]>
2026-04-22 09:22 [PATCH] Move REPACK (CONCURRENTLY) test out of stock regression tests Á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