Skip to content

Commit

Permalink
Fixed CORE-4505: Use of named cursor fails if statement was not execu…
Browse files Browse the repository at this point in the history
…ted. Should also fix CORE-4489, but I cannot check.
  • Loading branch information
AlexPeshkoff committed Jul 31, 2014
1 parent a7afd21 commit 900fb82
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 82 deletions.
2 changes: 1 addition & 1 deletion examples/interfaces/04.print_table.cpp
Expand Up @@ -93,7 +93,7 @@ int main()
"or RDB$VIEW_SOURCE is not null";

// Do not use IStatement - just ask attachment to open cursor
curs = att->openCursor(st, tra, 0, sql, 3, NULL, NULL, NULL);
curs = att->openCursor(st, tra, 0, sql, 3, NULL, NULL, NULL, NULL);
check(st, "openCursor");

meta = curs->getMetadata(st);
Expand Down
2 changes: 1 addition & 1 deletion src/auth/SecureRemotePassword/manage/SrpManagement.cpp
Expand Up @@ -150,7 +150,7 @@ class SrpManagement FB_FINAL : public Firebird::StdPlugin<IManagement, FB_AUTH_M
Message out;
Field<Varying> grantor(out, MAX_SQL_IDENTIFIER_SIZE);
Firebird::IResultSet* curs = att->openCursor(&s, tra, selGrantor.length(),
selGrantor.c_str(), SQL_DIALECT_V6, NULL, NULL, out.getMetadata());
selGrantor.c_str(), SQL_DIALECT_V6, NULL, NULL, out.getMetadata(), NULL);
check(&s);

bool hasGrant = curs->fetchNext(&s, out.getBuffer());
Expand Down
7 changes: 5 additions & 2 deletions src/dsql/dsql.cpp
Expand Up @@ -426,7 +426,7 @@ void DsqlDmlRequest::setCursor(thread_db* tdbb, const TEXT* name)
const size_t MAX_CURSOR_LENGTH = 132 - 1;
string cursor = name;

if (cursor.hasData() && cursor[0] == '\"')
if (cursor[0] == '\"')
{
// Quoted cursor names eh? Strip'em.
// Note that "" will be replaced with ".
Expand Down Expand Up @@ -477,13 +477,16 @@ void DsqlDmlRequest::setCursor(thread_db* tdbb, const TEXT* name)
// If there already is a cursor and its name isn't the same, ditto.
// We already know there is no cursor by this name in the hash table

if (req_cursor.isEmpty())
if (req_cursor.isEmpty() || !(req_flags & dsql_req::FLAG_OPENED_CURSOR))
{
if (req_cursor.hasData())
req_dbb->dbb_cursors.remove(req_cursor);
req_cursor = cursor;
req_dbb->dbb_cursors.put(cursor, this);
}
else
{
fb_assert(!symbol);
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-502) <<
Arg::Gds(isc_dsql_decl_err) <<
Arg::Gds(isc_dsql_cursor_redefined) << req_cursor);
Expand Down
9 changes: 5 additions & 4 deletions src/include/firebird/Provider.h
Expand Up @@ -141,15 +141,14 @@ class IResultSet : public IRefCounted
virtual FB_BOOLEAN FB_CARG isEof(IStatus* status) = 0;
virtual FB_BOOLEAN FB_CARG isBof(IStatus* status) = 0;
virtual IMessageMetadata* FB_CARG getMetadata(IStatus* status) = 0;
virtual void FB_CARG setCursorName(IStatus* status, const char* name) = 0;
virtual void FB_CARG close(IStatus* status) = 0;

// This item is for ISC API emulation only
// It may be gone in future versions
// Please do not use it!
virtual void FB_CARG setDelayedOutputFormat(IStatus* status, IMessageMetadata* format) = 0;
};
#define FB_RESULTSET_VERSION (FB_REFCOUNTED_VERSION + 12)
#define FB_RESULTSET_VERSION (FB_REFCOUNTED_VERSION + 11)

