8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:40:38 +01:00

A bit better solution for CORE-6110: 64-bit transaction IDs are not stored properly in status vector

This commit is contained in:
hvlad 2020-02-12 13:08:40 +02:00
parent 9a7a0a3750
commit 641eca3aa0
5 changed files with 40 additions and 48 deletions

View File

@ -333,6 +333,18 @@ PrivateDyn::PrivateDyn(ISC_STATUS codeWithoutFacility) throw() :
Num::Num(ISC_STATUS s) throw() :
Base(isc_arg_number, s) { }
Int64::Int64(SINT64 val) throw() :
Str(text)
{
sprintf(text, "%" SQUADFORMAT, val);
}
Int64::Int64(FB_UINT64 val) throw() :
Str(text)
{
sprintf(text, "%" UQUADFORMAT, val);
}
Quad::Quad(const ISC_QUAD* quad) throw() :
Str(text)
{

View File

@ -248,6 +248,17 @@ public:
explicit Num(ISC_STATUS s) throw();
};
// On 32-bit architecture ISC_STATUS can't fit 64-bit integer therefore
// convert such a numbers into text and put string into status-vector
class Int64 : public Str
{
public:
explicit Int64(SINT64 val) throw();
explicit Int64(FB_UINT64 val) throw();
private:
char text[24];
};
class Quad : public Str
{
public:

View File

@ -12427,13 +12427,11 @@ void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratc
// msg 297: Concurrent ALTER DATABASE is not supported
Arg::PrivateDyn status(297);
string trans_num_str;
if (conflict_trans)
{
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
trans_num_str.printf("%" UQUADFORMAT, conflict_trans);
status << Arg::Gds(isc_concurrent_transaction) << Arg::Str(trans_num_str);
status << Arg::Gds(isc_concurrent_transaction) << Arg::Int64(conflict_trans);
}
status_exception::raise(status);

View File

@ -1164,11 +1164,8 @@ jrd_tra* TRA_reconnect(thread_db* tdbb, const UCHAR* id, USHORT length)
gds__msg_lookup(NULL, JRD_BUGCHK, message, sizeof(text), text, &flags);
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, number);
ERR_post(Arg::Gds(isc_no_recon) <<
Arg::Gds(isc_tra_state) << Arg::Str(trans_num_str) << Arg::Str(text));
Arg::Gds(isc_tra_state) << Arg::Int64(number) << Arg::Str(text));
}
MemoryPool* const pool = attachment->createPool();

View File

