@ -828,6 +828,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)
resultRelation ,
resultRelationIndex ,
true ,
NULL ,
estate - > es_instrument ) ;
resultRelInfo + + ;
}
@ -1218,6 +1219,7 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
Relation resultRelationDesc ,
Index resultRelationIndex ,
bool load_partition_check ,
Relation partition_root ,
int instrument_options )
{
MemSet ( resultRelInfo , 0 , sizeof ( ResultRelInfo ) ) ;
@ -1259,6 +1261,11 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
resultRelInfo - > ri_PartitionCheck =
RelationGetPartitionQual ( resultRelationDesc ,
true ) ;
/*
* The following gets set to NULL unless we are initializing leaf
* partitions for tuple - routing .
*/
resultRelInfo - > ri_PartitionRoot = partition_root ;
}
/*
@ -1322,6 +1329,7 @@ ExecGetTriggerResultRel(EState *estate, Oid relid)
rel ,
0 , /* dummy rangetable index */
true ,
NULL ,
estate - > es_instrument ) ;
estate - > es_trig_target_relations =
lappend ( estate - > es_trig_target_relations , rInfo ) ;
@ -1743,9 +1751,21 @@ ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
return ExecQual ( resultRelInfo - > ri_PartitionCheckExpr , econtext , true ) ;
}
/*
* ExecConstraints - check constraints of the tuple in ' slot '
*
* This checks the traditional NOT NULL and check constraints , as well as
* the partition constraint , if any .
*
* Note : ' slot ' contains the tuple to check the constraints of , which may
* have been converted from the original input tuple after tuple routing ,
* while ' orig_slot ' contains the original tuple to be shown in the message ,
* if an error occurs .
*/
void
ExecConstraints ( ResultRelInfo * resultRelInfo ,
TupleTableSlot * slot , EState * estate )
TupleTableSlot * slot , TupleTableSlot * orig_slot ,
EState * estate )
{
Relation rel = resultRelInfo - > ri_RelationDesc ;
TupleDesc tupdesc = RelationGetDescr ( rel ) ;
@ -1767,12 +1787,24 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
slot_attisnull ( slot , attrChk ) )
{
char * val_desc ;
Relation orig_rel = rel ;
TupleDesc orig_tupdesc = tupdesc ;
/*
* choose the correct relation to build val_desc from the
* tuple contained in orig_slot
*/
if ( resultRelInfo - > ri_PartitionRoot )
{
rel = resultRelInfo - > ri_PartitionRoot ;
tupdesc = RelationGetDescr ( rel ) ;
}
insertedCols = GetInsertedColumns ( resultRelInfo , estate ) ;
updatedCols = GetUpdatedColumns ( resultRelInfo , estate ) ;
modifiedCols = bms_union ( insertedCols , updatedCols ) ;
val_desc = ExecBuildSlotValueDescription ( RelationGetRelid ( rel ) ,
slot ,
orig_ slot,
tupdesc ,
modifiedCols ,
64 ) ;
@ -1780,9 +1812,9 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
ereport ( ERROR ,
( errcode ( ERRCODE_NOT_NULL_VIOLATION ) ,
errmsg ( " null value in column \" %s \" violates not-null constraint " ,
NameStr ( tupdesc - > attrs [ attrChk - 1 ] - > attname ) ) ,
NameStr ( orig_ tupdesc- > attrs [ attrChk - 1 ] - > attname ) ) ,
val_desc ? errdetail ( " Failing row contains %s. " , val_desc ) : 0 ,
errtablecol ( rel , attrChk ) ) ) ;
errtablecol ( orig_ rel, attrChk ) ) ) ;
}
}
}
@ -1794,21 +1826,29 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
if ( ( failed = ExecRelCheck ( resultRelInfo , slot , estate ) ) ! = NULL )
{
char * val_desc ;
Relation orig_rel = rel ;
/* See the comment above. */
if ( resultRelInfo - > ri_PartitionRoot )
{
rel = resultRelInfo - > ri_PartitionRoot ;
tupdesc = RelationGetDescr ( rel ) ;
}
insertedCols = GetInsertedColumns ( resultRelInfo , estate ) ;
updatedCols = GetUpdatedColumns ( resultRelInfo , estate ) ;
modifiedCols = bms_union ( insertedCols , updatedCols ) ;
val_desc = ExecBuildSlotValueDescription ( RelationGetRelid ( rel ) ,
slot ,
orig_ slot,
tupdesc ,
modifiedCols ,
64 ) ;
ereport ( ERROR ,
( errcode ( ERRCODE_CHECK_VIOLATION ) ,
errmsg ( " new row for relation \" %s \" violates check constraint \" %s \" " ,
RelationGetRelationName ( rel ) , failed ) ,
RelationGetRelationName ( orig_ rel) , failed ) ,
val_desc ? errdetail ( " Failing row contains %s. " , val_desc ) : 0 ,
errtableconstraint ( rel , failed ) ) ) ;
errtableconstraint ( orig_ rel, failed ) ) ) ;
}
}
@ -1816,19 +1856,27 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
! ExecPartitionCheck ( resultRelInfo , slot , estate ) )
{
char * val_desc ;
Relation orig_rel = rel ;
/* See the comment above. */
if ( resultRelInfo - > ri_PartitionRoot )
{
rel = resultRelInfo - > ri_PartitionRoot ;
tupdesc = RelationGetDescr ( rel ) ;
}
insertedCols = GetInsertedColumns ( resultRelInfo , estate ) ;
updatedCols = GetUpdatedColumns ( resultRelInfo , estate ) ;
modifiedCols = bms_union ( insertedCols , updatedCols ) ;
val_desc = ExecBuildSlotValueDescription ( RelationGetRelid ( rel ) ,
slot ,
orig_ slot,
tupdesc ,
modifiedCols ,
64 ) ;
ereport ( ERROR ,
( errcode ( ERRCODE_CHECK_VIOLATION ) ,
errmsg ( " new row for relation \" %s \" violates partition constraint " ,
RelationGetRelationName ( rel ) ) ,
RelationGetRelationName ( orig_ rel) ) ,
val_desc ? errdetail ( " Failing row contains %s. " , val_desc ) : 0 ) ) ;
}
}
@ -3086,6 +3134,7 @@ ExecSetupPartitionTupleRouting(Relation rel,
partrel ,
1 , /* dummy */
false ,
rel ,
0 ) ;
/*