($INBOX_DIR/description missing)  
help / color / mirror / Atom feed
[PATCH 5/7] fix
75+ messages / 5 participants
[nested] [flat]

* [PATCH 5/7] fix
@ 2020-03-19 01:54 Tomas Vondra <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Tomas Vondra @ 2020-03-19 01:54 UTC (permalink / raw)

---
 .../postgres_fdw/expected/postgres_fdw.out    |  4 ++--
 src/backend/executor/execExpr.c               |  5 +++--
 src/backend/executor/nodeAgg.c                | 20 +++++++++----------
 src/backend/optimizer/util/pathnode.c         |  4 ++--
 4 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index 62c2697920..fc0ed2f4d5 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -3448,8 +3448,8 @@ select c2, sum(c1) from ft1 where c2 < 3 group by rollup(c2) order by 1 nulls la
    Sort Key: ft1.c2
    ->  MixedAggregate
          Output: c2, sum(c1)
-         Hash Key: ft1.c2
          Group Key: ()
+         Hash Key: ft1.c2
          ->  Foreign Scan on public.ft1
                Output: c2, c1
                Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" WHERE ((c2 < 3))
@@ -3473,8 +3473,8 @@ select c2, sum(c1) from ft1 where c2 < 3 group by cube(c2) order by 1 nulls last
    Sort Key: ft1.c2
    ->  MixedAggregate
          Output: c2, sum(c1)
-         Hash Key: ft1.c2
          Group Key: ()
+         Hash Key: ft1.c2
          ->  Foreign Scan on public.ft1
                Output: c2, c1
                Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" WHERE ((c2 < 3))
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 07789501f7..669843faf5 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -2937,7 +2937,7 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, bool nullcheck)
 	PlanState  *parent = &aggstate->ss.ps;
 	ExprEvalStep scratch = {0};
 	bool		isCombine = DO_AGGSPLIT_COMBINE(aggstate->aggsplit);
-	ListCell	*lc;
+	ListCell   *lc;
 	LastAttnumInfo deform = {0, 0, 0};
 
 	state->expr = (Expr *) aggstate;
@@ -2978,6 +2978,7 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, bool nullcheck)
 		NullableDatum *strictargs = NULL;
 		bool	   *strictnulls = NULL;
 		int			argno;
+		int			setno;
 		ListCell   *bail;
 
 		/*
@@ -3155,7 +3156,7 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, bool nullcheck)
 		 * grouping set). Do so for both sort and hash based computations, as
 		 * applicable.
 		 */
