8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 04:43:03 +01:00

Fixed reported issues with ROW_COUNT.

This commit is contained in:
dimitr 2005-06-24 12:56:34 +00:00
parent 0ce1d52f3e
commit e3578f5912
5 changed files with 89 additions and 15 deletions

View File

@ -2002,7 +2002,6 @@ jrd_req* CMP_make_request(thread_db* tdbb, CompilerScratch* csb)
request->req_external = csb->csb_external;
request->req_variables = csb->csb_variables;
request->req_resources = csb->csb_resources; // Assign array contents
request->req_records_affected = 0;
if (csb->csb_g_flags & csb_blr_version4) {
request->req_flags |= req_blr_version4;
}

View File

@ -5220,10 +5220,12 @@ static dsc* internal_info(thread_db* tdbb, const dsc* value, impure_value* impur
tdbb->tdbb_request->req_last_xcp.as_sqlcode();
break;
case internal_rows_affected:
impure->vlu_misc.vlu_long = tdbb->tdbb_request->req_records_affected;
impure->vlu_misc.vlu_long =
tdbb->tdbb_request->req_records_affected.getCount();
break;
case internal_trigger_action:
impure->vlu_misc.vlu_long = tdbb->tdbb_request->req_trigger_action;
impure->vlu_misc.vlu_long =
tdbb->tdbb_request->req_trigger_action;
break;
default:
BUGCHECK(232); /* msg 232 EVL_expr: invalid operation */

View File

@ -108,6 +108,49 @@
using namespace Jrd;
// AffectedRows class implementation
AffectedRows::AffectedRows()
{
clear();
}
void AffectedRows::clear()
{
writeFlag = false;
fetchedRows = modifiedRows = 0;
}
void AffectedRows::bumpFetched()
{
fetchedRows++;
}
void AffectedRows::bumpModified(bool increment)
{
if (increment) {
modifiedRows++;
}
else {
writeFlag = true;
}
}
bool AffectedRows::isReadOnly() const
{
return !writeFlag;
}
bool AffectedRows::hasCursor() const
{
return (fetchedRows > 0);
}
int AffectedRows::getCount() const
{
return writeFlag ? modifiedRows : fetchedRows;
}
// StatusXcp class implementation
StatusXcp::StatusXcp()
@ -1176,6 +1219,7 @@ static jrd_nod* erase(thread_db* tdbb, jrd_nod* node, SSHORT which_trig)
switch (request->req_operation) {
case jrd_req::req_evaluate:
{
request->req_records_affected.bumpModified(false);
if (!node->nod_arg[e_erase_statement])
break;
const Format* format = MET_current(tdbb, rpb->rpb_relation);
@ -1294,12 +1338,12 @@ static jrd_nod* erase(thread_db* tdbb, jrd_nod* node, SSHORT which_trig)
if (relation == request->req_top_view_erase) {
if (which_trig == ALL_TRIGS || which_trig == POST_TRIG) {
request->req_records_deleted++;
request->req_records_affected++;
request->req_records_affected.bumpModified(true);
}
}
else if (relation->rel_file || !relation->rel_view_rse) {
request->req_records_deleted++;
request->req_records_affected++;
request->req_records_affected.bumpModified(true);
}
if (transaction != dbb->dbb_sys_trans) {
@ -1850,6 +1894,8 @@ static jrd_nod* looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
jrd_nod* node = in_node;
request->req_records_affected.clear();
// Catch errors so we can unwind cleanly
bool error_pending = false;
@ -1964,7 +2010,7 @@ static jrd_nod* looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
case nod_for:
switch (request->req_operation) {
case jrd_req::req_evaluate:
request->req_records_affected = 0;
request->req_records_affected.clear();
RSE_open(tdbb, (RecordSource*) node->nod_arg[e_for_rsb]);
case jrd_req::req_return:
if (node->nod_arg[e_for_stall]) {
@ -2043,14 +2089,14 @@ static jrd_nod* looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
if (!(impure->irsb_flags & irsb_open)) {
ERR_post(isc_cursor_not_open, 0);
}
request->req_records_affected.clear();
// perform preliminary navigation, if specified
if (node->nod_arg[e_cursor_stmt_seek]) {
node = node->nod_arg[e_cursor_stmt_seek];
break;
}
request->req_records_affected = 0;
case jrd_req::req_return:
if (!request->req_records_affected) {
if (!request->req_records_affected.hasCursor()) {
// fetch one record
if (RSE_get_record(tdbb, rsb,
#ifdef SCROLLABLE_CURSORS
@ -2951,6 +2997,7 @@ static jrd_nod* modify(thread_db* tdbb, jrd_nod* node, SSHORT which_trig)
switch (request->req_operation) {
case jrd_req::req_evaluate:
request->req_records_affected.bumpModified(false);
break;
case jrd_req::req_return:
@ -3075,12 +3122,12 @@ static jrd_nod* modify(thread_db* tdbb, jrd_nod* node, SSHORT which_trig)
if (relation == request->req_top_view_modify) {
if (which_trig == ALL_TRIGS || which_trig == POST_TRIG) {
request->req_records_updated++;
request->req_records_affected++;
request->req_records_affected.bumpModified(true);
}
}
else if (relation->rel_file || !relation->rel_view_rse) {
request->req_records_updated++;
request->req_records_affected++;
request->req_records_affected.bumpModified(true);
}
if (which_trig != PRE_TRIG) {
@ -3895,6 +3942,12 @@ static jrd_nod* store(thread_db* tdbb, jrd_nod* node, SSHORT which_trig)
switch (request->req_operation) {
case jrd_req::req_evaluate:
if (request->req_records_affected.isReadOnly() &&
!request->req_records_affected.hasCursor())
{
request->req_records_affected.clear();
}
request->req_records_affected.bumpModified(false);
impure->sta_state = 0;
RLCK_reserve_relation(tdbb, transaction, relation, true, true);
break;
@ -3967,12 +4020,12 @@ static jrd_nod* store(thread_db* tdbb, jrd_nod* node, SSHORT which_trig)
if (relation == request->req_top_view_store) {
if (which_trig == ALL_TRIGS || which_trig == POST_TRIG) {
request->req_records_inserted++;
request->req_records_affected++;
request->req_records_affected.bumpModified(true);
}
}
else if (relation->rel_file || !relation->rel_view_rse) {
request->req_records_inserted++;
request->req_records_affected++;
request->req_records_affected.bumpModified(true);
}
if (transaction != dbb->dbb_sys_trans) {

View File

@ -146,6 +146,26 @@ class SaveRecordParam : public pool_alloc<type_srpb>
typedef Firebird::BePlusTree<ULONG, ULONG, MemoryPool> TempBlobIdTree;
/* Affected rows counter class */
class AffectedRows {
public:
AffectedRows();
void clear();
void bumpFetched();
void bumpModified(bool);
bool isReadOnly() const;
bool hasCursor() const;
int getCount() const;
private:
bool writeFlag;
int fetchedRows;
int modifiedRows;
};
/* request block */
class jrd_req : public pool_alloc_rpt<record_param, type_req>
@ -195,7 +215,7 @@ public:
ULONG req_records_updated; /* count of records updated by request */
ULONG req_records_deleted; /* count of records deleted by request */
ULONG req_records_affected; /* count of records affected by the last statement */
AffectedRows req_records_affected; /* records affected by the last statement */
USHORT req_view_flags; /* special flags for virtual ops on views */
jrd_rel* req_top_view_store; /* the top view in store(), if any */

View File

@ -20,7 +20,7 @@
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* $Id: rse.cpp,v 1.88 2005-06-12 06:27:12 dimitr Exp $
* $Id: rse.cpp,v 1.89 2005-06-24 12:56:34 dimitr Exp $
*
* 2001.07.28: John Bellardo: Implemented rse_skip and made rse_first work with
* seekable streams.
@ -483,7 +483,7 @@ bool RSE_get_record(thread_db* tdbb, RecordSource* rsb, RSE_GET_MODE mode)
if (count) {
request->req_records_selected++;
request->req_records_affected++;
request->req_records_affected.bumpFetched();
}
break;
}