@ -874,12 +874,9 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
tdbb->bumpRelStats(RuntimeStatistics::RECORD_CONFLICTS, relation->rel_id);
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, rpb->rpb_transaction_nr);
ERR_post(Arg::Gds(isc_deadlock) <<
Arg::Gds(isc_read_conflict) <<
Arg::Gds(isc_concurrent_transaction) << Arg::Str(trans_num_str));
Arg::Gds(isc_concurrent_transaction) << Arg::Int64(rpb->rpb_transaction_nr));
}
// refetch the record and try again. The active transaction
@ -1004,9 +1001,7 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
CCH_RELEASE(tdbb, &rpb->getWindow(tdbb));
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, rpb->rpb_transaction_nr);
ERR_post(Arg::Gds(isc_rec_in_limbo) << Arg::Str(trans_num_str));
ERR_post(Arg::Gds(isc_rec_in_limbo) << Arg::Int64(rpb->rpb_transaction_nr));
}
case tra_active:
@ -1862,12 +1857,9 @@ void VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
if (prepare_update(tdbb, transaction, tid_fetch, rpb, &temp, 0, stack, false))
{
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, rpb->rpb_transaction_nr);
ERR_post(Arg::Gds(isc_deadlock) <<
Arg::Gds(isc_update_conflict) <<
Arg::Gds(isc_concurrent_transaction) << Arg::Str(trans_num_str));
Arg::Gds(isc_concurrent_transaction) << Arg::Int64(rpb->rpb_transaction_nr));
}
// Old record was restored and re-fetched for write. Now replace it.
@ -2617,9 +2609,7 @@ bool VIO_get_current(thread_db* tdbb,
if (!(transaction->tra_flags & TRA_ignore_limbo))
{
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, rpb->rpb_transaction_nr);
ERR_post(Arg::Gds(isc_rec_in_limbo) << Arg::Str(trans_num_str));
ERR_post(Arg::Gds(isc_rec_in_limbo) << Arg::Int64(rpb->rpb_transaction_nr));
}
// fall thru
@ -3160,12 +3150,9 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
stack, false))
{
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, org_rpb->rpb_transaction_nr);
ERR_post(Arg::Gds(isc_deadlock) <<
Arg::Gds(isc_update_conflict) <<
Arg::Gds(isc_concurrent_transaction) << Arg::Str(trans_num_str));
Arg::Gds(isc_concurrent_transaction) << Arg::Int64(org_rpb->rpb_transaction_nr));
}
IDX_modify_flag_uk_modified(tdbb, org_rpb, new_rpb, transaction);
@ -3401,12 +3388,9 @@ bool VIO_refetch_record(thread_db* tdbb, record_param* rpb, jrd_tra* transaction
tdbb->bumpRelStats(RuntimeStatistics::RECORD_CONFLICTS, rpb->rpb_relation->rel_id);
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, rpb->rpb_transaction_nr);
ERR_post(Arg::Gds(isc_deadlock) <<
Arg::Gds(isc_update_conflict) <<
Arg::Gds(isc_concurrent_transaction) << Arg::Str(trans_num_str));
Arg::Gds(isc_concurrent_transaction) << Arg::Int64(rpb->rpb_transaction_nr));
}
return true;
@ -4021,19 +4005,14 @@ bool VIO_writelock(thread_db* tdbb, record_param* org_rpb, jrd_tra* transaction)
org_rpb->rpb_runtime_flags |= RPB_refetch;
return false;
case PREPARE_LOCKERR:
{
// We got some kind of locking error (deadlock, timeout or lock_conflict)
// Error details should be stuffed into status vector at this point
// hvlad: we have no details as TRA_wait has already cleared the status vector
// We got some kind of locking error (deadlock, timeout or lock_conflict)
// Error details should be stuffed into status vector at this point
// hvlad: we have no details as TRA_wait has already cleared the status vector
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, org_rpb->rpb_transaction_nr);
ERR_post(Arg::Gds(isc_deadlock) <<
Arg::Gds(isc_update_conflict) <<
Arg::Gds(isc_concurrent_transaction) << Arg::Str(trans_num_str));
}
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
ERR_post(Arg::Gds(isc_deadlock) <<
Arg::Gds(isc_update_conflict) <<
Arg::Gds(isc_concurrent_transaction) << Arg::Int64(org_rpb->rpb_transaction_nr));
}
// Old record was restored and re-fetched for write. Now replace it.
@ -5728,20 +5707,15 @@ static int prepare_update( thread_db* tdbb,
tdbb->bumpRelStats(RuntimeStatistics::RECORD_CONFLICTS, relation->rel_id);
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, update_conflict_trans);
ERR_post(Arg::Gds(isc_update_conflict) <<
Arg::Gds(isc_concurrent_transaction) << Arg::Str(trans_num_str));
Arg::Gds(isc_concurrent_transaction) << Arg::Int64(update_conflict_trans));
}
case tra_limbo:
if (!(transaction->tra_flags & TRA_ignore_limbo))
{
// Cannot use Arg::Num here because transaction number is 64-bit unsigned integer
string trans_num_str;
trans_num_str.printf("%" UQUADFORMAT, rpb->rpb_transaction_nr);
ERR_post(Arg::Gds(isc_rec_in_limbo) << Arg::Str(trans_num_str));
ERR_post(Arg::Gds(isc_rec_in_limbo) << Arg::Int64(rpb->rpb_transaction_nr));
}
// fall thru