-		for (int setno = 0; setno < phase->numsets; setno++)
+		for (setno = 0; setno < phase->numsets; setno++)
 		{
 			ExecBuildAggTransCall(state, aggstate, &scratch, trans_fcinfo,
 								  pertrans, transno, setno, phase, nullcheck);
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 20c5eb98b3..38d0bd5895 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -333,7 +333,7 @@ initialize_phase(AggState *aggstate, int newphase)
 	AggStatePerPhaseSort persort;
 
 	Assert(newphase == 0 || newphase == aggstate->current_phase + 1);
-	
+
 	/* Don't use aggstate->phase here, it might not be initialized yet*/
 	current_phase = aggstate->phases[aggstate->current_phase];
 
@@ -1516,7 +1516,7 @@ hash_agg_entry_size(int numAggs, Size tupleWidth, Size transitionSpace)
  * When called, CurrentMemoryContext should be the per-query context. The
  * already-calculated hash value for the tuple must be specified.
  */
-static void 
+static void
 lookup_hash_entry(AggState *aggstate, AggStatePerPhaseHash perhash, uint32 hash)
 {
 	TupleTableSlot *hashslot = perhash->hashslot;
@@ -1724,7 +1724,7 @@ agg_retrieve_direct(AggState *aggstate)
 					numGroupingSets = aggstate->phase->numsets;
 					node = aggstate->phase->aggnode;
 					numReset = numGroupingSets;
-					pergroups = aggstate->phase->pergroups; 
+					pergroups = aggstate->phase->pergroups;
 				}
 				else
 				{
@@ -2123,7 +2123,7 @@ agg_retrieve_hash_table(AggState *aggstate)
 				 */
 				select_current_set(aggstate, 0, true);
 				initialize_phase(aggstate, aggstate->current_phase + 1);
-				perhash = (AggStatePerPhaseHash) aggstate->phase;	
+				perhash = (AggStatePerPhaseHash) aggstate->phase;
 				ResetTupleHashIterator(perhash->hashtable, &perhash->hashiter);
 
 				continue;
@@ -2269,7 +2269,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 
 	aggstate->maxsets = numGroupingSets;
 	aggstate->numphases = 1 + list_length(node->chain);
-	
+
 	/*
 	 * The first phase is not sorted, agg need to do its own sort. See
 	 * agg_sort_input(), this can only happen in groupingsets case.
@@ -2390,7 +2390,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 	numaggs = aggstate->numaggs;
 	Assert(numaggs == list_length(aggstate->aggs));
 
-	/* 
+	/*
 	 * For each phase, prepare grouping set data and fmgr lookup data for
 	 * compare functions.  Accumulate all_grouped_cols in passing.
 	 */
@@ -2430,7 +2430,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 
 			all_grouped_cols = bms_add_members(all_grouped_cols, cols);
 
-			/* 
+			/*
 			 * Initialize pergroup state. For AGG_HASHED, all groups do transition
 			 * on the fly, all pergroup states are kept in hashtable, everytime
 			 * a tuple is processed, lookup_hash_entry() choose one group and
@@ -2499,7 +2499,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 				phasedata->grouped_cols = NULL;
 			}
 
-			/* 
+			/*
 			 * Initialize pergroup states for AGG_SORTED/AGG_PLAIN/AGG_MIXED
 			 * phases, each set only have one group on the fly, all groups in
 			 * a set can reuse a pergroup state. Unlike AGG_HASHED, we
@@ -3610,8 +3610,8 @@ ExecReScanAgg(AggState *node)
 					   sizeof(AggStatePerGroupData) * node->numaggs);
 		}
 
-		/* 
-		 * the agg did its own first sort using tuplesort and the first
+		/*
+		 * The agg did its own first sort using tuplesort and the first
 		 * tuplesort is kept (see initialize_phase), if the subplan does
 		 * not have any parameter changes, and none of our own parameter
 		 * changes affect input expressions of the aggregated functions,
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 2dfa3fa17e..ff8f676dfb 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -2983,7 +2983,7 @@ create_agg_path(PlannerInfo *root,
  * 'rollups' is a list of RollupData nodes
  * 'agg_costs' contains cost info about the aggregate functions to be computed
  * 'numGroups' is the estimated total number of groups
- * 'is_sorted' is the input sorted in the group cols of first rollup 
+ * 'is_sorted' is the input sorted in the group cols of first rollup
  */
 GroupingSetsPath *
 create_groupingsets_path(PlannerInfo *root,
@@ -3098,7 +3098,7 @@ create_groupingsets_path(PlannerInfo *root,
 			AggStrategy	rollup_strategy;
 			Path	sort_path;	/* dummy for result of cost_sort */
 			Path	agg_path;	/* dummy for result of cost_agg */
-			
+
 			sort_path.startup_cost = 0;
 			sort_path.total_cost = 0;
 			sort_path.rows = subpath->rows;
-- 
2.21.1


--4ms6w442s2ji2wqe
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment;
	filename="0006-Parallel-grouping-sets.patch"
Content-Transfer-Encoding: 8bit



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

* [PATCH 7/7] fix
@ 2020-03-19 02:02 Tomas Vondra <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Tomas Vondra @ 2020-03-19 02:02 UTC (permalink / raw)

---
 src/backend/executor/nodeAgg.c       | 20 ++++++++++----------
 src/backend/jit/llvm/llvmjit_expr.c  |  2 +-
 src/backend/optimizer/plan/planner.c | 12 ++++++------
 3 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index f7b98dd798..51c7f229e2 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -360,7 +360,7 @@ initialize_phase(AggState *aggstate, int newphase)
 		if (persort->store_in)
 		{
 			tuplestore_end(persort->store_in);
-			persort->store_in = NULL;	
+			persort->store_in = NULL;
 		}
 	}
 
@@ -2017,7 +2017,7 @@ agg_preprocess_groupingsets(AggState *aggstate)
 	/* Initialize tuples storage for each aggregate phases */
 	for (phaseidx = 0; phaseidx < aggstate->numphases; phaseidx++)
 	{
-		phase = aggstate->phases[phaseidx];	
+		phase = aggstate->phases[phaseidx];
 
 		if (!phase->is_hashed)
 		{
@@ -2039,12 +2039,12 @@ agg_preprocess_groupingsets(AggState *aggstate)
 			}
 			else
 			{
-				persort->store_in = tuplestore_begin_heap(false, false, work_mem);	
+				persort->store_in = tuplestore_begin_heap(false, false, work_mem);
 			}
 		}
 		else
 		{
-			/* 
+			/*
 			 * If it's a AGG_HASHED, we don't need a storage to store
 			 * the tuples for later process, we can do the transition
 			 * immediately.
@@ -2422,7 +2422,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 	aggstate->maxsets = numGroupingSets;
 	aggstate->numphases = 1 + list_length(node->chain);
 
-	/* 
+	/*
 	 * We are doing final stage of partial groupingsets, do preprocess
 	 * to input tuples first, redirect the tuples to according aggregate
 	 * phases. See agg_preprocess_groupingsets().
@@ -2431,7 +2431,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 	{
 		aggstate->groupingsets_preprocess = true;
 
-		/* 
+		/*
 		 * Allocate gsetid <-> phases mapping, in final stage of
 		 * partial groupingsets, all grouping sets are extracted
 		 * to individual phases, so the number of sets is equal
@@ -2449,7 +2449,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 	 * agg_sort_input(), this can only happen in groupingsets case.
 	 */
 	if (node->sortnode)
-		aggstate->input_sorted = false;	
+		aggstate->input_sorted = false;
 
 	aggstate->aggcontexts = (ExprContext **)
 		palloc0(sizeof(ExprContext *) * numGroupingSets);
@@ -2626,7 +2626,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 				phasedata->setno_gsetids[0] = gs->setId;
 			}
 
-			/* 
+			/*
 			 * Initialize pergroup state. For AGG_HASHED, all groups do transition
 			 * on the fly, all pergroup states are kept in hashtable, everytime
 			 * a tuple is processed, lookup_hash_entry() choose one group and
@@ -2688,7 +2688,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
 					phasedata->grouped_cols[i] = cols;
 					phasedata->gset_lengths[i] = current_length;
 
-					/* 
+					/*
 					 * In the initial stage of partial grouping sets, it provides extra
 					 * grouping sets ID in the targetlist, fill the setno <-> gsetid
 					 * map, so EEOP_GROUPING_SET_ID can evaluate correct gsetid for
@@ -3871,7 +3871,7 @@ ExecReScanAgg(AggState *node)
 			}
 		}
 
-		/* 
+		/*
 		 * if the agg is doing final stage of partial groupingsets, reset the
 		 * flag to do groupingsets preprocess again.
 		 */
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index f442442269..f70eaabd0c 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -1893,7 +1893,7 @@ llvm_compile_expr(ExprState *state)
 					v_aggstatep =
 						LLVMBuildBitCast(b, v_parent, l_ptr(StructAggState), "");
 
-					/* 
+					/*
 					 * op->resvalue =
 					 * aggstate->phase->setno_gsetids
 					 * [aggstate->current_set]
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index cedd3e1c9d..a0186091a1 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -4211,7 +4211,7 @@ create_ordinary_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel,
  * added to grouped_rel->pathlist. And aggsplit value is not sufficient to
  * make a decision.
  */
-static void 
+static void
 consider_groupingsets_paths(PlannerInfo *root,
 							RelOptInfo *grouped_rel,
 							Path *path,
@@ -4601,7 +4601,7 @@ consider_groupingsets_paths(PlannerInfo *root,
 	}
 }
 
-/* 
+/*
  * If we are combining the partial groupingsets aggregation, the input is
  * mixed with tuples from different grouping sets, executor dispatch the
  * tuples to different rollups (phases) according to the grouping set id.
@@ -4644,7 +4644,7 @@ extract_final_rollups(PlannerInfo *root,
 			{
 				new_rollup->groupClause = NIL;
 				new_rollup->gsets_data = list_make1(gs);
-				new_rollup->gsets = list_make1(NIL); 
+				new_rollup->gsets = list_make1(NIL);
 				new_rollup->hashable = false;
 				new_rollup->is_hashed = false;
 			}
@@ -5364,7 +5364,7 @@ make_partial_grouping_target(PlannerInfo *root,
 
 	add_new_columns_to_pathtarget(partial_target, non_group_exprs);
 
-	/* 
+	/*
 	 * We are generate partial groupingsets path, add an expression to show
 	 * the grouping set ID for a tuple, so in the final stage, executor can
 	 * know which set this tuple belongs to and combine them.
@@ -6985,7 +6985,7 @@ create_partial_grouping_paths(PlannerInfo *root,
 													 path,
 													 root->group_pathkeys,
 													 -1.0);
-				
+
 				if (parse->hasAggs)
 					add_partial_path(partially_grouped_rel, (Path *)
 									 create_agg_path(root,
@@ -7059,7 +7059,7 @@ create_partial_grouping_paths(PlannerInfo *root,
 										AGGSPLIT_INITIAL_SERIAL,
 										add_partial_path);
 		}
-		else 
+		else
 		{
 			hashaggtablesize =
 				estimate_hashagg_tablesize(cheapest_partial_path,
-- 
2.21.1


--4ms6w442s2ji2wqe--





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

* [PATCH 2/3] fix
@ 2020-06-15 10:28 Your Name <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Your Name @ 2020-06-15 10:28 UTC (permalink / raw)

---
 src/bin/pg_dump/t/002_pg_dump.pl | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 8c89488a12..d28988b870 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -154,6 +154,8 @@ my %pgdump_runs = (
 		test_key => 'defaults',
 		dump_cmd => [
 			[ 'pg_dump', '-Fc', '-Z6', '--no-sync', 'postgres', ],
+			'|',
+			[ 'perl', '-pe', '', ],
 			'>', "$tempdir/defaults_custom_format_no_seek_parallel_restore.dump", # stdout disables seeking
 		],
 		restore_cmd => [
-- 
2.24.2


--K3vkeaB0MlFjg8U+--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH 2/2] fix
@ 2020-08-01 02:24 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-08-01 02:24 UTC (permalink / raw)

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0


--OQhbRXNHSL5w/5po--





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

* [PATCH v34 2/8] fix
@ 2020-12-12 17:42 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2020-12-12 17:42 UTC (permalink / raw)

---
 src/backend/catalog/index.c      | 23 ++++++-----
 src/backend/commands/cluster.c   |  3 +-
 src/backend/commands/indexcmds.c | 68 ++++++++++++++++----------------
 src/backend/commands/tablecmds.c |  4 +-
 src/backend/tcop/utility.c       |  6 +--
 src/include/catalog/index.h      |  4 +-
 src/include/commands/defrem.h    |  6 +--
 7 files changed, 58 insertions(+), 56 deletions(-)

diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 06342fddf1..da2f45b796 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3594,7 +3594,7 @@ IndexGetRelation(Oid indexId, bool missing_ok)
  */
 void
 reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
-			  ReindexOptions options)
+			  ReindexOptions *options)
 {
 	Relation	iRel,
 				heapRelation;
@@ -3602,7 +3602,6 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
 	IndexInfo  *indexInfo;
 	volatile bool skipped_constraint = false;
 	PGRUsage	ru0;
-	bool		progress = options.REINDEXOPT_REPORT_PROGRESS;
 
 	pg_rusage_init(&ru0);
 
@@ -3611,12 +3610,12 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
 	 * we only need to be sure no schema or data changes are going on.
 	 */
 	heapId = IndexGetRelation(indexId,
-							  options.REINDEXOPT_MISSING_OK);
+							  options->REINDEXOPT_MISSING_OK);
 	/* if relation is missing, leave */
 	if (!OidIsValid(heapId))
 		return;
 
-	if (options.REINDEXOPT_MISSING_OK)
+	if (options->REINDEXOPT_MISSING_OK)
 		heapRelation = try_table_open(heapId, ShareLock);
 	else
 		heapRelation = table_open(heapId, ShareLock);
@@ -3625,7 +3624,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
 	if (!heapRelation)
 		return;
 
-	if (progress)
+	if (options->REINDEXOPT_REPORT_PROGRESS)
 	{
 		pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX,
 									  heapId);
@@ -3641,7 +3640,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
 	 */
 	iRel = index_open(indexId, AccessExclusiveLock);
 
-	if (progress)
+	if (options->REINDEXOPT_REPORT_PROGRESS)
 		pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID,
 									 iRel->rd_rel->relam);
 
@@ -3792,14 +3791,14 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
 	}
 
 	/* Log what we did */
-	if (options.REINDEXOPT_VERBOSE)
+	if (options->REINDEXOPT_VERBOSE)
 		ereport(INFO,
 				(errmsg("index \"%s\" was reindexed",
 						get_rel_name(indexId)),
 				 errdetail_internal("%s",
 									pg_rusage_show(&ru0))));
 
