mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 06:43:03 +01:00
Fixed CORE-4670: Constraint violation error may be swallowed in some cases.
This commit is contained in:
parent
09af5b862d
commit
fbb4edcfd7
124
src/jrd/fun.epp
124
src/jrd/fun.epp
@ -301,8 +301,6 @@ enum UdfError
|
||||
};
|
||||
|
||||
|
||||
static void handleUdfException(const Exception& ex);
|
||||
static void reRaiseExceptionFromUdf(thread_db* tdbb);
|
||||
static SSHORT blob_get_segment(blb*, UCHAR*, USHORT, USHORT*);
|
||||
static void blob_put_segment(blb*, const UCHAR*, USHORT);
|
||||
static SLONG blob_lseek(blb*, USHORT, SLONG);
|
||||
@ -943,50 +941,6 @@ UserFunction* FUN_resolve(thread_db* tdbb, CompilerScratch* csb, UserFunction* f
|
||||
}
|
||||
|
||||
|
||||
static void handleUdfException(const Exception& ex)
|
||||
{
|
||||
/****************************************
|
||||
*
|
||||
* h a n d l e U d f E x c e p t i o n
|
||||
*
|
||||
****************************************
|
||||
*
|
||||
* Functional description
|
||||
* When exception happens in UDF we have
|
||||
* no better choice then store it in
|
||||
* tdbb_status_vector and raise again
|
||||
* on return from UDF.
|
||||
*
|
||||
****************************************/
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
fb_utils::init_status(tdbb->tdbb_status_vector);
|
||||
ex.stuff_exception(tdbb->tdbb_status_vector);
|
||||
}
|
||||
|
||||
|
||||
static void reRaiseExceptionFromUdf(thread_db* tdbb)
|
||||
{
|
||||
/*************************************************
|
||||
*
|
||||
* r e R a i s e E x c e p t i o n F r o m U d f
|
||||
*
|
||||
*************************************************
|
||||
*
|
||||
* Functional description
|
||||
* When exception happens in UDF we have
|
||||
* no better choice then store it in
|
||||
* tdbb_status_vector and raise again
|
||||
* on return from UDF.
|
||||
*
|
||||
*************************************************/
|
||||
ISC_STATUS* st = tdbb->tdbb_status_vector;
|
||||
if (st[0] == 1 && st[1] != 0)
|
||||
{
|
||||
ERR_punt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static SLONG blob_lseek(blb* blob, USHORT mode, SLONG offset)
|
||||
{
|
||||
/**************************************
|
||||
@ -1000,18 +954,25 @@ static SLONG blob_lseek(blb* blob, USHORT mode, SLONG offset)
|
||||
*
|
||||
**************************************/
|
||||
// As this is a call-back from a UDF, must put it under try/catch and reacquire the engine mutex
|
||||
|
||||
try
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
Database::SyncGuard dsGuard(tdbb->getDatabase());
|
||||
|
||||
return BLB_lseek(blob, mode, offset);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
handleUdfException(ex);
|
||||
return -1;
|
||||
try
|
||||
{
|
||||
Database::SyncGuard dsGuard(tdbb->getDatabase());
|
||||
return BLB_lseek(blob, mode, offset);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuff_exception(tdbb->tdbb_status_vector);
|
||||
}
|
||||
}
|
||||
catch (const Exception&)
|
||||
{} // no-op
|
||||
|
||||
return -1; // error
|
||||
}
|
||||
|
||||
|
||||
@ -1028,17 +989,23 @@ static void blob_put_segment(blb* blob, const UCHAR* buffer, USHORT length)
|
||||
*
|
||||
**************************************/
|
||||
// As this is a call-back from a UDF, must put it under try/catch and reacquire the engine mutex
|
||||
|
||||
try
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
Database::SyncGuard dsGuard(tdbb->getDatabase());
|
||||
|
||||
BLB_put_segment(tdbb, blob, buffer, length);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
handleUdfException(ex);
|
||||
try
|
||||
{
|
||||
Database::SyncGuard dsGuard(tdbb->getDatabase());
|
||||
BLB_put_segment(tdbb, blob, buffer, length);
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuff_exception(tdbb->tdbb_status_vector);
|
||||
}
|
||||
}
|
||||
catch (const Exception&)
|
||||
{} // no-op
|
||||
}
|
||||
|
||||
|
||||
@ -1059,26 +1026,34 @@ static SSHORT blob_get_segment(blb* blob, UCHAR* buffer, USHORT length, USHORT*
|
||||
*
|
||||
**************************************/
|
||||
// As this is a call-back from a UDF, must put it under try/catch and reacquire the engine mutex
|
||||
|
||||
try
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
Database::SyncGuard dsGuard(tdbb->getDatabase());
|
||||
|
||||
*return_length = BLB_get_segment(tdbb, blob, buffer, length);
|
||||
try
|
||||
{
|
||||
Database::SyncGuard dsGuard(tdbb->getDatabase());
|
||||
|
||||
if (blob->blb_flags & BLB_eof)
|
||||
return 0;
|
||||
*return_length = BLB_get_segment(tdbb, blob, buffer, length);
|
||||
|
||||
if (blob->blb_fragment_size)
|
||||
return -1;
|
||||
if (blob->blb_flags & BLB_eof)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
if (blob->blb_fragment_size)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
ex.stuff_exception(tdbb->tdbb_status_vector);
|
||||
}
|
||||
}
|
||||
catch (const Exception& ex)
|
||||
{
|
||||
handleUdfException(ex);
|
||||
return 0;
|
||||
}
|
||||
{} // no-op
|
||||
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
|
||||
@ -1188,8 +1163,7 @@ static void invoke(thread_db* tdbb,
|
||||
SET_TDBB(tdbb);
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
|
||||
// Get ready to accept exceptions from API called from UDF
|
||||
fb_utils::init_status(tdbb->tdbb_status_vector);
|
||||
ThreadStatusGuard tempStatus(tdbb);
|
||||
|
||||
START_CHECK_FOR_EXCEPTIONS(function->fun_exception_message.c_str());
|
||||
if (function->fun_return_arg)
|
||||
@ -1361,7 +1335,11 @@ static void invoke(thread_db* tdbb,
|
||||
}
|
||||
END_CHECK_FOR_EXCEPTIONS(function->fun_exception_message.c_str());
|
||||
|
||||
reRaiseExceptionFromUdf(tdbb);
|
||||
// When exception happens inside UDF we have no better choice than storing it in
|
||||
// tdbb_status_vector and raising again on return from UDF
|
||||
|
||||
if (tempStatus[0] == isc_arg_gds && tempStatus[1] != FB_SUCCESS)
|
||||
ERR_post(Arg::StatusVector(tempStatus));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user