]> granicus.if.org Git - postgresql/commitdiff
Rewrite ExecPartitionCheckEmitError for clarity
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 28 Dec 2018 17:47:05 +0000 (14:47 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 28 Dec 2018 17:47:05 +0000 (14:47 -0300)
The original was hard to follow and failed to comply with DRY principle.

Discussion: https://postgr.es/m/20181206222221.g5witbsklvqthjll@alvherre.pgsql

src/backend/executor/execMain.c

index d83d296d82c283a1c3a92dbb76afb864ea607b01..5974e8f57778d3ea8303de46bbb586a6237d9ff4 100644 (file)
@@ -1837,25 +1837,26 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo,
                                                        TupleTableSlot *slot,
                                                        EState *estate)
 {
-       Relation        rel = resultRelInfo->ri_RelationDesc;
-       Relation        orig_rel = rel;
-       TupleDesc       tupdesc = RelationGetDescr(rel);
+       Oid                     root_relid;
+       TupleDesc       tupdesc;
        char       *val_desc;
        Bitmapset  *modifiedCols;
-       Bitmapset  *insertedCols;
-       Bitmapset  *updatedCols;
 
        /*
-        * Need to first convert the tuple to the root partitioned table's row
-        * type. For details, check similar comments in ExecConstraints().
+        * If the tuple has been routed, it's been converted to the partition's
+        * rowtype, which might differ from the root table's.  We must convert it
+        * back to the root table's rowtype so that val_desc in the error message
+        * matches the input tuple.
         */
        if (resultRelInfo->ri_PartitionRoot)
        {
-               TupleDesc       old_tupdesc = RelationGetDescr(rel);
+               TupleDesc       old_tupdesc;
                AttrNumber *map;
 
-               rel = resultRelInfo->ri_PartitionRoot;
-               tupdesc = RelationGetDescr(rel);
+               root_relid = RelationGetRelid(resultRelInfo->ri_PartitionRoot);
+               tupdesc = RelationGetDescr(resultRelInfo->ri_PartitionRoot);
+
+               old_tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
                /* a reverse map */
                map = convert_tuples_by_name_map_if_req(old_tupdesc, tupdesc,
                                                                                                gettext_noop("could not convert row type"));
@@ -1868,11 +1869,16 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo,
                        slot = execute_attr_map_slot(map, slot,
                                                                                 MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
        }
+       else
+       {
+               root_relid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
+               tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
+       }
+
+       modifiedCols = bms_add_members(GetInsertedColumns(resultRelInfo, estate),
+                                                                  GetUpdatedColumns(resultRelInfo, estate));
 
-       insertedCols = GetInsertedColumns(resultRelInfo, estate);
-       updatedCols = GetUpdatedColumns(resultRelInfo, estate);
-       modifiedCols = bms_union(insertedCols, updatedCols);
-       val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel),
+       val_desc = ExecBuildSlotValueDescription(root_relid,
                                                                                         slot,
                                                                                         tupdesc,
                                                                                         modifiedCols,
@@ -1880,7 +1886,7 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo,
        ereport(ERROR,
                        (errcode(ERRCODE_CHECK_VIOLATION),
                         errmsg("new row for relation \"%s\" violates partition constraint",
-                                       RelationGetRelationName(orig_rel)),
+                                       RelationGetRelationName(resultRelInfo->ri_RelationDesc)),
                         val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
 }