-	if (progress)
+	if (options->REINDEXOPT_REPORT_PROGRESS)
 		pgstat_progress_end_command();
 
 	/* Close rels, but keep locks */
@@ -3846,7 +3845,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
  * index rebuild.
  */
 bool
-reindex_relation(Oid relid, int flags, ReindexOptions options)
+reindex_relation(Oid relid, int flags, ReindexOptions *options)
 {
 	Relation	rel;
 	Oid			toast_relid;
@@ -3861,7 +3860,7 @@ reindex_relation(Oid relid, int flags, ReindexOptions options)
 	 * to prevent schema and data changes in it.  The lock level used here
 	 * should match ReindexTable().
 	 */
-	if (options.REINDEXOPT_MISSING_OK)
+	if (options->REINDEXOPT_MISSING_OK)
 		rel = try_table_open(relid, ShareLock);
 	else
 		rel = table_open(relid, ShareLock);
@@ -3965,9 +3964,9 @@ reindex_relation(Oid relid, int flags, ReindexOptions options)
 		 * Note that this should fail if the toast relation is missing, so
 		 * reset REINDEXOPT_MISSING_OK.
 		 */
-		ReindexOptions newoptions = options;
+		ReindexOptions newoptions = *options;
 		newoptions.REINDEXOPT_MISSING_OK = false;
-		result |= reindex_relation(toast_relid, flags, newoptions);
+		result |= reindex_relation(toast_relid, flags, &newoptions);
 	}
 
 	return result;
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index b0aa3536d1..272723e050 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -1353,6 +1353,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
 				 char newrelpersistence)
 {
 	ObjectAddress object;
+	ReindexOptions reindexopts = {false};
 	Oid			mapped_tables[4];
 	int			reindex_flags;
 	int			i;
@@ -1412,7 +1413,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
 	pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE,
 								 PROGRESS_CLUSTER_PHASE_REBUILD_INDEX);
 
-	reindex_relation(OIDOldHeap, reindex_flags, (ReindexOptions){});
+	reindex_relation(OIDOldHeap, reindex_flags, &reindexopts);
 
 	/* Report that we are now doing clean up */
 	pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE,
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index cd8eaa732d..d39840d493 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -89,9 +89,9 @@ static List *ChooseIndexColumnNames(List *indexElems);
 static void RangeVarCallbackForReindexIndex(const RangeVar *relation,
 											Oid relId, Oid oldRelId, void *arg);
 static void reindex_error_callback(void *args);
-static void ReindexPartitions(Oid relid, ReindexOptions options, bool isTopLevel);
-static void ReindexMultipleInternal(List *relids, ReindexOptions options);
-static bool ReindexRelationConcurrently(Oid relationOid, ReindexOptions options);
+static void ReindexPartitions(Oid relid, ReindexOptions *options, bool isTopLevel);
+static void ReindexMultipleInternal(List *relids, ReindexOptions *options);
+static bool ReindexRelationConcurrently(Oid relationOid, ReindexOptions *options);
 static void update_relispartition(Oid relationId, bool newval);
 static inline void set_indexsafe_procflags(void);
 
@@ -2459,7 +2459,7 @@ ReindexOptions
 ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt)
 {
 	ListCell   *lc;
-	ReindexOptions options = {};
+	ReindexOptions options = {0};
 
 	/* Parse option list */
 	foreach(lc, stmt->params)
@@ -2486,7 +2486,7 @@ ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt)
  *		Recreate a specific index.
  */
 void
