* ExecPartitionCheckEmitError - Form and emit an error message after a failed * partition constraint check. */
| 3010 | * partition constraint check. |
| 3011 | */ |
| 3012 | void |
| 3013 | ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, |
| 3014 | TupleTableSlot *slot, |
| 3015 | EState *estate) |
| 3016 | { |
| 3017 | Oid root_relid; |
| 3018 | TupleDesc tupdesc; |
| 3019 | char *val_desc; |
| 3020 | Bitmapset *modifiedCols; |
| 3021 | |
| 3022 | /* |
| 3023 | * If the tuple has been routed, it's been converted to the partition's |
| 3024 | * rowtype, which might differ from the root table's. We must convert it |
| 3025 | * back to the root table's rowtype so that val_desc in the error message |
| 3026 | * matches the input tuple. |
| 3027 | */ |
| 3028 | if (resultRelInfo->ri_RootResultRelInfo) |
| 3029 | { |
| 3030 | ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo; |
| 3031 | TupleDesc old_tupdesc; |
| 3032 | AttrMap *map; |
| 3033 | |
| 3034 | root_relid = RelationGetRelid(rootrel->ri_RelationDesc); |
| 3035 | tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); |
| 3036 | |
| 3037 | old_tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); |
| 3038 | /* a reverse map */ |
| 3039 | map = build_attrmap_by_name_if_req(old_tupdesc, tupdesc); |
| 3040 | |
| 3041 | /* |
| 3042 | * Partition-specific slot's tupdesc can't be changed, so allocate a |
| 3043 | * new one. |
| 3044 | */ |
| 3045 | if (map != NULL) |
| 3046 | slot = execute_attr_map_slot(map, slot, |
| 3047 | MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); |
| 3048 | modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate), |
| 3049 | ExecGetUpdatedCols(rootrel, estate)); |
| 3050 | } |
| 3051 | else |
| 3052 | { |
| 3053 | root_relid = RelationGetRelid(resultRelInfo->ri_RelationDesc); |
| 3054 | tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); |
| 3055 | modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate), |
| 3056 | ExecGetUpdatedCols(resultRelInfo, estate)); |
| 3057 | } |
| 3058 | |
| 3059 | val_desc = ExecBuildSlotValueDescription(root_relid, |
| 3060 | slot, |
| 3061 | tupdesc, |
| 3062 | modifiedCols, |
| 3063 | 64); |
| 3064 | ereport(ERROR, |
| 3065 | (errcode(ERRCODE_CHECK_VIOLATION), |
| 3066 | errmsg("new row for relation \"%s\" violates partition constraint", |
| 3067 | RelationGetRelationName(resultRelInfo->ri_RelationDesc)), |
| 3068 | val_desc ? errdetail("Failing row contains %s.", val_desc) : 0, |
| 3069 | errtable(resultRelInfo->ri_RelationDesc))); |
no test coverage detected