From e3578f59129a28e9ed9a3dae22f9388ff9d8f159 Mon Sep 17 00:00:00 2001 From: dimitr Date: Fri, 24 Jun 2005 12:56:34 +0000 Subject: [PATCH] Fixed reported issues with ROW_COUNT. --- src/jrd/cmp.cpp | 1 - src/jrd/evl.cpp | 6 +++-- src/jrd/exe.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++------- src/jrd/req.h | 22 ++++++++++++++- src/jrd/rse.cpp | 4 +-- 5 files changed, 89 insertions(+), 15 deletions(-) diff --git a/src/jrd/cmp.cpp b/src/jrd/cmp.cpp index 788e1b8c51..37d6be8df5 100644 --- a/src/jrd/cmp.cpp +++ b/src/jrd/cmp.cpp @@ -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; } diff --git a/src/jrd/evl.cpp b/src/jrd/evl.cpp index 21825c0728..7ec44e0c61 100644 --- a/src/jrd/evl.cpp +++ b/src/jrd/evl.cpp @@ -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 */ diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index a06e989f28..d5b4376e01 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -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) { diff --git a/src/jrd/req.h b/src/jrd/req.h index ad66079e12..edf4a4e58e 100644 --- a/src/jrd/req.h +++ b/src/jrd/req.h @@ -146,6 +146,26 @@ class SaveRecordParam : public pool_alloc typedef Firebird::BePlusTree 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 @@ -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 */ diff --git a/src/jrd/rse.cpp b/src/jrd/rse.cpp index 735f911494..a562367188 100644 --- a/src/jrd/rse.cpp +++ b/src/jrd/rse.cpp @@ -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; }