aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeModifyTable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeModifyTable.c')
-rw-r--r--src/backend/executor/nodeModifyTable.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 309e27f8b5f..333cbf78343 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -212,33 +212,53 @@ ExecCheckPlanOutput(Relation resultRel, List *targetList)
attr = TupleDescAttr(resultDesc, attno);
attno++;
- if (!attr->attisdropped)
+ /*
+ * Special cases here should match planner's expand_insert_targetlist.
+ */
+ if (attr->attisdropped)
{
- /* Normal case: demand type match */
- if (exprType((Node *) tle->expr) != attr->atttypid)
+ /*
+ * For a dropped column, we can't check atttypid (it's likely 0).
+ * In any case the planner has most likely inserted an INT4 null.
+ * What we insist on is just *some* NULL constant.
+ */
+ if (!IsA(tle->expr, Const) ||
+ !((Const *) tle->expr)->constisnull)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("table row type and query-specified row type do not match"),
- errdetail("Table has type %s at ordinal position %d, but query expects %s.",
- format_type_be(attr->atttypid),
- attno,
- format_type_be(exprType((Node *) tle->expr)))));
+ errdetail("Query provides a value for a dropped column at ordinal position %d.",
+ attno)));
}
- else
+ else if (attr->attgenerated)
{
/*
- * For a dropped column, we can't check atttypid (it's likely 0).
- * In any case the planner has most likely inserted an INT4 null.
- * What we insist on is just *some* NULL constant.
+ * For a generated column, the planner will have inserted a null
+ * of the column's base type (to avoid possibly failing on domain
+ * not-null constraints). It doesn't seem worth insisting on that
+ * exact type though, since a null value is type-independent. As
+ * above, just insist on *some* NULL constant.
*/
if (!IsA(tle->expr, Const) ||
!((Const *) tle->expr)->constisnull)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("table row type and query-specified row type do not match"),
- errdetail("Query provides a value for a dropped column at ordinal position %d.",
+ errdetail("Query provides a value for a generated column at ordinal position %d.",
attno)));
}
+ else
+ {
+ /* Normal case: demand type match */
+ if (exprType((Node *) tle->expr) != attr->atttypid)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("table row type and query-specified row type do not match"),
+ errdetail("Table has type %s at ordinal position %d, but query expects %s.",
+ format_type_be(attr->atttypid),
+ attno,
+ format_type_be(exprType((Node *) tle->expr)))));
+ }
}
if (attno != resultDesc->natts)
ereport(ERROR,