diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
new file mode 100644
index 17d9765..f9a8bff
*** a/src/backend/access/nbtree/nbtinsert.c
--- b/src/backend/access/nbtree/nbtinsert.c
***************
*** 21,26 ****
--- 21,27 ----
  #include "miscadmin.h"
  #include "storage/lmgr.h"
  #include "storage/predicate.h"
+ #include "utils/acl.h"
  #include "utils/inval.h"
  #include "utils/tqual.h"
  
*************** _bt_check_unique(Relation rel, IndexTupl
*** 387,400 ****
  
  						index_deform_tuple(itup, RelationGetDescr(rel),
  										   values, isnull);
! 						ereport(ERROR,
! 								(errcode(ERRCODE_UNIQUE_VIOLATION),
! 								 errmsg("duplicate key value violates unique constraint \"%s\"",
! 										RelationGetRelationName(rel)),
! 								 errdetail("Key %s already exists.",
! 										   BuildIndexValueDescription(rel,
! 															values, isnull)),
! 								 errtableconstraint(heapRel,
  											 RelationGetRelationName(rel))));
  					}
  				}
--- 388,420 ----
  
  						index_deform_tuple(itup, RelationGetDescr(rel),
  										   values, isnull);
! 						/*
! 						 * When reporting a failure, it can be handy to have
! 						 * the key which failed reported.  Unfortunately, when
! 						 * using column-level privileges, this could expose
! 						 * a column the user does not have rights for.  Instead,
! 						 * only report the key if the user has full table-level
! 						 * SELECT rights on the relation.
! 						 */
! 						if (pg_class_aclcheck(RelationGetRelid(rel),
! 											  GetUserId(), ACL_SELECT) ==
! 								ACLCHECK_OK)
! 							ereport(ERROR,
! 									(errcode(ERRCODE_UNIQUE_VIOLATION),
! 									 errmsg("duplicate key value violates unique constraint \"%s\"",
! 											RelationGetRelationName(rel)),
! 									 errdetail("Key %s already exists.",
! 											   BuildIndexValueDescription(rel,
! 																values,
! 																isnull)),
! 									 errtableconstraint(heapRel,
! 											 RelationGetRelationName(rel))));
! 						else
! 							ereport(ERROR,
! 									(errcode(ERRCODE_UNIQUE_VIOLATION),
! 									 errmsg("duplicate key value violates unique constraint \"%s\"",
! 											RelationGetRelationName(rel)),
! 									 errtableconstraint(heapRel,
  											 RelationGetRelationName(rel))));
  					}
  				}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
new file mode 100644
index 85d1c63..fe98599
*** a/src/backend/executor/execMain.c
--- b/src/backend/executor/execMain.c
*************** ExecConstraints(ResultRelInfo *resultRel
*** 1600,1614 ****
  		{
  			if (tupdesc->attrs[attrChk - 1]->attnotnull &&
  				slot_attisnull(slot, attrChk))
! 				ereport(ERROR,
! 						(errcode(ERRCODE_NOT_NULL_VIOLATION),
! 						 errmsg("null value in column \"%s\" violates not-null constraint",
! 							  NameStr(tupdesc->attrs[attrChk - 1]->attname)),
! 						 errdetail("Failing row contains %s.",
! 								   ExecBuildSlotValueDescription(slot,
! 																 tupdesc,
! 																 64)),
! 						 errtablecol(rel, attrChk)));
  		}
  	}
  
--- 1600,1631 ----
  		{
  			if (tupdesc->attrs[attrChk - 1]->attnotnull &&
  				slot_attisnull(slot, attrChk))
! 			{
! 				/*
! 				 * When reporting failure, it's handy to have the whole row
! 				 * which failed returned, but we can only show it if the user
! 				 * has full SELECT rights on the relation, otherwise we might
! 				 * end up showing fields the user does not have access to, due
! 				 * to column-level privileges.
! 				 */
! 				if (pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
! 									  ACL_SELECT) == ACLCHECK_OK)
! 					ereport(ERROR,
! 							(errcode(ERRCODE_NOT_NULL_VIOLATION),
! 						 	errmsg("null value in column \"%s\" violates not-null constraint",
! 								  NameStr(tupdesc->attrs[attrChk - 1]->attname)),
! 						 	errdetail("Failing row contains %s.",
! 									   ExecBuildSlotValueDescription(slot,
! 																	 tupdesc,
! 																	 64)),
! 						 	errtablecol(rel, attrChk)));
! 				else
! 					ereport(ERROR,
! 							(errcode(ERRCODE_NOT_NULL_VIOLATION),
! 						 	errmsg("null value in column \"%s\" violates not-null constraint",
! 								  NameStr(tupdesc->attrs[attrChk - 1]->attname)),
! 						 	errtablecol(rel, attrChk)));
! 			}
  		}
  	}
  
*************** ExecConstraints(ResultRelInfo *resultRel
*** 1617,1631 ****
  		const char *failed;
  
  		if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_CHECK_VIOLATION),
! 					 errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
! 							RelationGetRelationName(rel), failed),
! 					 errdetail("Failing row contains %s.",
! 							   ExecBuildSlotValueDescription(slot,
! 															 tupdesc,
! 															 64)),
! 					 errtableconstraint(rel, failed)));
  	}
  }
  
--- 1634,1659 ----
  		const char *failed;
  
  		if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
! 		{
! 			/* Check table-level SELECT rights on the relation, see above */
! 			if (pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
! 								  ACL_SELECT) == ACLCHECK_OK)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_CHECK_VIOLATION),
! 						 errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
! 								RelationGetRelationName(rel), failed),
! 						 errdetail("Failing row contains %s.",
! 								   ExecBuildSlotValueDescription(slot,
! 																 tupdesc,
! 																 64)),
! 						 errtableconstraint(rel, failed)));
! 			else
! 				ereport(ERROR,
! 						(errcode(ERRCODE_CHECK_VIOLATION),
! 						 errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
! 								RelationGetRelationName(rel), failed),
! 						 errtableconstraint(rel, failed)));
! 		}
  	}
  }
  