-ReindexIndex(RangeVar *indexRelation, ReindexOptions options, bool isTopLevel)
+ReindexIndex(RangeVar *indexRelation, ReindexOptions *options, bool isTopLevel)
 {
 	struct ReindexIndexCallbackState state;
 	Oid			indOid;
@@ -2503,10 +2503,10 @@ ReindexIndex(RangeVar *indexRelation, ReindexOptions options, bool isTopLevel)
 	 * upgrade the lock, but that's OK, because other sessions can't hold
 	 * locks on our temporary table.
 	 */
-	state.options = options;
+	state.options = *options;
 	state.locked_table_oid = InvalidOid;
 	indOid = RangeVarGetRelidExtended(indexRelation,
-									  options.REINDEXOPT_CONCURRENTLY ?
+									  options->REINDEXOPT_CONCURRENTLY ?
 									  ShareUpdateExclusiveLock : AccessExclusiveLock,
 									  0,
 									  RangeVarCallbackForReindexIndex,
@@ -2521,14 +2521,14 @@ ReindexIndex(RangeVar *indexRelation, ReindexOptions options, bool isTopLevel)
 
 	if (relkind == RELKIND_PARTITIONED_INDEX)
 		ReindexPartitions(indOid, options, isTopLevel);
-	else if (options.REINDEXOPT_CONCURRENTLY &&
+	else if (options->REINDEXOPT_CONCURRENTLY &&
 			 persistence != RELPERSISTENCE_TEMP)
 		ReindexRelationConcurrently(indOid, options);
 	else
 	{
-		ReindexOptions newoptions = options;
+		ReindexOptions newoptions = *options;
 		newoptions.REINDEXOPT_REPORT_PROGRESS = true;
-		reindex_index(indOid, false, persistence, newoptions);
+		reindex_index(indOid, false, persistence, &newoptions);
 	}
 }
 
@@ -2608,7 +2608,7 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
  *		Recreate all indexes of a table (and of its toast table, if any)
  */
 Oid
-ReindexTable(RangeVar *relation, ReindexOptions options, bool isTopLevel)
+ReindexTable(RangeVar *relation, ReindexOptions *options, bool isTopLevel)
 {
 	Oid			heapOid;
 	bool		result;
@@ -2622,14 +2622,14 @@ ReindexTable(RangeVar *relation, ReindexOptions options, bool isTopLevel)
 	 * locks on our temporary table.
 	 */
 	heapOid = RangeVarGetRelidExtended(relation,
-									   options.REINDEXOPT_CONCURRENTLY ?
+									   options->REINDEXOPT_CONCURRENTLY ?
 									   ShareUpdateExclusiveLock : ShareLock,
 									   0,
 									   RangeVarCallbackOwnsTable, NULL);
 
 	if (get_rel_relkind(heapOid) == RELKIND_PARTITIONED_TABLE)
 		ReindexPartitions(heapOid, options, isTopLevel);
-	else if (options.REINDEXOPT_CONCURRENTLY &&
+	else if (options->REINDEXOPT_CONCURRENTLY &&
 			 get_rel_persistence(heapOid) != RELPERSISTENCE_TEMP)
 	{
 		result = ReindexRelationConcurrently(heapOid, options);
@@ -2641,12 +2641,12 @@ ReindexTable(RangeVar *relation, ReindexOptions options, bool isTopLevel)
 	}
 	else
 	{
-		ReindexOptions newoptions = options;
+		ReindexOptions newoptions = *options;
 		newoptions.REINDEXOPT_REPORT_PROGRESS = true;
 		result = reindex_relation(heapOid,
 								  REINDEX_REL_PROCESS_TOAST |
 								  REINDEX_REL_CHECK_CONSTRAINTS,
-								  newoptions);
+								  &newoptions);
 		if (!result)
 			ereport(NOTICE,
 					(errmsg("table \"%s\" has no indexes to reindex",
@@ -2666,7 +2666,7 @@ ReindexTable(RangeVar *relation, ReindexOptions options, bool isTopLevel)
  */
 void
 ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
-					  ReindexOptions options)
+					  ReindexOptions *options)
 {
 	Oid			objectOid;
 	Relation	relationRelation;
@@ -2685,7 +2685,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
 		   objectKind == REINDEX_OBJECT_DATABASE);
 
 	if (objectKind == REINDEX_OBJECT_SYSTEM &&
-		options.REINDEXOPT_CONCURRENTLY)
+		options->REINDEXOPT_CONCURRENTLY)
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 				 errmsg("cannot reindex system catalogs concurrently")));
@@ -2793,7 +2793,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
 		 * Skip system tables, since index_create() would reject indexing them
 		 * concurrently (and it would likely fail if we tried).
 		 */
-		if (options.REINDEXOPT_CONCURRENTLY &&
+		if (options->REINDEXOPT_CONCURRENTLY &&
 			IsCatalogRelationOid(relid))
 		{
 			if (!concurrent_warning)
@@ -2859,7 +2859,7 @@ reindex_error_callback(void *arg)
  * by the caller.
  */
 static void
-ReindexPartitions(Oid relid, ReindexOptions options, bool isTopLevel)
+ReindexPartitions(Oid relid, ReindexOptions *options, bool isTopLevel)
 {
 	List	   *partitions = NIL;
 	char		relkind = get_rel_relkind(relid);
@@ -2954,7 +2954,7 @@ ReindexPartitions(Oid relid, ReindexOptions options, bool isTopLevel)
  * and starts a new transaction when finished.
  */
 static void
-ReindexMultipleInternal(List *relids, ReindexOptions options)
+ReindexMultipleInternal(List *relids, ReindexOptions *options)
 {
 	ListCell   *l;
 
@@ -2990,36 +2990,36 @@ ReindexMultipleInternal(List *relids, ReindexOptions options)
 		Assert(relkind != RELKIND_PARTITIONED_INDEX &&
 			   relkind != RELKIND_PARTITIONED_TABLE);
 
-		if (options.REINDEXOPT_CONCURRENTLY &&
+		if (options->REINDEXOPT_CONCURRENTLY &&
 			relpersistence != RELPERSISTENCE_TEMP)
 		{
-			ReindexOptions newoptions = options;
+			ReindexOptions newoptions = *options;
 			newoptions.REINDEXOPT_MISSING_OK = true;
-			(void) ReindexRelationConcurrently(relid, newoptions);
+			(void) ReindexRelationConcurrently(relid, &newoptions);
 			/* ReindexRelationConcurrently() does the verbose output */
 		}
 		else if (relkind == RELKIND_INDEX)
 		{
-			ReindexOptions newoptions = options;
+			ReindexOptions newoptions = *options;
 			newoptions.REINDEXOPT_REPORT_PROGRESS = true;
 			newoptions.REINDEXOPT_MISSING_OK = true;
-			reindex_index(relid, false, relpersistence, newoptions);
+			reindex_index(relid, false, relpersistence, &newoptions);
 			PopActiveSnapshot();
 			/* reindex_index() does the verbose output */
 		}
 		else
 		{
 			bool		result;
-			ReindexOptions newoptions = options;
+			ReindexOptions newoptions = *options;
 			newoptions.REINDEXOPT_REPORT_PROGRESS = true;
 			newoptions.REINDEXOPT_MISSING_OK = true;
 
 			result = reindex_relation(relid,
 									  REINDEX_REL_PROCESS_TOAST |
 									  REINDEX_REL_CHECK_CONSTRAINTS,
-									  newoptions);
+									  &newoptions);
 
-			if (result && options.REINDEXOPT_VERBOSE)
+			if (result && options->REINDEXOPT_VERBOSE)
 				ereport(INFO,
 						(errmsg("table \"%s.%s\" was reindexed",
 								get_namespace_name(get_rel_namespace(relid)),
@@ -3059,7 +3059,7 @@ ReindexMultipleInternal(List *relids, ReindexOptions options)
  * anyway, and a non-concurrent reindex is more efficient.
  */
 static bool
-ReindexRelationConcurrently(Oid relationOid, ReindexOptions options)
+ReindexRelationConcurrently(Oid relationOid, ReindexOptions *options)
 {
 	List	   *heapRelationIds = NIL;
 	List	   *indexIds = NIL;
@@ -3092,7 +3092,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexOptions options)
 											"ReindexConcurrent",
 											ALLOCSET_SMALL_SIZES);
 
-	if (options.REINDEXOPT_VERBOSE)
+	if (options->REINDEXOPT_VERBOSE)
 	{
 		/* Save data needed by REINDEX VERBOSE in private context */
 		oldcontext = MemoryContextSwitchTo(private_context);
@@ -3137,7 +3137,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexOptions options)
 							 errmsg("cannot reindex system catalogs concurrently")));
 
 				/* Open relation to get its indexes */
-				if (options.REINDEXOPT_MISSING_OK)
+				if (options->REINDEXOPT_MISSING_OK)
 				{
 					heapRelation = try_table_open(relationOid,
 												  ShareUpdateExclusiveLock);
@@ -3233,7 +3233,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexOptions options)
 		case RELKIND_INDEX:
 			{
 				Oid			heapId = IndexGetRelation(relationOid,
-													  options.REINDEXOPT_MISSING_OK);
+													  options->REINDEXOPT_MISSING_OK);
 				Relation	heapRelation;
 
 				/* if relation is missing, leave */
@@ -3262,7 +3262,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexOptions options)
 				 * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
 				 * should not be used once all the session locks are taken.
 				 */
-				if (options.REINDEXOPT_MISSING_OK)
+				if (options->REINDEXOPT_MISSING_OK)
 				{
 					heapRelation = try_table_open(heapId,
 												  ShareUpdateExclusiveLock);
@@ -3754,7 +3754,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexOptions options)
 	StartTransactionCommand();
 
 	/* Log what we did */
-	if (options.REINDEXOPT_VERBOSE)
+	if (options->REINDEXOPT_VERBOSE)
 	{
 		if (relkind == RELKIND_INDEX)
 			ereport(INFO,
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 9f218ac0e4..e0f62d3c77 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1854,6 +1854,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
 		{
 			Oid			heap_relid;
 			Oid			toast_relid;
+			ReindexOptions reindexopts = {false}; /* Default options are all false */
 
 			/*
 			 * This effectively deletes all rows in the table, and may be done
@@ -1891,7 +1892,8 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
 			/*
 			 * Reconstruct the indexes to match, and we're done.
 			 */
-			reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST, (ReindexOptions){});
+			reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST,
+					&reindexopts);
 		}
 
 		pgstat_count_truncate(rel);
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index e5a4e8f662..23612b7a90 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -929,10 +929,10 @@ standard_ProcessUtility(PlannedStmt *pstmt,
 				switch (stmt->kind)
 				{
 					case REINDEX_OBJECT_INDEX:
-						ReindexIndex(stmt->relation, options, isTopLevel);
+						ReindexIndex(stmt->relation, &options, isTopLevel);
 						break;
 					case REINDEX_OBJECT_TABLE:
-						ReindexTable(stmt->relation, options, isTopLevel);
+						ReindexTable(stmt->relation, &options, isTopLevel);
 						break;
 					case REINDEX_OBJECT_SCHEMA:
 					case REINDEX_OBJECT_SYSTEM:
@@ -948,7 +948,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
 												  (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
 												  (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
 												  "REINDEX DATABASE");
-						ReindexMultipleTables(stmt->name, stmt->kind, options);
+						ReindexMultipleTables(stmt->name, stmt->kind, &options);
 						break;
 					default:
 						elog(ERROR, "unrecognized object type: %d",
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 81e3de4d22..3a8671f558 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -146,7 +146,7 @@ extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action);
 extern Oid	IndexGetRelation(Oid indexId, bool missing_ok);
 
 extern void reindex_index(Oid indexId, bool skip_constraint_checks,
-						  char relpersistence, ReindexOptions options);
+						  char relpersistence, ReindexOptions *options);
 
 /* Flag bits for reindex_relation(): */
 #define REINDEX_REL_PROCESS_TOAST			0x01
@@ -155,7 +155,7 @@ extern void reindex_index(Oid indexId, bool skip_constraint_checks,
 #define REINDEX_REL_FORCE_INDEXES_UNLOGGED	0x08
 #define REINDEX_REL_FORCE_INDEXES_PERMANENT 0x10
 
-extern bool reindex_relation(Oid relid, int flags, ReindexOptions options);
+extern bool reindex_relation(Oid relid, int flags, ReindexOptions *options);
 
 extern bool ReindexIsProcessingHeap(Oid heapOid);
 extern bool ReindexIsProcessingIndex(Oid indexOid);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 5b1a60d5fa..33df5d5780 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -36,10 +36,10 @@ extern ObjectAddress DefineIndex(Oid relationId,
 								 bool skip_build,
 								 bool quiet);
 extern ReindexOptions ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt);
-extern void ReindexIndex(RangeVar *indexRelation, ReindexOptions options, bool isTopLevel);
-extern Oid	ReindexTable(RangeVar *relation, ReindexOptions options, bool isTopLevel);
+extern void ReindexIndex(RangeVar *indexRelation, ReindexOptions *options, bool isTopLevel);
+extern Oid	ReindexTable(RangeVar *relation, ReindexOptions *options, bool isTopLevel);
 extern void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
-								  ReindexOptions options);
+								  ReindexOptions *options);
 extern char *makeObjectName(const char *name1, const char *name2,
 							const char *label);
 extern char *ChooseRelationName(const char *name1, const char *name2,
-- 
2.17.0


--ucW7QTJbHsz5ya91
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
 filename="v34-0003-ExecReindex-and-ReindexParams.patch"



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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH] fix
@ 2021-01-10 21:41 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-01-10 21:41 UTC (permalink / raw)

---
 src/backend/commands/tablecmds.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index d7b9c63e5f..144c27c303 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17131,6 +17131,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		Oid		partrelid,
 				parentrelid;
 		LOCKTAG		tag;
+		LockRelId	partlockrelid;
 		char   *parentrelname;
 		char   *partrelname;
 
@@ -17162,6 +17163,10 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		table_close(rel, NoLock);
 		tab->rel = NULL;
 
+		partlockrelid.relId = parentrelid;
+		partlockrelid.dbId = MyDatabaseId;
+		LockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
+
 		/* Make updated catalog entry visible */
 		PopActiveSnapshot();
 		CommitTransactionCommand();
@@ -17204,7 +17209,7 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
 					 errmsg("partition \"%s\" was removed concurrently", partrelname)));
 
 		tab->rel = rel;
-
+		UnlockRelationIdForSession(&partlockrelid, ShareUpdateExclusiveLock);
 	}
 
 	/* Do the final part of detaching */
@@ -17444,7 +17449,10 @@ DetachAddConstraintIfNeeded(List **wqueue, Relation partRel)
 	TupleDesc	td = RelationGetDescr(partRel);
 	Constraint *n;
 
-	constraintExpr = make_ands_explicit(RelationGetPartitionQual(partRel));
+	List *l = RelationGetPartitionQual(partRel);
+	Assert(partRel->rd_rel->relispartition);
+	Assert(l != NIL);
+	constraintExpr = make_ands_explicit(l);
 
 	/* If an identical constraint exists, we don't need to create one */
 	if (td->constr && td->constr->num_check > 0)
-- 
2.17.0


--kR3zbvD4cgoYnS/6--





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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* [PATCH 2/3] fix
@ 2021-03-13 21:51 Justin Pryzby <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Justin Pryzby @ 2021-03-13 21:51 UTC (permalink / raw)

---
 src/backend/access/gin/ginarrayproc.c | 3 ++-
 src/test/regress/expected/gin.out     | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index b10bd04ec8..983cc42a86 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -93,7 +93,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
 	if (strategy == GinContainsElemStrategy)
 	{
 		/* single element is passed, set elems to its pointer */
-		elems = &PG_GETARG_DATUM(0);
+		elems = palloc(sizeof(*elems));
+		*elems = PG_GETARG_DATUM(0);
 		nulls = &PG_ARGISNULL(0);
 		nelems = 1;
 	}
diff --git a/src/test/regress/expected/gin.out b/src/test/regress/expected/gin.out
index 698d322e14..7fc7436646 100644
--- a/src/test/regress/expected/gin.out
+++ b/src/test/regress/expected/gin.out
@@ -78,13 +78,13 @@ select count(*) from gin_test_tbl where i @>> 999;
 select count(*) from gin_test_tbl where i @>> 1;
  count 
 -------
-     3
+  2997
 (1 row)
 
 select count(*) from gin_test_tbl where i @>> 999;
  count 
 -------
-     0
+     3
 (1 row)
 
 -- Very weak test for gin_fuzzy_search_limit
-- 
2.17.0


--opg8F0UgoHELSI+9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0003-fk_arrays_elems.patch"



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

* Re: Memory leak from ExecutorState context?
@ 2023-03-01 17:48 Jehan-Guillaume de Rorthais <[email protected]>
  2023-03-01 18:09 ` Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
  2023-03-01 19:29 ` Re: Memory leak from ExecutorState context? Tomas Vondra <[email protected]>
  0 siblings, 2 replies; 75+ messages in thread

From: Jehan-Guillaume de Rorthais @ 2023-03-01 17:48 UTC (permalink / raw)
  To: Tomas Vondra <[email protected]>; +Cc: [email protected]

Hi Tomas,

On Tue, 28 Feb 2023 20:51:02 +0100
Tomas Vondra <[email protected]> wrote:
> On 2/28/23 19:06, Jehan-Guillaume de Rorthais wrote:
> > * HashBatchContext goes up to 1441MB after 240s then stay flat until the end
> >   (400s as the last record)  
> 
> That's interesting. We're using HashBatchContext for very few things, so
> what could it consume so much memory? But e.g. the number of buckets
> should be limited by work_mem, so how could it get to 1.4GB?
> 
> Can you break at ExecHashIncreaseNumBatches/ExecHashIncreaseNumBuckets
> and print how many batches/butches are there?

I did this test this morning.

Batches and buckets increased really quickly to 1048576/1048576.

ExecHashIncreaseNumBatches was really chatty, having hundreds of thousands of
calls, always short-cut'ed to 1048576, I guess because of the conditional block
«/* safety check to avoid overflow */» appearing early in this function.

I disabled the breakpoint on ExecHashIncreaseNumBatches a few time to make the
query run faster. Enabling it at 19.1GB of memory consumption, it stayed
silent till the memory exhaustion (around 21 or 22GB, I don't remember exactly).

The breakpoint on ExecHashIncreaseNumBuckets triggered some times at beginning,
and a last time close to the end of the query execution.

> > Any idea? How could I help to have a better idea if a leak is actually
> > occurring and where exactly?
> 
> Investigating memory leaks is tough, especially for generic memory
> contexts like ExecutorState :-( Even more so when you can't reproduce it
> on a machine with custom builds.
> 
> What I'd try is this:
> 
> 1) attach breakpoints to all returns in AllocSetAlloc(), printing the
> pointer and size for ExecutorState context, so something like
> 
>   break aset.c:783 if strcmp("ExecutorState",context->header.name) == 0
>   commands
>   print MemoryChunkGetPointer(chunk) size
>   cont
>   end
> 
> 2) do the same for AllocSetFree()
> 
> 3) Match the palloc/pfree calls (using the pointer address), to
> determine which ones are not freed and do some stats on the size.
> Usually there's only a couple distinct sizes that account for most of
> the leaked memory.

So here is what I end up with this afternoon, using file, lines and macro from
REL_11_18:

  set logging  on
  set pagination off
  
  break aset.c:781 if strcmp("ExecutorState",context.name) == 0
  commands 1
  print (((char *)(chunk)) + sizeof(struct AllocChunkData))
  print chunk->size
  cont
  end
  
  break aset.c:820 if strcmp("ExecutorState",context.name) == 0
  commands 2
  print (((char *)(chunk)) + sizeof(struct AllocChunkData))
  print chunk->size
  cont 
  end
  
  break aset.c:979 if strcmp("ExecutorState",context.name) == 0
  commands 3
  print (((char *)(chunk)) + sizeof(struct AllocChunkData))
  print chunk->size
  cont 
  end
  
  break AllocSetFree if strcmp("ExecutorState",context.name) == 0
  commands 4 
  print pointer
  cont
  end

So far, gdb had more than 3h of CPU time and is eating 2.4GB of memory. The
backend had only 3'32" of CPU time:

   VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
  2727284   2.4g  17840 R  99.0  7.7 181:25.07 gdb
  9054688 220648 103056 t   1.3  0.7   3:32.05 postmaster

Interestingly, the RES memory of the backend did not explode yet, but VIRT is
already high.

I suppose the query will run for some more hours, hopefully, gdb will not
exhaust the memory in the meantime...

You'll find some intermediate stats I already collected in attachment:

* break 1, 2 and 3 are from AllocSetAlloc, break 4 is from AllocSetFree.
* most of the non-free'd chunk are allocated since the very beginning, before
  the 5000's allocation call for almost 1M call so far.
* 3754 of them have a chunk->size of 0
* it seems there's some buggy stats or data:
       # this one actually really comes from the gdb log
       0x38a77b8: break=3 num=191       sz=4711441762604810240 (weird sz)
       # this one might be a bug in my script
             0x2: break=2 num=945346    sz=2                   (weird address)
* ignoring the weird size requested during the 191st call, the total amount
  of non free'd memory is currently 5488MB

I couldn't print "size" as it is optimzed away, that's why I tracked
chunk->size... Is there anything wrong with my current run and gdb log? 

The gdb log is 5MB compressed. I'll keep it off-list, but I can provide it if
needed.

Stay tuned...

Thank you!


Attachments:

  [application/gzip] allocs-tmp-stats.txt.gz (52.5K, ../../20230301184840.0a897a80@karst/2-allocs-tmp-stats.txt.gz)
  download

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

* Re: Memory leak from ExecutorState context?
  2023-03-01 17:48 Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
@ 2023-03-01 18:09 ` Jehan-Guillaume de Rorthais <[email protected]>
  1 sibling, 0 replies; 75+ messages in thread

From: Jehan-Guillaume de Rorthais @ 2023-03-01 18:09 UTC (permalink / raw)
  To: Tomas Vondra <[email protected]>; +Cc: [email protected]

On Wed, 1 Mar 2023 18:48:40 +0100
Jehan-Guillaume de Rorthais <[email protected]> wrote:
...
> You'll find some intermediate stats I already collected in attachment:
> 
> * break 1, 2 and 3 are from AllocSetAlloc, break 4 is from AllocSetFree.
> * most of the non-free'd chunk are allocated since the very beginning, before
>   the 5000's allocation call for almost 1M call so far.
> * 3754 of them have a chunk->size of 0
> * it seems there's some buggy stats or data:
>        # this one actually really comes from the gdb log
>        0x38a77b8: break=3 num=191       sz=4711441762604810240 (weird sz)
>        # this one might be a bug in my script
>              0x2: break=2 num=945346    sz=2                   (weird address)
> * ignoring the weird size requested during the 191st call, the total amount
>   of non free'd memory is currently 5488MB

I forgot one stat. I don't know if this is expected, normal or not, but 53
chunks has been allocated on an existing address that was not free'd before.

Regards,






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

* Re: Memory leak from ExecutorState context?
  2023-03-01 17:48 Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
@ 2023-03-01 19:29 ` Tomas Vondra <[email protected]>
  2023-03-01 23:18   ` Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
  1 sibling, 1 reply; 75+ messages in thread

From: Tomas Vondra @ 2023-03-01 19:29 UTC (permalink / raw)
  To: Jehan-Guillaume de Rorthais <[email protected]>; +Cc: [email protected]

On 3/1/23 18:48, Jehan-Guillaume de Rorthais wrote:
> Hi Tomas,
> 
> On Tue, 28 Feb 2023 20:51:02 +0100
> Tomas Vondra <[email protected]> wrote:
>> On 2/28/23 19:06, Jehan-Guillaume de Rorthais wrote:
>>> * HashBatchContext goes up to 1441MB after 240s then stay flat until the end
>>>   (400s as the last record)  
>>
>> That's interesting. We're using HashBatchContext for very few things, so
>> what could it consume so much memory? But e.g. the number of buckets
>> should be limited by work_mem, so how could it get to 1.4GB?
>>
>> Can you break at ExecHashIncreaseNumBatches/ExecHashIncreaseNumBuckets
>> and print how many batches/butches are there?
> 
> I did this test this morning.
> 
> Batches and buckets increased really quickly to 1048576/1048576.
> 

OK. I think 1M buckets is mostly expected for work_mem=64MB. It means
buckets will use 8MB, which leaves ~56B per tuple (we're aiming for
fillfactor 1.0).

But 1M batches? I guess that could be problematic. It doesn't seem like
much, but we need 1M files on each side - 1M for the hash table, 1M for
the outer relation. That's 16MB of pointers, but the files are BufFile
and we keep 8kB buffer for each of them. That's ~16GB right there :-(

In practice it probably won't be that bad, because not all files will be
allocated/opened concurrently (especially if this is due to many tuples
having the same value). Assuming that's what's happening here, ofc.

> ExecHashIncreaseNumBatches was really chatty, having hundreds of thousands of
> calls, always short-cut'ed to 1048576, I guess because of the conditional block
> «/* safety check to avoid overflow */» appearing early in this function.
> 

Hmmm, that's a bit weird, no? I mean, the check is

  /* safety check to avoid overflow */
  if (oldnbatch > Min(INT_MAX / 2, MaxAllocSize / (sizeof(void *) * 2)))
     return;

Why would it stop at 1048576? It certainly is not higher than  INT_MAX/2
and with MaxAllocSize = ~1GB the second value should be ~33M. So what's
happening here?

> I disabled the breakpoint on ExecHashIncreaseNumBatches a few time to make the
> query run faster. Enabling it at 19.1GB of memory consumption, it stayed
> silent till the memory exhaustion (around 21 or 22GB, I don't remember exactly).
> 
> The breakpoint on ExecHashIncreaseNumBuckets triggered some times at beginning,
> and a last time close to the end of the query execution.
> 
>>> Any idea? How could I help to have a better idea if a leak is actually
>>> occurring and where exactly?
>>
>> Investigating memory leaks is tough, especially for generic memory
>> contexts like ExecutorState :-( Even more so when you can't reproduce it
>> on a machine with custom builds.
>>
>> What I'd try is this:
>>
>> 1) attach breakpoints to all returns in AllocSetAlloc(), printing the
>> pointer and size for ExecutorState context, so something like
>>
>>   break aset.c:783 if strcmp("ExecutorState",context->header.name) == 0
>>   commands
>>   print MemoryChunkGetPointer(chunk) size
>>   cont
>>   end
>>
>> 2) do the same for AllocSetFree()
>>
>> 3) Match the palloc/pfree calls (using the pointer address), to
>> determine which ones are not freed and do some stats on the size.
>> Usually there's only a couple distinct sizes that account for most of
>> the leaked memory.
> 
> So here is what I end up with this afternoon, using file, lines and macro from
> REL_11_18:
> 
>   set logging  on
>   set pagination off
>   
>   break aset.c:781 if strcmp("ExecutorState",context.name) == 0
>   commands 1
>   print (((char *)(chunk)) + sizeof(struct AllocChunkData))
>   print chunk->size
>   cont
>   end
>   
>   break aset.c:820 if strcmp("ExecutorState",context.name) == 0
>   commands 2
>   print (((char *)(chunk)) + sizeof(struct AllocChunkData))
>   print chunk->size
>   cont 
>   end
>   
>   break aset.c:979 if strcmp("ExecutorState",context.name) == 0
>   commands 3
>   print (((char *)(chunk)) + sizeof(struct AllocChunkData))
>   print chunk->size
>   cont 
>   end
>   
>   break AllocSetFree if strcmp("ExecutorState",context.name) == 0
>   commands 4 
>   print pointer
>   cont
>   end
> 
> So far, gdb had more than 3h of CPU time and is eating 2.4GB of memory. The
> backend had only 3'32" of CPU time:
> 
>    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
>   2727284   2.4g  17840 R  99.0  7.7 181:25.07 gdb
>   9054688 220648 103056 t   1.3  0.7   3:32.05 postmaster
> 
> Interestingly, the RES memory of the backend did not explode yet, but VIRT is
> already high.
> 
> I suppose the query will run for some more hours, hopefully, gdb will not
> exhaust the memory in the meantime...
> 
> You'll find some intermediate stats I already collected in attachment:
> 
> * break 1, 2 and 3 are from AllocSetAlloc, break 4 is from AllocSetFree.
> * most of the non-free'd chunk are allocated since the very beginning, before
>   the 5000's allocation call for almost 1M call so far.
> * 3754 of them have a chunk->size of 0
> * it seems there's some buggy stats or data:
>        # this one actually really comes from the gdb log
>        0x38a77b8: break=3 num=191       sz=4711441762604810240 (weird sz)
>        # this one might be a bug in my script
>              0x2: break=2 num=945346    sz=2                   (weird address)
> * ignoring the weird size requested during the 191st call, the total amount
>   of non free'd memory is currently 5488MB
> 
> I couldn't print "size" as it is optimzed away, that's why I tracked
> chunk->size... Is there anything wrong with my current run and gdb log? 
> 

There's definitely something wrong. The size should not be 0, and
neither it should be > 1GB. I suspect it's because some of the variables
get optimized out, and gdb just uses some nonsense :-(

I guess you'll need to debug the individual breakpoints, and see what's
available. It probably depends on the compiler version, etc. For example
I don't see the "chunk" for breakpoint 3, but "chunk_size" works and I
can print the chunk pointer with a bit of arithmetics:

  p (block->freeptr - chunk_size)

I suppose similar gympastics could work for the other breakpoints.


regards

-- 
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company






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

* Re: Memory leak from ExecutorState context?
  2023-03-01 17:48 Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
  2023-03-01 19:29 ` Re: Memory leak from ExecutorState context? Tomas Vondra <[email protected]>
@ 2023-03-01 23:18   ` Jehan-Guillaume de Rorthais <[email protected]>
  2023-03-02 00:30     ` Re: Memory leak from ExecutorState context? Tomas Vondra <[email protected]>
  0 siblings, 1 reply; 75+ messages in thread

From: Jehan-Guillaume de Rorthais @ 2023-03-01 23:18 UTC (permalink / raw)
  To: Tomas Vondra <[email protected]>; +Cc: [email protected]

Hi,

On Wed, 1 Mar 2023 20:29:11 +0100
Tomas Vondra <[email protected]> wrote:
> On 3/1/23 18:48, Jehan-Guillaume de Rorthais wrote:
> > On Tue, 28 Feb 2023 20:51:02 +0100
> > Tomas Vondra <[email protected]> wrote:  
> >> On 2/28/23 19:06, Jehan-Guillaume de Rorthais wrote:  
> >>> * HashBatchContext goes up to 1441MB after 240s then stay flat until the
> >>> end (400s as the last record)
> >>
> >> That's interesting. We're using HashBatchContext for very few things, so
> >> what could it consume so much memory? But e.g. the number of buckets
> >> should be limited by work_mem, so how could it get to 1.4GB?
> >>
> >> Can you break at ExecHashIncreaseNumBatches/ExecHashIncreaseNumBuckets
> >> and print how many batches/butches are there?  
> > 
> > I did this test this morning.
> > 
> > Batches and buckets increased really quickly to 1048576/1048576.
> 
> OK. I think 1M buckets is mostly expected for work_mem=64MB. It means
> buckets will use 8MB, which leaves ~56B per tuple (we're aiming for
> fillfactor 1.0).
> 
> But 1M batches? I guess that could be problematic. It doesn't seem like
> much, but we need 1M files on each side - 1M for the hash table, 1M for
> the outer relation. That's 16MB of pointers, but the files are BufFile
> and we keep 8kB buffer for each of them. That's ~16GB right there :-(
>
> In practice it probably won't be that bad, because not all files will be
> allocated/opened concurrently (especially if this is due to many tuples
> having the same value). Assuming that's what's happening here, ofc.

And I suppose they are close/freed concurrently as well?

> > ExecHashIncreaseNumBatches was really chatty, having hundreds of thousands
> > of calls, always short-cut'ed to 1048576, I guess because of the
> > conditional block «/* safety check to avoid overflow */» appearing early in
> > this function. 
> 
> Hmmm, that's a bit weird, no? I mean, the check is
> 
>   /* safety check to avoid overflow */
>   if (oldnbatch > Min(INT_MAX / 2, MaxAllocSize / (sizeof(void *) * 2)))
>      return;
> 
> Why would it stop at 1048576? It certainly is not higher than  INT_MAX/2
> and with MaxAllocSize = ~1GB the second value should be ~33M. So what's
> happening here?

Indeed, not the good suspect. But what about this other short-cut then?

    /* do nothing if we've decided to shut off growth */
    if (!hashtable->growEnabled)
        return;

    [...]

    /*
     * If we dumped out either all or none of the tuples in the table, disable
     * further expansion of nbatch.  This situation implies that we have
     * enough tuples of identical hashvalues to overflow spaceAllowed.
     * Increasing nbatch will not fix it since there's no way to subdivide the
     * group any more finely. We have to just gut it out and hope the server
     * has enough RAM.
     */
    if (nfreed == 0 || nfreed == ninmemory)
    {
        hashtable->growEnabled = false;
  #ifdef HJDEBUG
        printf("Hashjoin %p: disabling further increase of nbatch\n",
               hashtable);
  #endif
    }

If I guess correctly, the function is not able to split the current batch, so
it sits and hopes. This is a much better suspect and I can surely track this
from gdb.

Being able to find what are the fields involved in the join could help as well
to check or gather some stats about them, but I hadn't time to dig this yet...

[...]
> >> Investigating memory leaks is tough, especially for generic memory
> >> contexts like ExecutorState :-( Even more so when you can't reproduce it
> >> on a machine with custom builds.
> >>
> >> What I'd try is this:

[...]
> > I couldn't print "size" as it is optimzed away, that's why I tracked
> > chunk->size... Is there anything wrong with my current run and gdb log? 
> 
> There's definitely something wrong. The size should not be 0, and
> neither it should be > 1GB. I suspect it's because some of the variables
> get optimized out, and gdb just uses some nonsense :-(
> 
> I guess you'll need to debug the individual breakpoints, and see what's
> available. It probably depends on the compiler version, etc. For example
> I don't see the "chunk" for breakpoint 3, but "chunk_size" works and I
> can print the chunk pointer with a bit of arithmetics:
> 
>   p (block->freeptr - chunk_size)
> 
> I suppose similar gympastics could work for the other breakpoints.

OK, I'll give it a try tomorrow.

Thank you!

NB: the query has been killed by the replication.






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

* Re: Memory leak from ExecutorState context?
  2023-03-01 17:48 Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
  2023-03-01 19:29 ` Re: Memory leak from ExecutorState context? Tomas Vondra <[email protected]>
  2023-03-01 23:18   ` Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
@ 2023-03-02 00:30     ` Tomas Vondra <[email protected]>
  2023-03-02 12:08       ` Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
  0 siblings, 1 reply; 75+ messages in thread

From: Tomas Vondra @ 2023-03-02 00:30 UTC (permalink / raw)
  To: Jehan-Guillaume de Rorthais <[email protected]>; +Cc: [email protected]

On 3/2/23 00:18, Jehan-Guillaume de Rorthais wrote:
> Hi,
> 
> On Wed, 1 Mar 2023 20:29:11 +0100
> Tomas Vondra <[email protected]> wrote:
>> On 3/1/23 18:48, Jehan-Guillaume de Rorthais wrote:
>>> On Tue, 28 Feb 2023 20:51:02 +0100
>>> Tomas Vondra <[email protected]> wrote:  
>>>> On 2/28/23 19:06, Jehan-Guillaume de Rorthais wrote:  
>>>>> * HashBatchContext goes up to 1441MB after 240s then stay flat until the
>>>>> end (400s as the last record)
>>>>
>>>> That's interesting. We're using HashBatchContext for very few things, so
>>>> what could it consume so much memory? But e.g. the number of buckets
>>>> should be limited by work_mem, so how could it get to 1.4GB?
>>>>
>>>> Can you break at ExecHashIncreaseNumBatches/ExecHashIncreaseNumBuckets
>>>> and print how many batches/butches are there?  
>>>
>>> I did this test this morning.
>>>
>>> Batches and buckets increased really quickly to 1048576/1048576.
>>
>> OK. I think 1M buckets is mostly expected for work_mem=64MB. It means
>> buckets will use 8MB, which leaves ~56B per tuple (we're aiming for
>> fillfactor 1.0).
>>
>> But 1M batches? I guess that could be problematic. It doesn't seem like
>> much, but we need 1M files on each side - 1M for the hash table, 1M for
>> the outer relation. That's 16MB of pointers, but the files are BufFile
>> and we keep 8kB buffer for each of them. That's ~16GB right there :-(
>>
>> In practice it probably won't be that bad, because not all files will be
>> allocated/opened concurrently (especially if this is due to many tuples
>> having the same value). Assuming that's what's happening here, ofc.
> 
> And I suppose they are close/freed concurrently as well?
> 

Yeah. There can be different subsets of the files used, depending on
when the number of batches start to explode, etc.

>>> ExecHashIncreaseNumBatches was really chatty, having hundreds of thousands
>>> of calls, always short-cut'ed to 1048576, I guess because of the
>>> conditional block «/* safety check to avoid overflow */» appearing early in
>>> this function. 
>>
>> Hmmm, that's a bit weird, no? I mean, the check is
>>
>>   /* safety check to avoid overflow */
>>   if (oldnbatch > Min(INT_MAX / 2, MaxAllocSize / (sizeof(void *) * 2)))
>>      return;
>>
>> Why would it stop at 1048576? It certainly is not higher than  INT_MAX/2
>> and with MaxAllocSize = ~1GB the second value should be ~33M. So what's
>> happening here?
> 
> Indeed, not the good suspect. But what about this other short-cut then?
> 
>     /* do nothing if we've decided to shut off growth */
>     if (!hashtable->growEnabled)
>         return;
> 
>     [...]
> 
>     /*
>      * If we dumped out either all or none of the tuples in the table, disable
>      * further expansion of nbatch.  This situation implies that we have
>      * enough tuples of identical hashvalues to overflow spaceAllowed.
>      * Increasing nbatch will not fix it since there's no way to subdivide the
>      * group any more finely. We have to just gut it out and hope the server
>      * has enough RAM.
>      */
>     if (nfreed == 0 || nfreed == ninmemory)
>     {
>         hashtable->growEnabled = false;
>   #ifdef HJDEBUG
>         printf("Hashjoin %p: disabling further increase of nbatch\n",
>                hashtable);
>   #endif
>     }
> 
> If I guess correctly, the function is not able to split the current batch, so
> it sits and hopes. This is a much better suspect and I can surely track this
> from gdb.
> 

Yes, this would make much more sense - it'd be consistent with the
hypothesis that this is due to number of batches exploding (it's a
protection exactly against that).

You specifically mentioned the other check earlier, but now I realize
you've been just speculating it might be that.

> Being able to find what are the fields involved in the join could help as well
> to check or gather some stats about them, but I hadn't time to dig this yet...
> 

It's going to be tricky, because all parts of the plan may be doing
something, and there may be multiple hash joins. So you won't know if
you're executing the part of the plan that's causing issues :-(


But I have another idea - put a breakpoint on makeBufFile() which is the
bit that allocates the temp files including the 8kB buffer, and print in
what context we allocate that. I have a hunch we may be allocating it in
the ExecutorState. That'd explain all the symptoms.


BTW with how many batches does the hash join start?


regards

-- 
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company






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

* Re: Memory leak from ExecutorState context?
  2023-03-01 17:48 Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
  2023-03-01 19:29 ` Re: Memory leak from ExecutorState context? Tomas Vondra <[email protected]>
  2023-03-01 23:18   ` Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
  2023-03-02 00:30     ` Re: Memory leak from ExecutorState context? Tomas Vondra <[email protected]>
@ 2023-03-02 12:08       ` Jehan-Guillaume de Rorthais <[email protected]>
  0 siblings, 0 replies; 75+ messages in thread

From: Jehan-Guillaume de Rorthais @ 2023-03-02 12:08 UTC (permalink / raw)
  To: Tomas Vondra <[email protected]>; +Cc: [email protected]

On Thu, 2 Mar 2023 01:30:27 +0100
Tomas Vondra <[email protected]> wrote:
> On 3/2/23 00:18, Jehan-Guillaume de Rorthais wrote:
> >>> ExecHashIncreaseNumBatches was really chatty, having hundreds of thousands
> >>> of calls, always short-cut'ed to 1048576, I guess because of the
> >>> conditional block «/* safety check to avoid overflow */» appearing early
> >>> in this function.   
> >[...] But what about this other short-cut then?
> > 
> >     /* do nothing if we've decided to shut off growth */
> >     if (!hashtable->growEnabled)
> >         return;
> > 
> >     [...]
> > 
> >     /*
> >      * If we dumped out either all or none of the tuples in the table,
> >      * disable
> >      * further expansion of nbatch.  This situation implies that we have
> >      * enough tuples of identical hashvalues to overflow spaceAllowed.
> >      * Increasing nbatch will not fix it since there's no way to subdivide
> >      * the
> >      * group any more finely. We have to just gut it out and hope the server
> >      * has enough RAM.
> >      */
> >     if (nfreed == 0 || nfreed == ninmemory)
> >     {
> >         hashtable->growEnabled = false;
> >   #ifdef HJDEBUG
> >         printf("Hashjoin %p: disabling further increase of nbatch\n",
> >                hashtable);
> >   #endif
> >     }
> > 
> > If I guess correctly, the function is not able to split the current batch,
> > so it sits and hopes. This is a much better suspect and I can surely track
> > this from gdb.
> 
> Yes, this would make much more sense - it'd be consistent with the
> hypothesis that this is due to number of batches exploding (it's a
> protection exactly against that).
> 
> You specifically mentioned the other check earlier, but now I realize
> you've been just speculating it might be that.

Yes, sorry about that, I jumped on this speculation without actually digging it
much...

[...]
> But I have another idea - put a breakpoint on makeBufFile() which is the
> bit that allocates the temp files including the 8kB buffer, and print in
> what context we allocate that. I have a hunch we may be allocating it in
> the ExecutorState. That'd explain all the symptoms.

That what I was wondering as well yesterday night.

So, on your advice, I set a breakpoint on makeBufFile:

  (gdb) info br
  Num     Type           Disp Enb Address            What
  1       breakpoint     keep y   0x00000000007229df in makeBufFile
          bt 10
          p CurrentMemoryContext.name


Then, I disabled it and ran the query up to this mem usage:

   VIRT    RES    SHR S  %CPU %MEM
  20.1g   7.0g  88504 t   0.0 22.5

Then, I enabled the breakpoint and look at around 600 bt and context name
before getting bored. They **all** looked like that:

  Breakpoint 1, BufFileCreateTemp (...)                at buffile.c:201
  201     in buffile.c
  #0  BufFileCreateTemp (...)                             buffile.c:201
  #1  ExecHashJoinSaveTuple (tuple=0x1952c180, ...)       nodeHashjoin.c:1238
  #2  ExecHashJoinImpl (parallel=false, pstate=0x31a6418) nodeHashjoin.c:398
  #3  ExecHashJoin (pstate=0x31a6418)                     nodeHashjoin.c:584
  #4  ExecProcNodeInstr (node=<optimized out>)            execProcnode.c:462
  #5  ExecProcNode (node=0x31a6418)
  #6  ExecSort (pstate=0x31a6308)
  #7  ExecProcNodeInstr (node=<optimized out>)
  #8  ExecProcNode (node=0x31a6308)
  #9  fetch_input_tuple (aggstate=aggstate@entry=0x31a5ea0)
  
  $421643 = 0x99d7f7 "ExecutorState"

These 600-ish 8kB buffer were all allocated in "ExecutorState". I could
probably log much more of them if more checks/stats need to be collected, but
it really slow down the query a lot, granting it only 1-5% of CPU time instead
of the usual 100%.

So It's not exactly a leakage, as memory would be released at the end of the
query, but I suppose they should be allocated in a shorter living context,
to avoid this memory bloat, am I right?

> BTW with how many batches does the hash join start?

* batches went from 32 to 1048576 before being growEnabled=false as suspected
* original and current nbuckets were set to 1048576 immediately
* allowed space is set to the work_mem, but current space usage is 1.3GB, as
  measured previously close before system refuse more memory allocation.

Here are the full details about the hash associated with the previous backtrace:

  (gdb) up
  (gdb) up
  (gdb) p *((HashJoinState*)pstate)->hj_HashTable
  $421652 = {
    nbuckets = 1048576,
    log2_nbuckets = 20,
    nbuckets_original = 1048576,
    nbuckets_optimal = 1048576,
    log2_nbuckets_optimal = 20,
    buckets = {unshared = 0x68f12e8, shared = 0x68f12e8},
    keepNulls = true,
    skewEnabled = false,
    skewBucket = 0x0,
    skewBucketLen = 0,
    nSkewBuckets = 0,
    skewBucketNums = 0x0,
    nbatch = 1048576,
    curbatch = 0,
    nbatch_original = 32,
    nbatch_outstart = 1048576,
    growEnabled = false,
    totalTuples = 19541735,
    partialTuples = 19541735,
    skewTuples = 0,
    innerBatchFile = 0xdfcd168,
    outerBatchFile = 0xe7cd1a8,
    outer_hashfunctions = 0x68ed3a0,
    inner_hashfunctions = 0x68ed3f0,
    hashStrict = 0x68ed440,
    spaceUsed = 1302386440,
    spaceAllowed = 67108864,
    spacePeak = 1302386440,
    spaceUsedSkew = 0,
    spaceAllowedSkew = 1342177,
    hashCxt = 0x68ed290,
    batchCxt = 0x68ef2a0,
    chunks = 0x251f28e88,
    current_chunk = 0x0,
    area = 0x0,
    parallel_state = 0x0,
    batches = 0x0,
    current_chunk_shared = 1103827828993
  }

For what it worth, contexts are:

  (gdb) p ((HashJoinState*)pstate)->hj_HashTable->hashCxt.name
  $421657 = 0x99e3c0 "HashTableContext"

  (gdb) p ((HashJoinState*)pstate)->hj_HashTable->batchCxt.name
  $421658 = 0x99e3d1 "HashBatchContext"

Regards,






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


end of thread, other threads:[~2023-03-02 12:08 UTC | newest]

Thread overview: 75+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2020-03-19 01:54 [PATCH 5/7] fix Tomas Vondra <[email protected]>
2020-03-19 02:02 [PATCH 7/7] fix Tomas Vondra <[email protected]>
2020-06-15 10:28 [PATCH 2/3] fix Your Name <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-08-01 02:24 [PATCH 2/2] fix Justin Pryzby <[email protected]>
2020-12-12 17:42 [PATCH v34 2/8] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-01-10 21:41 [PATCH] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2021-03-13 21:51 [PATCH 2/3] fix Justin Pryzby <[email protected]>
2023-03-01 17:48 Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
2023-03-01 18:09 ` Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
2023-03-01 19:29 ` Re: Memory leak from ExecutorState context? Tomas Vondra <[email protected]>
2023-03-01 23:18   ` Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[email protected]>
2023-03-02 00:30     ` Re: Memory leak from ExecutorState context? Tomas Vondra <[email protected]>
2023-03-02 12:08       ` Re: Memory leak from ExecutorState context? Jehan-Guillaume de Rorthais <[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