Ah, it looks like we can get away with initializing the RRI to 0, and
then explicitly handle that case in ExecPartitionCheckEmitError, as in
the attached (which means reindenting, but I left it alone to make it
easy to read).  It kinda sucks because we don't report the tuple that
causes the error, but

a) it's a very unlikely case anyway
b) it's better than the bogus error message
c) it's better than some hypothetical crash
d) nobody uses partitioned default partitions anyway
e) nobody uses differing column order anyway

-- 
Álvaro Herrera                https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
>From 7289a0706d95aa621b9d6f626a836ac381fd4f61 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvhe...@alvh.no-ip.org>
Date: Mon, 7 Sep 2020 19:26:37 -0300
Subject: [PATCH] Avoid invalid RRI

---
 src/backend/executor/execMain.c      | 7 +++++++
 src/backend/executor/execPartition.c | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 4fdffad6f3..a0c3e56a03 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1840,6 +1840,12 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo,
 	 * back to the root table's rowtype so that val_desc in the error message
 	 * matches the input tuple.
 	 */
+	if (resultRelInfo->ri_RangeTableIndex == 0)
+	{
+		val_desc = NULL;
+	}
+	else
+	{
 	if (resultRelInfo->ri_PartitionRoot)
 	{
 		TupleDesc	old_tupdesc;
@@ -1874,6 +1880,7 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo,
 											 tupdesc,
 											 modifiedCols,
 											 64);
+	}
 	ereport(ERROR,
 			(errcode(ERRCODE_CHECK_VIOLATION),
 			 errmsg("new row for relation \"%s\" violates partition constraint",
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 0ca1d34dfa..c1ef34d771 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -1111,7 +1111,7 @@ ExecInitPartitionDispatchInfo(EState *estate,
 	{
 		ResultRelInfo *rri = makeNode(ResultRelInfo);
 
-		InitResultRelInfo(rri, rel, 1, proute->partition_root, 0);
+		InitResultRelInfo(rri, rel, 0, proute->partition_root, 0);
 		proute->nonleaf_partitions[dispatchidx] = rri;
 	}
 	else
-- 
2.20.1

Reply via email to