class IStatement : public IRefCounted
{
Expand Down Expand Up @@ -186,10 +185,11 @@ class IStatement : public IRefCounted
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, void* outBuffer) = 0;
virtual IResultSet* FB_CARG openCursor(IStatus* status, ITransaction* transaction,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata) = 0;
virtual void FB_CARG setCursorName(IStatus* status, const char* name) = 0;
virtual void FB_CARG free(IStatus* status) = 0;
virtual unsigned FB_CARG getFlags(IStatus* status) = 0;
};
#define FB_STATEMENT_VERSION (FB_REFCOUNTED_VERSION + 10)
#define FB_STATEMENT_VERSION (FB_REFCOUNTED_VERSION + 11)

class IRequest : public IRefCounted
{
Expand Down Expand Up @@ -253,7 +253,8 @@ class IAttachment : public IRefCounted
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, void* outBuffer) = 0;
virtual IResultSet* FB_CARG openCursor(IStatus* status, ITransaction* transaction,
unsigned int stmtLength, const char* sqlStmt, unsigned dialect,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata) = 0;
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata,
const char* cursorName) = 0;
virtual IEvents* FB_CARG queEvents(IStatus* status, IEventCallback* callback,
unsigned int length, const unsigned char* events) = 0;
virtual void FB_CARG cancelOperation(IStatus* status, int option) = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/jrd/EngineInterface.h
Expand Up @@ -146,7 +146,6 @@ class JResultSet FB_FINAL : public Firebird::RefCntIface<Firebird::IResultSet, F
virtual FB_BOOLEAN FB_CARG isEof(Firebird::IStatus* status);
virtual FB_BOOLEAN FB_CARG isBof(Firebird::IStatus* status);
virtual Firebird::IMessageMetadata* FB_CARG getMetadata(Firebird::IStatus* status);
virtual void FB_CARG setCursorName(Firebird::IStatus* status, const char* name);
virtual void FB_CARG close(Firebird::IStatus* status);
virtual void FB_CARG setDelayedOutputFormat(Firebird::IStatus* status, Firebird::IMessageMetadata* format);

Expand Down Expand Up @@ -190,6 +189,7 @@ class JStatement FB_FINAL : public Firebird::RefCntIface<Firebird::IStatement, F
virtual JResultSet* FB_CARG openCursor(Firebird::IStatus* status,
Firebird::ITransaction* transaction, Firebird::IMessageMetadata* inMetadata, void* inBuffer,
Firebird::IMessageMetadata* outMetadata);
virtual void FB_CARG setCursorName(Firebird::IStatus* status, const char* name);
virtual unsigned FB_CARG getFlags(Firebird::IStatus* status);

