@ -1849,16 +1849,12 @@ ExecRelCheck(ResultRelInfo *resultRelInfo,
* ExecPartitionCheck - - - check that tuple meets the partition constraint .
* ExecPartitionCheck - - - check that tuple meets the partition constraint .
*
*
* Exported in executor . h for outside use .
* Exported in executor . h for outside use .
* Returns true if it meets the partition constraint , else returns false .
*/
*/
void
bool
ExecPartitionCheck ( ResultRelInfo * resultRelInfo , TupleTableSlot * slot ,
ExecPartitionCheck ( ResultRelInfo * resultRelInfo , TupleTableSlot * slot ,
EState * estate )
EState * estate )
{
{
Relation rel = resultRelInfo - > ri_RelationDesc ;
TupleDesc tupdesc = RelationGetDescr ( rel ) ;
Bitmapset * modifiedCols ;
Bitmapset * insertedCols ;
Bitmapset * updatedCols ;
ExprContext * econtext ;
ExprContext * econtext ;
/*
/*
@ -1886,52 +1882,69 @@ ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
* As in case of the catalogued constraints , we treat a NULL result as
* As in case of the catalogued constraints , we treat a NULL result as
* success here , not a failure .
* success here , not a failure .
*/
*/
if ( ! ExecCheck ( resultRelInfo - > ri_PartitionCheckExpr , econtext ) )
return ExecCheck ( resultRelInfo - > ri_PartitionCheckExpr , econtext ) ;
{
}
char * val_desc ;
Relation orig_rel = rel ;
/*
* ExecPartitionCheckEmitError - Form and emit an error message after a failed
* partition constraint check .
*/
void
ExecPartitionCheckEmitError ( ResultRelInfo * resultRelInfo ,
TupleTableSlot * slot ,
EState * estate )
{
Relation rel = resultRelInfo - > ri_RelationDesc ;
Relation orig_rel = rel ;
TupleDesc tupdesc = RelationGetDescr ( rel ) ;
char * val_desc ;
Bitmapset * modifiedCols ;
Bitmapset * insertedCols ;
Bitmapset * updatedCols ;
/* See the comment above. */
/*
if ( resultRelInfo - > ri_PartitionRoot )
* Need to first convert the tuple to the root partitioned table ' s row
* type . For details , check similar comments in ExecConstraints ( ) .
*/
if ( resultRelInfo - > ri_PartitionRoot )
{
HeapTuple tuple = ExecFetchSlotTuple ( slot ) ;
TupleDesc old_tupdesc = RelationGetDescr ( rel ) ;
TupleConversionMap * map ;
rel = resultRelInfo - > ri_PartitionRoot ;
tupdesc = RelationGetDescr ( rel ) ;
/* a reverse map */
map = convert_tuples_by_name ( old_tupdesc , tupdesc ,
gettext_noop ( " could not convert row type " ) ) ;
if ( map ! = NULL )
{
{
HeapTuple tuple = ExecFetchSlotTuple ( slot ) ;
tuple = do_convert_tuple ( tuple , map ) ;
TupleDesc old_tupdesc = RelationGetDescr ( rel ) ;
ExecSetSlotDescriptor ( slot , tupdesc ) ;
TupleConversionMap * map ;
ExecStoreTuple ( tuple , slot , InvalidBuffer , false ) ;
rel = resultRelInfo - > ri_PartitionRoot ;
tupdesc = RelationGetDescr ( rel ) ;
/* a reverse map */
map = convert_tuples_by_name ( old_tupdesc , tupdesc ,
gettext_noop ( " could not convert row type " ) ) ;
if ( map ! = NULL )
{
tuple = do_convert_tuple ( tuple , map ) ;
ExecSetSlotDescriptor ( slot , tupdesc ) ;
ExecStoreTuple ( tuple , slot , InvalidBuffer , false ) ;
}
}
}
insertedCols = GetInsertedColumns ( resultRelInfo , estate ) ;
updatedCols = GetUpdatedColumns ( resultRelInfo , estate ) ;
modifiedCols = bms_union ( insertedCols , updatedCols ) ;
val_desc = ExecBuildSlotValueDescription ( RelationGetRelid ( rel ) ,
slot ,
tupdesc ,
modifiedCols ,
64 ) ;
ereport ( ERROR ,
( errcode ( ERRCODE_CHECK_VIOLATION ) ,
errmsg ( " new row for relation \" %s \" violates partition constraint " ,
RelationGetRelationName ( orig_rel ) ) ,
val_desc ? errdetail ( " Failing row contains %s. " , val_desc ) : 0 ) ) ;
}
}
insertedCols = GetInsertedColumns ( resultRelInfo , estate ) ;
updatedCols = GetUpdatedColumns ( resultRelInfo , estate ) ;
modifiedCols = bms_union ( insertedCols , updatedCols ) ;
val_desc = ExecBuildSlotValueDescription ( RelationGetRelid ( rel ) ,
slot ,
tupdesc ,
modifiedCols ,
64 ) ;
ereport ( ERROR ,
( errcode ( ERRCODE_CHECK_VIOLATION ) ,
errmsg ( " new row for relation \" %s \" violates partition constraint " ,
RelationGetRelationName ( orig_rel ) ) ,
val_desc ? errdetail ( " Failing row contains %s. " , val_desc ) : 0 ) ) ;
}
}
/*
/*
* ExecConstraints - check constraints of the tuple in ' slot '
* ExecConstraints - check constraints of the tuple in ' slot '
*
*
* This checks the traditional NOT NULL and check constraints , as well as
* This checks the traditional NOT NULL and check constraints , and if
* the partition constraint , if any .
* requested , checks the partition constraint .
*
*
* Note : ' slot ' contains the tuple to check the constraints of , which may
* Note : ' slot ' contains the tuple to check the constraints of , which may
* have been converted from the original input tuple after tuple routing .
* have been converted from the original input tuple after tuple routing .
@ -1939,7 +1952,8 @@ ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
*/
*/
void
void
ExecConstraints ( ResultRelInfo * resultRelInfo ,
ExecConstraints ( ResultRelInfo * resultRelInfo ,
TupleTableSlot * slot , EState * estate )
TupleTableSlot * slot , EState * estate ,
bool check_partition_constraint )
{
{
Relation rel = resultRelInfo - > ri_RelationDesc ;
Relation rel = resultRelInfo - > ri_RelationDesc ;
TupleDesc tupdesc = RelationGetDescr ( rel ) ;
TupleDesc tupdesc = RelationGetDescr ( rel ) ;
@ -2055,8 +2069,9 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
}
}
}
}
if ( resultRelInfo - > ri_PartitionCheck )
if ( check_partition_constraint & & resultRelInfo - > ri_PartitionCheck & &
ExecPartitionCheck ( resultRelInfo , slot , estate ) ;
! ExecPartitionCheck ( resultRelInfo , slot , estate ) )
ExecPartitionCheckEmitError ( resultRelInfo , slot , estate ) ;
}
}