public:
Expand Down Expand Up @@ -331,7 +331,7 @@ class JAttachment FB_FINAL : public Firebird::RefCntIface<Firebird::IAttachment,
virtual Firebird::IResultSet* FB_CARG openCursor(Firebird::IStatus* status,
Firebird::ITransaction* transaction, unsigned int stmtLength, const char* sqlStmt,
unsigned int dialect, Firebird::IMessageMetadata* inMetadata, void* inBuffer,
Firebird::IMessageMetadata* outMetadata);
Firebird::IMessageMetadata* outMetadata, const char* cursorName);
virtual JEvents* FB_CARG queEvents(Firebird::IStatus* status, Firebird::IEventCallback* callback,
unsigned int length, const unsigned char* events);
virtual void FB_CARG cancelOperation(Firebird::IStatus* status, int option);
Expand Down
4 changes: 2 additions & 2 deletions src/jrd/Mapping.cpp
Expand Up @@ -278,7 +278,7 @@ class Cache : public MapHash, public GlobalStorage
"SELECT RDB$MAP_USING, RDB$MAP_PLUGIN, RDB$MAP_DB, RDB$MAP_FROM_TYPE, "
" RDB$MAP_FROM, RDB$MAP_TO_TYPE, RDB$MAP_TO "
"FROM RDB$AUTH_MAPPING",
3, NULL, NULL, mMap.getMetadata());
3, NULL, NULL, mMap.getMetadata(), NULL);
if (!st.isSuccess())
{
if (fb_utils::containsErrorCode(st.get(), isc_dsql_relation_err))
Expand Down Expand Up @@ -1190,7 +1190,7 @@ RecordBuffer* MappingList::getList(thread_db* tdbb, jrd_rel* relation)
"SELECT RDB$MAP_NAME, RDB$MAP_USING, RDB$MAP_PLUGIN, RDB$MAP_DB, "
" RDB$MAP_FROM_TYPE, RDB$MAP_FROM, RDB$MAP_TO_TYPE, RDB$MAP_TO "
"FROM RDB$AUTH_MAPPING",
3, NULL, NULL, mMap.getMetadata());
3, NULL, NULL, mMap.getMetadata(), NULL);
if (!st.isSuccess())
{
if (!fb_utils::containsErrorCode(st.get(), isc_dsql_relation_err))
Expand Down
19 changes: 14 additions & 5 deletions src/jrd/jrd.cpp
Expand Up @@ -4474,7 +4474,8 @@ JResultSet* FB_CARG JStatement::openCursor(IStatus* user_status, ITransaction* t

IResultSet* JAttachment::openCursor(IStatus* user_status, ITransaction* apiTra,
unsigned int length, const char* string, unsigned int dialect,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata)
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata,
const char* cursorName)
{
IStatement* tmpStatement = prepare(user_status, apiTra, length, string, dialect,
(outMetadata ? 0 : IStatement::PREPARE_PREFETCH_OUTPUT_PARAMETERS));
Expand All @@ -4483,6 +4484,16 @@ IResultSet* JAttachment::openCursor(IStatus* user_status, ITransaction* apiTra,
return NULL;
}

if (cursorName)
{
tmpStatement->setCursorName(user_status, cursorName);
if (!user_status->isSuccess())
{
tmpStatement->release();
return NULL;
}
}

IResultSet* rs = tmpStatement->openCursor(user_status, apiTra,
inMetadata, inBuffer, outMetadata);

Expand Down Expand Up @@ -5035,7 +5046,7 @@ ISC_UINT64 JStatement::getAffectedRecords(IStatus* userStatus)
}


void JResultSet::setCursorName(IStatus* user_status, const char* cursor)
void JStatement::setCursorName(IStatus* user_status, const char* cursor)
{
try
{
Expand All @@ -5044,9 +5055,7 @@ void JResultSet::setCursorName(IStatus* user_status, const char* cursor)

try
{
dsql_req* req = getStatement()->getHandle();
fb_assert(req);
req->setCursor(tdbb, cursor);
getHandle()->setCursor(tdbb, cursor);
}
catch (const Exception& ex)
{
Expand Down
30 changes: 18 additions & 12 deletions src/remote/client/interface.cpp
Expand Up @@ -253,7 +253,6 @@ class ResultSet FB_FINAL : public Firebird::RefCntIface<Firebird::IResultSet, FB
virtual FB_BOOLEAN FB_CARG isEof(IStatus* status);
virtual FB_BOOLEAN FB_CARG isBof(IStatus* status);
virtual IMessageMetadata* FB_CARG getMetadata(IStatus* status);
virtual void FB_CARG setCursorName(IStatus* status, const char* name);
virtual void FB_CARG close(IStatus* status);
virtual void FB_CARG setDelayedOutputFormat(IStatus* status, IMessageMetadata* format);

Expand Down Expand Up @@ -308,6 +307,7 @@ class Statement FB_FINAL : public Firebird::RefCntIface<Firebird::IStatement, FB
IMessageMetadata* outMetadata, void* outBuffer);
virtual ResultSet* FB_CARG openCursor(IStatus* status, ITransaction* tra,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outFormat);
virtual void FB_CARG setCursorName(IStatus* status, const char* name);
virtual void FB_CARG free(IStatus* status);
virtual unsigned FB_CARG getFlags(IStatus* status);

Expand Down Expand Up @@ -475,7 +475,8 @@ class Attachment FB_FINAL : public Firebird::RefCntIface<Firebird::IAttachment,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, void* outBuffer);
virtual Firebird::IResultSet* FB_CARG openCursor(IStatus* status, ITransaction* transaction,
unsigned int stmtLength, const char* sqlStmt, unsigned dialect,
IMessageMetadata* inMetadata, void* inBuffer, Firebird::IMessageMetadata* outMetadata);
IMessageMetadata* inMetadata, void* inBuffer, Firebird::IMessageMetadata* outMetadata,
const char* cursorName);
virtual Firebird::IEvents* FB_CARG queEvents(IStatus* status, Firebird::IEventCallback* callback,
unsigned int length, const unsigned char* events);
virtual void FB_CARG cancelOperation(IStatus* status, int option);
Expand Down Expand Up @@ -1986,7 +1987,8 @@ ResultSet* Statement::openCursor(IStatus* status, Firebird::ITransaction* apiTra

IResultSet* FB_CARG Attachment::openCursor(IStatus* status, ITransaction* transaction,
unsigned int stmtLength, const char* sqlStmt, unsigned dialect,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata)
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata,
const char* cursorName)
{
Statement* stmt = prepare(status, transaction, stmtLength, sqlStmt, dialect,
(outMetadata ? 0 : IStatement::PREPARE_PREFETCH_OUTPUT_PARAMETERS));
Expand All @@ -2002,6 +2004,17 @@ IResultSet* FB_CARG Attachment::openCursor(IStatus* status, ITransaction* transa
return NULL;
}

if (cursorName)
{
stmt->setCursorName(status, cursorName);
if (!status->isSuccess())
{
rc->release();
stmt->release();
return NULL;
}
}

rc->tmpStatement = true;
return rc;
}
Expand Down Expand Up @@ -3070,7 +3083,7 @@ FB_BOOLEAN ResultSet::fetchRelative(IStatus* user_status, int offset, void* buff
}


void ResultSet::setCursorName(IStatus* status, const char* cursor)
void Statement::setCursorName(IStatus* status, const char* cursor)
{
/*****************************************
*
Expand Down Expand Up @@ -3101,16 +3114,9 @@ void ResultSet::setCursorName(IStatus* status, const char* cursor)

// Check and validate handles, etc.

if (!stmt)
{
(Arg::Gds(isc_dsql_cursor_err) << Arg::Gds(isc_bad_req_handle)).raise();
}
Rsr* statement = stmt->getStatement();
Rsr* statement = getStatement();
CHECK_HANDLE(statement, isc_bad_req_handle);

Rdb* rdb = statement->rsr_rdb;
CHECK_HANDLE(rdb, isc_bad_db_handle);

rem_port* port = rdb->rdb_port;
RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION);

Expand Down
37 changes: 16 additions & 21 deletions src/remote/server/server.cpp
Expand Up @@ -2898,7 +2898,6 @@ ISC_STATUS rem_port::end_statement(P_SQLFREE* free_stmt, PACKET* sendL)
return this->send_response(sendL, 0, 0, &status_vector, true);
}
statement->rsr_cursor = NULL;
statement->rsr_cursor_name = "";
fb_assert(statement->rsr_rtr);
FB_SIZE_T pos;
if (!statement->rsr_rtr->rtr_cursors.find(statement, pos))
Expand Down Expand Up @@ -3230,14 +3229,6 @@ ISC_STATUS rem_port::execute_statement(P_OP op, P_SQLDATA* sqldata, PACKET* send
{
transaction->rtr_cursors.add(statement);
statement->rsr_delayed_format = !out_blr_length;

if (statement->rsr_cursor_name.hasData())
{
statement->rsr_cursor->setCursorName(&status_vector, statement->rsr_cursor_name.c_str());

if (status_vector.isSuccess())
statement->rsr_cursor_name = "";
}
}
}
else
Expand Down Expand Up @@ -4051,6 +4042,13 @@ ISC_STATUS rem_port::prepare_statement(P_SQLST * prepareL, PACKET* sendL)
if (!status_vector.isSuccess())
return this->send_response(sendL, 0, 0, &status_vector, false);

if (statement->rsr_cursor_name.hasData())
{
statement->rsr_iface->setCursorName(&status_vector, statement->rsr_cursor_name.c_str());
if (!status_vector.isSuccess())
return this->send_response(sendL, 0, 0, &status_vector, false);
}

LocalStatus s2;
statement->rsr_iface->getInfo(&s2, infoLength, info, prepareL->p_sqlst_buffer_length, buffer);
if (!s2.isSuccess())
Expand Down Expand Up @@ -4999,7 +4997,6 @@ static void release_transaction( Rtr* transaction)
Rsr* const statement = transaction->rtr_cursors.pop();
fb_assert(statement->rsr_cursor);
statement->rsr_cursor = NULL;
statement->rsr_cursor_name = "";
}

for (Rtr** p = &rdb->rdb_transactions; *p; p = &(*p)->rtr_next)
Expand Down Expand Up @@ -5405,19 +5402,17 @@ ISC_STATUS rem_port::set_cursor(P_SQLCUR * sqlcur, PACKET* sendL)

getHandle(statement, sqlcur->p_sqlcur_statement);


if (statement->rsr_cursor)
statement->rsr_cursor->setCursorName(&status_vector, name);
else
if (port_protocol < PROTOCOL_VERSION13 && statement->rsr_cursor_name.hasData() &&
statement->rsr_cursor_name != name)
{
if (statement->rsr_cursor_name.hasData() && statement->rsr_cursor_name != name)
{
status_vector.set((Arg::Gds(isc_dsql_decl_err) <<
Arg::Gds(isc_dsql_cursor_redefined) << statement->rsr_cursor_name).value());
}
else
statement->rsr_cursor_name = name;
status_vector.set((Arg::Gds(isc_dsql_decl_err) <<
Arg::Gds(isc_dsql_cursor_redefined) << statement->rsr_cursor_name).value());
}
else
statement->rsr_cursor_name = name;

if (statement->rsr_iface)
statement->rsr_iface->setCursorName(&status_vector, name);

return this->send_response(sendL, 0, 0, &status_vector, false);
}
Expand Down
5 changes: 3 additions & 2 deletions src/yvalve/YObjects.h
Expand Up @@ -310,7 +310,6 @@ class YResultSet FB_FINAL : public YHelper<YResultSet, Firebird::IResultSet, FB_
virtual FB_BOOLEAN FB_CARG isEof(Firebird::IStatus* status);
virtual FB_BOOLEAN FB_CARG isBof(Firebird::IStatus* status);
virtual Firebird::IMessageMetadata* FB_CARG getMetadata(Firebird::IStatus* status);
virtual void FB_CARG setCursorName(Firebird::IStatus* status, const char* name);
virtual void FB_CARG close(Firebird::IStatus* status);
virtual void FB_CARG setDelayedOutputFormat(Firebird::IStatus* status, Firebird::IMessageMetadata* format);

Expand Down Expand Up @@ -358,6 +357,7 @@ class YStatement FB_FINAL : public YHelper<YStatement, Firebird::IStatement, FB_
Firebird::IMessageMetadata* outMetadata, void* outBuffer);
virtual Firebird::IResultSet* FB_CARG openCursor(Firebird::IStatus* status, Firebird::ITransaction* transaction,
Firebird::IMessageMetadata* inMetadata, void* inBuffer, Firebird::IMessageMetadata* outMetadata);
virtual void FB_CARG setCursorName(Firebird::IStatus* status, const char* name);
virtual void FB_CARG free(Firebird::IStatus* status);
virtual unsigned FB_CARG getFlags(Firebird::IStatus* status);

Expand Down Expand Up @@ -433,7 +433,8 @@ class YAttachment FB_FINAL : public YHelper<YAttachment, Firebird::IAttachment,
Firebird::IMessageMetadata* outMetadata, void* outBuffer);
virtual Firebird::IResultSet* FB_CARG openCursor(Firebird::IStatus* status, Firebird::ITransaction* transaction,
unsigned int stmtLength, const char* sqlStmt, unsigned int dialect,
Firebird::IMessageMetadata* inMetadata, void* inBuffer, Firebird::IMessageMetadata* outMetadata);
Firebird::IMessageMetadata* inMetadata, void* inBuffer, Firebird::IMessageMetadata* outMetadata,
const char* cursorName);
virtual YEvents* FB_CARG queEvents(Firebird::IStatus* status, Firebird::IEventCallback* callback,
unsigned int length, const unsigned char* eventsData);
virtual void FB_CARG cancelOperation(Firebird::IStatus* status, int option);
Expand Down

0 comments on commit 900fb82

Please sign in to comment.