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

Core (engine-level) support for scrollable DSQL cursors. Fixed the IResultSet API to match the JDBC spec. Renamed FB_EOF to FB_NO_DATA. Refactored some DSQL internals.

This commit is contained in:
dimitr 2015-01-27 10:29:30 +00:00
parent dcc5dfbba9
commit cc8cc680a3
25 changed files with 651 additions and 289 deletions

View File

@ -161,7 +161,7 @@ private:
Message out;
Field<Varying> grantor(out, MAX_SQL_IDENTIFIER_SIZE);
Firebird::IResultSet* curs = att->openCursor(&statusWrapper, tra, selGrantor.length(),
selGrantor.c_str(), SQL_DIALECT_V6, NULL, NULL, out.getMetadata(), NULL);
selGrantor.c_str(), SQL_DIALECT_V6, NULL, NULL, out.getMetadata(), NULL, 0);
check(&statusWrapper);
bool hasGrant = curs->fetchNext(&statusWrapper, out.getBuffer()) == Firebird::IStatus::FB_OK;
@ -563,7 +563,7 @@ public:
}
rs = stmt->openCursor(status, tra, (par ? par->getMetadata() : NULL),
(par ? par->getBuffer() : NULL), om);
(par ? par->getBuffer() : NULL), om, 0);
check(status);
while (rs->fetchNext(status, di.getBuffer()) == Firebird::IStatus::FB_OK)
@ -853,7 +853,7 @@ private:
{
int cc = blob->getSegment(&statusWrapper, sizeof(segbuf), segbuf, &len);
check(&statusWrapper);
if (cc == Firebird::IStatus::FB_EOF)
if (cc == Firebird::IStatus::FB_NO_DATA)
break;
s.append(segbuf, len);
}

270
src/dsql/DsqlCursor.cpp Normal file
View File

@ -0,0 +1,270 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Dmitry Yemanov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2015 Dmitry Yemanov <dimitrf@firebirdsql.org>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include "../jrd/tra_proto.h"
#include "../jrd/trace/TraceManager.h"
#include "../jrd/trace/TraceDSQLHelpers.h"
#include "../dsql/DsqlCursor.h"
using namespace Firebird;
using namespace Jrd;
const char* const SCRATCH = "fb_cursor_";
const ULONG PREFETCH_SIZE = 65536; // 64 KB
DsqlCursor::DsqlCursor(dsql_req* req, ULONG flags)
: m_request(req), m_flags(flags),
m_space(req->getPool(), SCRATCH),
m_state(BOS), m_eof(false), m_position(0), m_cachedCount(0),
m_messageSize(req->getStatement()->getReceiveMsg()->msg_length)
{
TRA_link_cursor(m_request->req_transaction, this);
}
jrd_tra* DsqlCursor::getTransaction() const
{
return m_request->req_transaction;
}
Attachment* DsqlCursor::getAttachment() const
{
return m_request->req_dbb->dbb_attachment;
}
void DsqlCursor::close(thread_db* tdbb, DsqlCursor* cursor)
{
if (!cursor)
return;
Jrd::Attachment* const attachment = cursor->getAttachment();
dsql_req* const request = cursor->m_request;
if (request->req_request)
{
ThreadStatusGuard status_vector(tdbb);
try
{
// Report some remaining fetches if any
if (request->req_fetch_baseline)
{
TraceDSQLFetch trace(attachment, request);
trace.fetch(true, ITracePlugin::TRACE_RESULT_SUCCESS);
}
if (request->req_traced && TraceManager::need_dsql_free(attachment))
{
TraceSQLStatementImpl stmt(request, NULL);
TraceManager::event_dsql_free(attachment, &stmt, DSQL_close);
}
JRD_unwind_request(tdbb, request->req_request);
}
catch (Firebird::Exception&)
{} // no-op
}
request->req_cursor = NULL;
TRA_unlink_cursor(request->req_transaction, cursor);
delete cursor;
}
int DsqlCursor::fetchNext(thread_db* tdbb, UCHAR* buffer)
{
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
{
m_eof = !m_request->fetch(tdbb, buffer);
if (m_eof)
{
m_state = EOS;
return 1;
}
m_state = POSITIONED;
return 0;
}
if (m_state == EOS)
return 1;
const FB_UINT64 position = (m_state == BOS) ? 0 : m_position + 1;
return fetchFromCache(tdbb, buffer, position);
}
int DsqlCursor::fetchPrior(thread_db* tdbb, UCHAR* buffer)
{
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("PRIOR")).raise();
if (m_state == BOS)
return -1;
if (!m_position)
{
m_state = BOS;
return -1;
}
const FB_UINT64 position = ((m_state == EOS) ? m_cachedCount : m_position) - 1;
return fetchFromCache(tdbb, buffer, position);
}
int DsqlCursor::fetchFirst(thread_db* tdbb, UCHAR* buffer)
{
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("FIRST")).raise();
return fetchAbsolute(tdbb, buffer, 1);
}
int DsqlCursor::fetchLast(thread_db* tdbb, UCHAR* buffer)
{
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("LAST")).raise();
return fetchAbsolute(tdbb, buffer, -1);
}
int DsqlCursor::fetchAbsolute(thread_db* tdbb, UCHAR* buffer, SLONG position)
{
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("ABSOLUTE")).raise();
if (!position)
{
m_state = BOS;
return -1;
}
SINT64 offset = -1;
if (position < 0)
{
if (!m_eof)
{
cacheInput(tdbb);
fb_assert(m_eof);
}
offset = m_cachedCount;
}
return fetchFromCache(tdbb, buffer, position + offset);
}
int DsqlCursor::fetchRelative(thread_db* tdbb, UCHAR* buffer, SLONG offset)
{
if (!(m_flags & IStatement::CURSOR_TYPE_SCROLLABLE))
(Arg::Gds(isc_invalid_fetch_option) << Arg::Str("RELATIVE")).raise();
if (m_state == BOS)
{
if (offset <= 0)
return -1;
return fetchFromCache(tdbb, buffer, offset - 1);
}
else if (m_state == EOS)
{
if (offset >= 0)
return 1;
fb_assert(m_eof);
if ((SINT64) m_cachedCount + offset < 0)
return -1;
return fetchFromCache(tdbb, buffer, m_cachedCount + offset);
}
if ((SINT64) m_position + offset < 0)
{
m_state = BOS;
return -1;
}
return fetchFromCache(tdbb, buffer, m_position + offset);
}
int DsqlCursor::fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position)
{
if (position >= m_cachedCount)
{
if (m_eof || !cacheInput(tdbb, position))
{
m_state = EOS;
return 1;
}
}
fb_assert(position < m_cachedCount);
const FB_UINT64 offset = position * m_messageSize;
const FB_UINT64 readBytes = m_space.read(offset, buffer, m_messageSize);
fb_assert(readBytes == m_messageSize);
m_position = position;
m_state = POSITIONED;
return 0;
}
bool DsqlCursor::cacheInput(thread_db* tdbb, FB_UINT64 position)
{
fb_assert(!m_eof);
const ULONG prefetchCount = MAX(PREFETCH_SIZE / m_messageSize, 1);
const ULONG prefetchSize = prefetchCount * m_messageSize;
UCharBuffer messageBuffer;
UCHAR* const buffer = messageBuffer.getBuffer(prefetchSize);
while (position >= m_cachedCount)
{
ULONG count = 0;
for (; count < prefetchCount; count++)
{
UCHAR* const ptr = buffer + count * m_messageSize;
if (!m_request->fetch(tdbb, ptr))
{
m_eof = true;
break;
}
}
if (count)
{
const FB_UINT64 offset = m_cachedCount * m_messageSize;
const ULONG fetchedSize = count * m_messageSize;
const FB_UINT64 writtenBytes = m_space.write(offset, buffer, fetchedSize);
fb_assert(writtenBytes == fetchedSize);
m_cachedCount += count;
}
if (m_eof)
break;
}
return (position < m_cachedCount);
}

78
src/dsql/DsqlCursor.h Normal file
View File

@ -0,0 +1,78 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Dmitry Yemanov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2015 Dmitry Yemanov <dimitrf@firebirdsql.org>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#ifndef DSQL_CURSOR_H
#define DSQL_CURSOR_H
#include "../jrd/TempSpace.h"
namespace Jrd {
class dsql_req;
class DsqlCursor
{
enum State { BOS, POSITIONED, EOS };
public:
explicit DsqlCursor(dsql_req* req, ULONG flags);
jrd_tra* getTransaction() const;
Attachment* getAttachment() const;
static void close(thread_db* tdbb, DsqlCursor* cursor);
int fetchNext(thread_db* tdbb, UCHAR* buffer);
int fetchPrior(thread_db* tdbb, UCHAR* buffer);
int fetchFirst(thread_db* tdbb, UCHAR* buffer);
int fetchLast(thread_db* tdbb, UCHAR* buffer);
int fetchAbsolute(thread_db* tdbb, UCHAR* buffer, SLONG position);
int fetchRelative(thread_db* tdbb, UCHAR* buffer, SLONG offset);
bool isBof() const
{
return (m_state == BOS);
}
bool isEof() const
{
return (m_state == EOS);
}
private:
int fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position);
bool cacheInput(thread_db* tdbb, FB_UINT64 position = MAX_UINT64);
dsql_req* const m_request;
const ULONG m_flags;
TempSpace m_space;
State m_state;
bool m_eof;
FB_UINT64 m_position;
FB_UINT64 m_cachedCount;
ULONG m_messageSize;
};
} // namespace
#endif // DSQL_CURSOR_H

View File

@ -77,7 +77,6 @@ using namespace Jrd;
using namespace Firebird;
static void close_cursor(thread_db*, dsql_req*);
static ULONG get_request_info(thread_db*, dsql_req*, ULONG, UCHAR*);
static dsql_dbb* init(Jrd::thread_db*, Jrd::Attachment*);
static void map_in_out(dsql_req*, bool, const dsql_msg*, IMessageMetadata*, UCHAR*,
@ -130,11 +129,10 @@ dsql_dbb::~dsql_dbb()
}
// Execute a non-SELECT dynamic SQL statement.
// Execute a dynamic SQL statement.
void DSQL_execute(thread_db* tdbb,
jrd_tra** tra_handle,
jrd_tra** tra_handle,
dsql_req* request,
bool flOpenCursor,
IMessageMetadata* in_meta, const UCHAR* in_msg,
IMessageMetadata* out_meta, UCHAR* out_msg)
{
@ -166,44 +164,66 @@ void DSQL_execute(thread_db* tdbb,
if (reqTypeWithCursor(statement->getType()))
{
if (request->req_flags & dsql_req::FLAG_OPENED_CURSOR)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-502) <<
Arg::Gds(isc_dsql_cursor_open_err));
}
if (!(flOpenCursor || singleton))
{
(Arg::Gds(isc_random) << "Can not execute select statement").raise();
}
}
else if (flOpenCursor)
{
if (request->req_flags & dsql_req::FLAG_OPENED_CURSOR)
if (request->req_cursor)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-502) <<
Arg::Gds(isc_dsql_cursor_open_err));
}
if (!singleton)
(Arg::Gds(isc_random) << "Cannot execute SELECT statement").raise();
}
request->req_transaction = *tra_handle;
request->execute(tdbb, tra_handle, in_meta, in_msg, out_meta, out_msg, singleton);
}
// If the output message length is zero on a TYPE_SELECT then we must
// be doing an OPEN cursor operation.
// If we do have an output message length, then we're doing
// a singleton SELECT. In that event, we don't add the cursor
// to the list of open cursors (it's not really open).
if (reqTypeWithCursor(statement->getType()) && !singleton)
// Open a dynamic SQL cursor.
DsqlCursor* DSQL_open(thread_db* tdbb,
jrd_tra** tra_handle,
dsql_req* request,
IMessageMetadata* in_meta, const UCHAR* in_msg,
IMessageMetadata* out_meta, ULONG flags)
{
SET_TDBB(tdbb);
Jrd::ContextPoolHolder context(tdbb, &request->getPool());
const DsqlCompiledStatement* statement = request->getStatement();
if (statement->getFlags() & DsqlCompiledStatement::FLAG_ORPHAN)
{
fb_assert(flOpenCursor);
request->req_flags |= dsql_req::FLAG_OPENED_CURSOR;
TRA_link_cursor(request->req_transaction, request);
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
Arg::Gds(isc_bad_req_handle));
}
else
// Validate transaction handle
if (!*tra_handle)
{
///fb_assert(!flOpenCursor);
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
Arg::Gds(isc_bad_trans_handle));
}
// Validate statement type
if (!reqTypeWithCursor(statement->getType()))
(Arg::Gds(isc_random) << "Cannot open non-SELECT statement").raise();
// Validate cursor being not already open
if (request->req_cursor)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-502) <<
Arg::Gds(isc_dsql_cursor_open_err));
}
request->req_transaction = *tra_handle;
request->execute(tdbb, tra_handle, in_meta, in_msg, out_meta, NULL, false);
request->req_cursor = FB_NEW(request->getPool()) DsqlCursor(request, flags);
return request->req_cursor;
}
@ -235,7 +255,7 @@ bool DsqlDmlRequest::fetch(thread_db* tdbb, UCHAR* msgBuffer)
// if the cursor isn't open, we've got a problem
if (reqTypeWithCursor(statement->getType()))
{
if (!(req_flags & dsql_req::FLAG_OPENED_CURSOR))
if (!req_cursor)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
Arg::Gds(isc_dsql_cursor_err) <<
@ -307,13 +327,13 @@ void DSQL_free_statement(thread_db* tdbb, dsql_req* request, USHORT option)
// Just close the cursor associated with the request
if (reqTypeWithCursor(statement->getType()))
{
if (!(request->req_flags & dsql_req::FLAG_OPENED_CURSOR))
if (!request->req_cursor)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-501) <<
Arg::Gds(isc_dsql_cursor_close_err));
}
close_cursor(tdbb, request);
DsqlCursor::close(tdbb, request->req_cursor);
}
}
}
@ -419,7 +439,7 @@ void DsqlDmlRequest::setCursor(thread_db* tdbb, const TEXT* name)
USHORT length = (USHORT) fb_utils::name_length(cursor.c_str());
if (length == 0)
if (!length)
{
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-502) <<
Arg::Gds(isc_dsql_decl_err) <<
@ -447,20 +467,18 @@ 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() || !(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
if (req_cursor && req_cursor_name.hasData())
{
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);
Arg::Gds(isc_dsql_cursor_redefined) << req_cursor_name);
}
if (req_cursor_name.hasData())
req_dbb->dbb_cursors.remove(req_cursor_name);
req_cursor_name = cursor;
req_dbb->dbb_cursors.put(cursor, this);
}
@ -492,55 +510,6 @@ void DSQL_sql_info(thread_db* tdbb,
}
/**
close_cursor
@brief Close an open cursor.
@param request
@param tdbb
**/
static void close_cursor(thread_db* tdbb, dsql_req* request)
{
SET_TDBB(tdbb);
Jrd::Attachment* attachment = request->req_dbb->dbb_attachment;
const DsqlCompiledStatement* statement = request->getStatement();
if (request->req_request)
{
ThreadStatusGuard status_vector(tdbb);
try
{
// Report some remaining fetches if any
if (request->req_fetch_baseline)
{
TraceDSQLFetch trace(attachment, request);
trace.fetch(true, ITracePlugin::TRACE_RESULT_SUCCESS);
}
if (request->req_traced && TraceManager::need_dsql_free(attachment))
{
TraceSQLStatementImpl stmt(request, NULL);
TraceManager::event_dsql_free(attachment, &stmt, DSQL_close);
}
JRD_unwind_request(tdbb, request->req_request);
}
catch (Firebird::Exception&)
{
}
}
request->req_flags &= ~dsql_req::FLAG_OPENED_CURSOR;
TRA_unlink_cursor(request->req_transaction, request);
}
// Common part of prepare and execute a statement.
void DSQL_execute_immediate(thread_db* tdbb, Jrd::Attachment* attachment, jrd_tra** tra_handle,
ULONG length, const TEXT* string, USHORT dialect,
@ -1530,7 +1499,8 @@ dsql_req::dsql_req(MemoryPool& pool)
req_dbb(NULL),
req_transaction(NULL),
req_msg_buffers(req_pool),
req_cursor(req_pool),
req_cursor_name(req_pool),
req_cursor(NULL),
req_user_descs(req_pool),
req_traced(false),
req_interface(NULL)
@ -1588,8 +1558,8 @@ void dsql_req::destroy(thread_db* tdbb, dsql_req* request, bool drop)
// If the request had an open cursor, close it
if (request->req_flags & dsql_req::FLAG_OPENED_CURSOR)
close_cursor(tdbb, request);
if (request->req_cursor)
DsqlCursor::close(tdbb, request->req_cursor);
Jrd::Attachment* att = request->req_dbb->dbb_attachment;
const bool need_trace_free = request->req_traced && TraceManager::need_dsql_free(att);
@ -1600,10 +1570,10 @@ void dsql_req::destroy(thread_db* tdbb, dsql_req* request, bool drop)
}
request->req_traced = false;
if (request->req_cursor.hasData())
if (request->req_cursor_name.hasData())
{
request->req_dbb->dbb_cursors.remove(request->req_cursor);
request->req_cursor = "";
request->req_dbb->dbb_cursors.remove(request->req_cursor_name);
request->req_cursor_name = "";
}
// If a request has been compiled, release it now
@ -1618,8 +1588,7 @@ void dsql_req::destroy(thread_db* tdbb, dsql_req* request, bool drop)
request->req_request = NULL;
}
catch (Firebird::Exception&)
{
}
{} // no-op
}
const DsqlCompiledStatement* statement = request->getStatement();
@ -1628,9 +1597,7 @@ void dsql_req::destroy(thread_db* tdbb, dsql_req* request, bool drop)
// Release the entire request if explicitly asked for
if (drop)
{
request->req_dbb->deletePool(&request->getPool());
}
}

View File

@ -34,18 +34,21 @@
#ifndef DSQL_DSQL_H
#define DSQL_DSQL_H
#include "../jrd/RuntimeStatistics.h"
#include "../jrd/ntrace.h"
#include "../jrd/val.h" // Get rid of duplicated FUN_T enum.
#include "../jrd/Attachment.h"
#include "../dsql/BlrDebugWriter.h"
#include "../dsql/ddl_proto.h"
#include "../common/classes/array.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/MetaName.h"
#include "../common/classes/stack.h"
#include "../common/classes/auto.h"
#include "../common/classes/NestConst.h"
#include "../jrd/EngineInterface.h"
#include "../jrd/RuntimeStatistics.h"
#include "../jrd/ntrace.h"
#include "../jrd/val.h" // Get rid of duplicated FUN_T enum.
#include "../jrd/Attachment.h"
#include "../dsql/BlrDebugWriter.h"
#include "../dsql/ddl_proto.h"
#include "../dsql/DsqlCursor.h"
#ifdef DEV_BUILD
// This macro enables DSQL tracing code
@ -61,8 +64,6 @@ DEFINE_TRACE_ROUTINE(dsql_trace);
#include "../dsql/sym.h"
#include "../jrd/EngineInterface.h"
// Context aliases used in triggers
const char* const OLD_CONTEXT_NAME = "OLD";
const char* const NEW_CONTEXT_NAME = "NEW";
@ -523,9 +524,6 @@ private:
class dsql_req : public pool_alloc<dsql_type_req>
{
public:
static const unsigned FLAG_OPENED_CURSOR = 0x01;
public:
explicit dsql_req(MemoryPool& pool);
@ -572,10 +570,9 @@ public:
jrd_tra* req_transaction; // JRD transaction
jrd_req* req_request; // JRD request
unsigned req_flags; // flags
Firebird::Array<UCHAR*> req_msg_buffers;
Firebird::string req_cursor; // Cursor name, if any
Firebird::string req_cursor_name; // Cursor name, if any
DsqlCursor* req_cursor; // Open cursor, if any
Firebird::GenericMap<Firebird::NonPooled<const dsql_par*, dsc> > req_user_descs; // SQLDA data type
Firebird::AutoPtr<Jrd::RuntimeStatistics> req_fetch_baseline; // State of request performance counters when we reported it last time

View File

@ -34,12 +34,15 @@ namespace Jrd {
class dsql_req;
}
void DSQL_execute(Jrd::thread_db*, Jrd::jrd_tra**, Jrd::dsql_req*, bool,
Firebird::IMessageMetadata*, const UCHAR*, Firebird::IMessageMetadata*, UCHAR*);
void DSQL_execute(Jrd::thread_db*, Jrd::jrd_tra**, Jrd::dsql_req*,
Firebird::IMessageMetadata*, const UCHAR*, Firebird::IMessageMetadata*, UCHAR*);
void DSQL_execute_immediate(Jrd::thread_db*, Jrd::Attachment*, Jrd::jrd_tra**,
ULONG, const TEXT*, USHORT, Firebird::IMessageMetadata*, const UCHAR*,
Firebird::IMessageMetadata*, UCHAR*, bool);
void DSQL_free_statement(Jrd::thread_db*, Jrd::dsql_req*, USHORT);
Jrd::DsqlCursor* DSQL_open(Jrd::thread_db*, Jrd::jrd_tra**, Jrd::dsql_req*,
Firebird::IMessageMetadata*, const UCHAR*,
Firebird::IMessageMetadata*, ULONG);
Jrd::dsql_req* DSQL_prepare(Jrd::thread_db*, Jrd::Attachment*, Jrd::jrd_tra*, ULONG, const TEXT*,
USHORT, Firebird::Array<UCHAR>*, Firebird::Array<UCHAR>*, bool);
void DSQL_sql_info(Jrd::thread_db*, Jrd::dsql_req*,

View File

@ -1002,7 +1002,7 @@ static void gen_blob_for( const act* action, USHORT column)
column += INDENT;
gen_get_segment(action, column);
printa(column, "if (fbIStatus == Firebird::IStatus::FB_ERROR || "
"fbIStatus == Firebird::IStatus::FB_EOF) break;");
"fbIStatus == Firebird::IStatus::FB_NO_DATA) break;");
}

View File

@ -59,7 +59,7 @@ interface Status : Disposable
// completion codes - not used in Status, but I must have them somewhere
const int FB_ERROR = -1;
const int FB_OK = 0;
const int FB_EOF = 1;
const int FB_NO_DATA = 1;
const int FB_SEGMENT = 2;
void init();
@ -385,7 +385,7 @@ interface ResultSet : ReferenceCounted
[notImplemented(Status::FB_ERROR)] int fetchPrior(Status status, void* message);
[notImplemented(Status::FB_ERROR)] int fetchFirst(Status status, void* message);
[notImplemented(Status::FB_ERROR)] int fetchLast(Status status, void* message);
[notImplemented(Status::FB_ERROR)] int fetchAbsolute(Status status, uint position, void* message);
[notImplemented(Status::FB_ERROR)] int fetchAbsolute(Status status, int position, void* message);
[notImplemented(Status::FB_ERROR)] int fetchRelative(Status status, int offset, void* message);
boolean isEof(Status status);
boolean isBof(Status status);
@ -420,6 +420,9 @@ interface Statement : ReferenceCounted
const uint FLAG_HAS_CURSOR = 0x01;
const uint FLAG_REPEAT_EXECUTE = 0x02;
// Cursor flags.
const uint CURSOR_TYPE_SCROLLABLE = 0x01;
void getInfo(Status status,
uint itemsLength, const uchar* items,
uint bufferLength, uchar* buffer);
@ -431,7 +434,7 @@ interface Statement : ReferenceCounted
Transaction execute(Status status, Transaction transaction,
MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, void* outBuffer);
ResultSet openCursor(Status status, Transaction transaction,
MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata);
MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata, uint flags);
void setCursorName(Status status, const string name);
void free(Status status);
uint getFlags(Status status);
@ -495,7 +498,7 @@ interface Attachment : ReferenceCounted
ResultSet openCursor(Status status, Transaction transaction,
uint stmtLength, const string sqlStmt, uint dialect,
MessageMetadata inMetadata, void* inBuffer, MessageMetadata outMetadata,
const string cursorName);
const string cursorName, uint cursorFlags);
Events queEvents(Status status, EventCallback callback,
uint length, const uchar* events);
void cancelOperation(Status status, int option);

View File

@ -229,7 +229,7 @@ namespace Firebird
static const unsigned FB_HAS_ERRORS = 2;
static const int FB_ERROR = -1;
static const int FB_OK = 0;
static const int FB_EOF = 1;
static const int FB_NO_DATA = 1;
static const int FB_SEGMENT = 2;
void init()
@ -1370,7 +1370,7 @@ namespace Firebird
int (CLOOP_CARG *fetchPrior)(IResultSet* self, IStatus* status, void* message) throw();
int (CLOOP_CARG *fetchFirst)(IResultSet* self, IStatus* status, void* message) throw();
int (CLOOP_CARG *fetchLast)(IResultSet* self, IStatus* status, void* message) throw();
int (CLOOP_CARG *fetchAbsolute)(IResultSet* self, IStatus* status, unsigned position, void* message) throw();
int (CLOOP_CARG *fetchAbsolute)(IResultSet* self, IStatus* status, int position, void* message) throw();
int (CLOOP_CARG *fetchRelative)(IResultSet* self, IStatus* status, int offset, void* message) throw();
FB_BOOLEAN (CLOOP_CARG *isEof)(IResultSet* self, IStatus* status) throw();
FB_BOOLEAN (CLOOP_CARG *isBof)(IResultSet* self, IStatus* status) throw();
@ -1420,7 +1420,7 @@ namespace Firebird
return ret;
}
template <typename StatusType> int fetchAbsolute(StatusType* status, unsigned position, void* message)
template <typename StatusType> int fetchAbsolute(StatusType* status, int position, void* message)
{
int ret = static_cast<VTable*>(this->cloopVTable)->fetchAbsolute(this, status, position, message);
StatusType::checkException(status);
@ -1480,7 +1480,7 @@ namespace Firebird
IMessageMetadata* (CLOOP_CARG *getInputMetadata)(IStatement* self, IStatus* status) throw();
IMessageMetadata* (CLOOP_CARG *getOutputMetadata)(IStatement* self, IStatus* status) throw();
ITransaction* (CLOOP_CARG *execute)(IStatement* self, IStatus* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, void* outBuffer) throw();
IResultSet* (CLOOP_CARG *openCursor)(IStatement* self, IStatus* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata) throw();
IResultSet* (CLOOP_CARG *openCursor)(IStatement* self, IStatus* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, unsigned flags) throw();
void (CLOOP_CARG *setCursorName)(IStatement* self, IStatus* status, const char* name) throw();
void (CLOOP_CARG *free)(IStatement* self, IStatus* status) throw();
unsigned (CLOOP_CARG *getFlags)(IStatement* self, IStatus* status) throw();
@ -1511,6 +1511,8 @@ namespace Firebird
static const unsigned PREPARE_PREFETCH_ALL = IStatement::PREPARE_PREFETCH_METADATA | IStatement::PREPARE_PREFETCH_LEGACY_PLAN | IStatement::PREPARE_PREFETCH_DETAILED_PLAN | IStatement::PREPARE_PREFETCH_AFFECTED_RECORDS;
static const unsigned FLAG_HAS_CURSOR = 1;
static const unsigned FLAG_REPEAT_EXECUTE = 2;
static const unsigned CURSOR_TYPE_SCROLLABLE = 1;
template <typename StatusType> void getInfo(StatusType* status, unsigned itemsLength, const unsigned char* items, unsigned bufferLength, unsigned char* buffer)
{
@ -1560,9 +1562,9 @@ namespace Firebird
return ret;
}
template <typename StatusType> IResultSet* openCursor(StatusType* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata)
template <typename StatusType> IResultSet* openCursor(StatusType* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, unsigned flags)
{
IResultSet* ret = static_cast<VTable*>(this->cloopVTable)->openCursor(this, status, transaction, inMetadata, inBuffer, outMetadata);
IResultSet* ret = static_cast<VTable*>(this->cloopVTable)->openCursor(this, status, transaction, inMetadata, inBuffer, outMetadata, flags);
StatusType::checkException(status);
return ret;
}
@ -1702,7 +1704,7 @@ namespace Firebird
void (CLOOP_CARG *executeDyn)(IAttachment* self, IStatus* status, ITransaction* transaction, unsigned length, const unsigned char* dyn) throw();
IStatement* (CLOOP_CARG *prepare)(IAttachment* self, IStatus* status, ITransaction* tra, unsigned stmtLength, const char* sqlStmt, unsigned dialect, unsigned flags) throw();
ITransaction* (CLOOP_CARG *execute)(IAttachment* self, IStatus* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, void* outBuffer) throw();
IResultSet* (CLOOP_CARG *openCursor)(IAttachment* self, IStatus* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const char* cursorName) throw();
IResultSet* (CLOOP_CARG *openCursor)(IAttachment* self, IStatus* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const char* cursorName, unsigned cursorFlags) throw();
IEvents* (CLOOP_CARG *queEvents)(IAttachment* self, IStatus* status, IEventCallback* callback, unsigned length, const unsigned char* events) throw();
void (CLOOP_CARG *cancelOperation)(IAttachment* self, IStatus* status, int option) throw();
void (CLOOP_CARG *ping)(IAttachment* self, IStatus* status) throw();
@ -1803,9 +1805,9 @@ namespace Firebird
return ret;
}
template <typename StatusType> IResultSet* openCursor(StatusType* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const char* cursorName)
template <typename StatusType> IResultSet* openCursor(StatusType* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const char* cursorName, unsigned cursorFlags)
{
IResultSet* ret = static_cast<VTable*>(this->cloopVTable)->openCursor(this, status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, cursorName);
IResultSet* ret = static_cast<VTable*>(this->cloopVTable)->openCursor(this, status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, cursorName, cursorFlags);
StatusType::checkException(status);
return ret;
}
@ -7379,7 +7381,7 @@ namespace Firebird
}
}
static int CLOOP_CARG cloopfetchAbsoluteDispatcher(IResultSet* self, IStatus* status, unsigned position, void* message) throw()
static int CLOOP_CARG cloopfetchAbsoluteDispatcher(IResultSet* self, IStatus* status, int position, void* message) throw()
{
StatusType status2(status);
@ -7525,7 +7527,7 @@ namespace Firebird
virtual int fetchPrior(StatusType* status, void* message) = 0;
virtual int fetchFirst(StatusType* status, void* message) = 0;
virtual int fetchLast(StatusType* status, void* message) = 0;
virtual int fetchAbsolute(StatusType* status, unsigned position, void* message) = 0;
virtual int fetchAbsolute(StatusType* status, int position, void* message) = 0;
virtual int fetchRelative(StatusType* status, int offset, void* message) = 0;
virtual FB_BOOLEAN isEof(StatusType* status) = 0;
virtual FB_BOOLEAN isBof(StatusType* status) = 0;
@ -7670,13 +7672,13 @@ namespace Firebird
}
}
static IResultSet* CLOOP_CARG cloopopenCursorDispatcher(IStatement* self, IStatus* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata) throw()
static IResultSet* CLOOP_CARG cloopopenCursorDispatcher(IStatement* self, IStatus* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, unsigned flags) throw()
{
StatusType status2(status);
try
{
return static_cast<Name*>(self)->Name::openCursor(&status2, transaction, inMetadata, inBuffer, outMetadata);
return static_cast<Name*>(self)->Name::openCursor(&status2, transaction, inMetadata, inBuffer, outMetadata, flags);
}
catch (...)
{
@ -7774,7 +7776,7 @@ namespace Firebird
virtual IMessageMetadata* getInputMetadata(StatusType* status) = 0;
virtual IMessageMetadata* getOutputMetadata(StatusType* status) = 0;
virtual ITransaction* execute(StatusType* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, void* outBuffer) = 0;
virtual IResultSet* openCursor(StatusType* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata) = 0;
virtual IResultSet* openCursor(StatusType* status, ITransaction* transaction, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, unsigned flags) = 0;
virtual void setCursorName(StatusType* status, const char* name) = 0;
virtual void free(StatusType* status) = 0;
virtual unsigned getFlags(StatusType* status) = 0;
@ -8247,13 +8249,13 @@ namespace Firebird
}
}
static IResultSet* CLOOP_CARG cloopopenCursorDispatcher(IAttachment* self, IStatus* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const char* cursorName) throw()
static IResultSet* CLOOP_CARG cloopopenCursorDispatcher(IAttachment* self, IStatus* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const char* cursorName, unsigned cursorFlags) throw()
{
StatusType status2(status);
try
{
return static_cast<Name*>(self)->Name::openCursor(&status2, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, cursorName);
return static_cast<Name*>(self)->Name::openCursor(&status2, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, cursorName, cursorFlags);
}
catch (...)
{
@ -8384,7 +8386,7 @@ namespace Firebird
virtual void executeDyn(StatusType* status, ITransaction* transaction, unsigned length, const unsigned char* dyn) = 0;
virtual IStatement* prepare(StatusType* status, ITransaction* tra, unsigned stmtLength, const char* sqlStmt, unsigned dialect, unsigned flags) = 0;
virtual ITransaction* execute(StatusType* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, void* outBuffer) = 0;
virtual IResultSet* openCursor(StatusType* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const char* cursorName) = 0;
virtual IResultSet* openCursor(StatusType* status, ITransaction* transaction, unsigned stmtLength, const char* sqlStmt, unsigned dialect, IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, const char* cursorName, unsigned cursorFlags) = 0;
virtual IEvents* queEvents(StatusType* status, IEventCallback* callback, unsigned length, const unsigned char* events) = 0;
virtual void cancelOperation(StatusType* status, int option) = 0;
virtual void ping(StatusType* status) = 0;

View File

@ -1880,7 +1880,7 @@ void ISQL_print_validation(FILE* fp,
{
unsigned int length;
int cc = blob->getSegment(fbStatus, sizeof(buffer) - 1, buffer, &length);
if (cc == Firebird::IStatus::FB_EOF || cc == Firebird::IStatus::FB_ERROR)
if (cc == Firebird::IStatus::FB_NO_DATA || cc == Firebird::IStatus::FB_ERROR)
break;
buffer[length] = 0;
@ -7598,7 +7598,7 @@ processing_state ISQL_print_item_blob(FILE* fp, const IsqlVar* var, Firebird::IT
{
unsigned int length;
int cc = blob->getSegment(fbStatus, sizeof(buffer) - 1, buffer, &length);
if (cc == Firebird::IStatus::FB_EOF || cc == Firebird::IStatus::FB_ERROR)
if (cc == Firebird::IStatus::FB_NO_DATA || cc == Firebird::IStatus::FB_ERROR)
break;
// Special displays for blr or acl subtypes
@ -8556,7 +8556,7 @@ static processing_state process_statement(const TEXT* str2)
// Otherwise, open the cursor to start things up
Firebird::IResultSet* curs = global_Stmt->openCursor(fbStatus, M__trans,
NULL, NULL, message);
NULL, NULL, message, Firebird::IStatement::CURSOR_TYPE_SCROLLABLE);
if (ISQL_errmsg(fbStatus))
{
return ps_ERR;
@ -8591,10 +8591,8 @@ static processing_state process_statement(const TEXT* str2)
// Fetch the current cursor
if (curs->fetchNext(fbStatus, buffer) == Firebird::IStatus::FB_EOF)
{
if (curs->fetchNext(fbStatus, buffer) == Firebird::IStatus::FB_NO_DATA)
break;
}
// Print the header every Pagelength number of lines for
// command-line ISQL only.

View File

@ -1611,7 +1611,7 @@ void SHOW_print_metadata_text_blob(FILE* fp, ISC_QUAD* blobid, bool escape_squot
{
unsigned int length;
int cc = blob->getSegment(fbStatus, sizeof(buffer) - 1, buffer, &length);
if (cc == Firebird::IStatus::FB_EOF || cc == Firebird::IStatus::FB_ERROR)
if (cc == Firebird::IStatus::FB_NO_DATA || cc == Firebird::IStatus::FB_ERROR)
break;
// ASF: In Windows, \n characters are printed as \r\n in text mode.
@ -5810,7 +5810,7 @@ static processing_state show_users12()
return ps_ERR;
Firebird::IResultSet* rs = DB->openCursor(fbStatus, fbTrans, 0, getusers, isqlGlob.SQL_dialect,
NULL, NULL, outMetadata, NULL);
NULL, NULL, outMetadata, NULL, 0);
if (ISQL_errmsg (fbStatus))
return ps_ERR;

View File

@ -238,7 +238,7 @@ RecordBuffer* DbCreatorsList::getList(thread_db* tdbb, jrd_rel* relation)
LocalStatus st;
RefPtr<IResultSet> curs(att->openCursor(&st, tra, 0,
"select RDB$USER_TYPE, RDB$USER from RDB$DB_CREATORS",
SQL_DIALECT_V6, NULL, NULL, gr.getMetadata(), NULL));
SQL_DIALECT_V6, NULL, NULL, gr.getMetadata(), NULL, 0));
if (st.getStatus() & IStatus::FB_HAS_ERRORS)
{

View File

@ -33,6 +33,7 @@ namespace Jrd {
// Engine objects used by interface objects
class blb;
class jrd_tra;
class DsqlCursor;
class dsql_req;
class JrdStatement;
class StableAttachmentPart;
@ -148,7 +149,7 @@ public:
int fetchPrior(Firebird::CheckStatusWrapper* status, void* message);
int fetchFirst(Firebird::CheckStatusWrapper* status, void* message);
int fetchLast(Firebird::CheckStatusWrapper* status, void* message);
int fetchAbsolute(Firebird::CheckStatusWrapper* status, unsigned int position, void* message);
int fetchAbsolute(Firebird::CheckStatusWrapper* status, int position, void* message);
int fetchRelative(Firebird::CheckStatusWrapper* status, int offset, void* message);
FB_BOOLEAN isEof(Firebird::CheckStatusWrapper* status);
FB_BOOLEAN isBof(Firebird::CheckStatusWrapper* status);
@ -157,21 +158,22 @@ public:
void setDelayedOutputFormat(Firebird::CheckStatusWrapper* status, Firebird::IMessageMetadata* format);
public:
JResultSet(JStatement* aStatement);
JResultSet(DsqlCursor* handle, StableAttachmentPart* sa);
JStatement* getStatement()
StableAttachmentPart* getAttachment()
{
return statement;
return sAtt;
}
StableAttachmentPart* getAttachment();
// Change after adding separate handle for cursor in dsql
dsql_req* getHandle() throw();
DsqlCursor* getHandle() throw()
{
return cursor;
}
private:
Firebird::RefPtr<JStatement> statement;
bool eof;
DsqlCursor* cursor;
Firebird::RefPtr<StableAttachmentPart> sAtt;
int state;
void freeEngineData(Firebird::CheckStatusWrapper* status);
};
@ -196,7 +198,7 @@ public:
Firebird::IMessageMetadata* outMetadata, void* outBuffer);
JResultSet* openCursor(Firebird::CheckStatusWrapper* status,
Firebird::ITransaction* transaction, Firebird::IMessageMetadata* inMetadata, void* inBuffer,
Firebird::IMessageMetadata* outMetadata);
Firebird::IMessageMetadata* outMetadata, unsigned int flags);
void setCursorName(Firebird::CheckStatusWrapper* status, const char* name);
unsigned getFlags(Firebird::CheckStatusWrapper* status);
@ -221,17 +223,6 @@ private:
void freeEngineData(Firebird::CheckStatusWrapper* status);
};
inline StableAttachmentPart* JResultSet::getAttachment()
{
return statement->getAttachment();
}
// Change after adding separate handle for cursor in dsql
inline dsql_req* JResultSet::getHandle() throw()
{
return statement->getHandle();
}
class JRequest FB_FINAL :
public Firebird::RefCntIface<Firebird::IRequestImpl<JRequest, Firebird::CheckStatusWrapper> >
{
@ -343,7 +334,7 @@ public:
Firebird::IResultSet* openCursor(Firebird::CheckStatusWrapper* status,
Firebird::ITransaction* transaction, unsigned int stmtLength, const char* sqlStmt,
unsigned int dialect, Firebird::IMessageMetadata* inMetadata, void* inBuffer,
Firebird::IMessageMetadata* outMetadata, const char* cursorName);
Firebird::IMessageMetadata* outMetadata, const char* cursorName, unsigned int cursorFlags);
JEvents* queEvents(Firebird::CheckStatusWrapper* status, Firebird::IEventCallback* callback,
unsigned int length, const unsigned char* events);
void cancelOperation(Firebird::CheckStatusWrapper* status, int option);

View File

@ -279,7 +279,7 @@ public:
"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(), NULL);
3, NULL, NULL, mMap.getMetadata(), NULL, 0);
if (st.getStatus() & IStatus::FB_HAS_ERRORS)
{
if (fb_utils::containsErrorCode(st.getErrors(), isc_dsql_relation_err))
@ -1199,7 +1199,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(), NULL);
3, NULL, NULL, mMap.getMetadata(), NULL, 0);
if (st.getStatus() & IStatus::FB_HAS_ERRORS)
{
if (!fb_utils::containsErrorCode(st.getErrors(), isc_dsql_relation_err))

View File

@ -337,7 +337,7 @@ void PreparedStatement::execute(thread_db* tdbb, jrd_tra* transaction)
if (builder)
builder->moveToStatement(tdbb, this);
DSQL_execute(tdbb, &transaction, request, false, inMetadata, inMessage.begin(), NULL, NULL);
DSQL_execute(tdbb, &transaction, request, inMetadata, inMessage.begin(), NULL, NULL);
}
@ -348,7 +348,7 @@ void PreparedStatement::open(thread_db* tdbb, jrd_tra* transaction)
if (builder)
builder->moveToStatement(tdbb, this);
DSQL_execute(tdbb, &transaction, request, true, inMetadata, inMessage.begin(), outMetadata, NULL);
DSQL_open(tdbb, &transaction, request, inMetadata, inMessage.begin(), outMetadata, 0);
}

View File

@ -536,7 +536,7 @@ void InternalStatement::doOpen(thread_db* tdbb)
fb_assert(m_inMetadata->getMessageLength() == m_in_buffer.getCount());
m_cursor = m_request->openCursor(&statusWrapper, transaction,
m_inMetadata, m_in_buffer.begin(), m_outMetadata);
m_inMetadata, m_in_buffer.begin(), m_outMetadata, 0);
}
if (status.getStatus() & IStatus::FB_HAS_ERRORS)
@ -560,7 +560,7 @@ bool InternalStatement::doFetch(thread_db* tdbb)
}
if (status.getStatus() & IStatus::FB_HAS_ERRORS)
raise(status, tdbb, "JResultSet::fetch");
raise(status, tdbb, "JResultSet::fetchNext");
return res;
}

View File

@ -49,6 +49,7 @@
#include <errno.h>
#include "../jrd/ibase.h"
#include "../jrd/EngineInterface.h"
#include "../jrd/jrd.h"
#include "../jrd/irq.h"
#include "../jrd/drq.h"
@ -126,7 +127,6 @@
#include "../common/classes/RefMutex.h"
#include "../common/utils_proto.h"
#include "../jrd/DebugInterface.h"
#include "../jrd/EngineInterface.h"
#include "../jrd/CryptoManager.h"
#include "../jrd/DbCreators.h"
@ -318,8 +318,8 @@ JTransaction::JTransaction(JTransaction* from)
}
JResultSet::JResultSet(JStatement* aStatement)
: statement(aStatement), eof(false)
JResultSet::JResultSet(DsqlCursor* handle, StableAttachmentPart* sa)
: cursor(handle), sAtt(sa), state(-1)
{
}
@ -635,6 +635,15 @@ namespace
validateHandle(tdbb, events->getAttachment()->getHandle());
}
inline void validateHandle(thread_db* tdbb, DsqlCursor* const cursor)
{
if (!cursor)
status_exception::raise(Arg::Gds(isc_bad_req_handle));
validateHandle(tdbb, cursor->getTransaction());
validateHandle(tdbb, cursor->getAttachment());
}
class AttachmentHolder
{
public:
@ -3080,7 +3089,7 @@ int JBlob::getSegment(CheckStatusWrapper* user_status, unsigned int buffer_lengt
}
if (getHandle()->blb_flags & BLB_eof)
cc = IStatus::FB_EOF;
cc = IStatus::FB_NO_DATA;
else if (getHandle()->getFragmentSize())
cc = IStatus::FB_SEGMENT;
else
@ -4413,7 +4422,7 @@ ITransaction* JStatement::execute(CheckStatusWrapper* user_status, ITransaction*
try
{
DSQL_execute(tdbb, &tra, getHandle(), false,
DSQL_execute(tdbb, &tra, getHandle(),
inMetadata, static_cast<UCHAR*>(inBuffer),
outMetadata, static_cast<UCHAR*>(outBuffer));
@ -4456,7 +4465,7 @@ ITransaction* JStatement::execute(CheckStatusWrapper* user_status, ITransaction*
JResultSet* JStatement::openCursor(CheckStatusWrapper* user_status, ITransaction* transaction,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata)
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, unsigned int flags)
{
JTransaction* jt = transaction ? getAttachment()->getTransactionInterface(user_status, transaction) : NULL;
jrd_tra* tra = jt ? jt->getHandle() : NULL;
@ -4483,10 +4492,12 @@ JResultSet* JStatement::openCursor(CheckStatusWrapper* user_status, ITransaction
}
}
DSQL_execute(tdbb, &tra, getHandle(), true,
inMetadata, static_cast<UCHAR*>(inBuffer), outMetadata, NULL);
DsqlCursor* const cursor =
DSQL_open(tdbb, &tra, getHandle(),
inMetadata, static_cast<UCHAR*>(inBuffer),
outMetadata, flags);
rs = new JResultSet(this);
rs = new JResultSet(cursor, getAttachment());
rs->addRef();
}
catch (const Exception& ex)
@ -4510,7 +4521,7 @@ JResultSet* JStatement::openCursor(CheckStatusWrapper* user_status, ITransaction
IResultSet* JAttachment::openCursor(CheckStatusWrapper* user_status, ITransaction* apiTra,
unsigned int length, const char* string, unsigned int dialect,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata,
const char* cursorName)
const char* cursorName, unsigned int cursorFlags)
{
IStatement* tmpStatement = prepare(user_status, apiTra, length, string, dialect,
(outMetadata ? 0 : IStatement::PREPARE_PREFETCH_OUTPUT_PARAMETERS));
@ -4530,7 +4541,7 @@ IResultSet* JAttachment::openCursor(CheckStatusWrapper* user_status, ITransactio
}
IResultSet* rs = tmpStatement->openCursor(user_status, apiTra,
inMetadata, inBuffer, outMetadata);
inMetadata, inBuffer, outMetadata, cursorFlags);
tmpStatement->release();
return rs;
@ -4593,36 +4604,28 @@ ITransaction* JAttachment::execute(CheckStatusWrapper* user_status, ITransaction
}
successful_completion(user_status);
return jt;
}
int JResultSet::fetchNext(CheckStatusWrapper* user_status, void* buffer)
{
bool hasMessage = false;
try
{
EngineContextHolder tdbb(user_status, this, FB_FUNCTION);
dsql_req* req = getStatement()->getHandle();
validateHandle(tdbb, req->req_transaction);
check_database(tdbb);
try
{
hasMessage = req->fetch(tdbb, static_cast<UCHAR*>(buffer));
if (!hasMessage)
{
eof = true;
}
state = cursor->fetchNext(tdbb, static_cast<UCHAR*>(buffer));
}
catch (const Exception& ex)
{
transliterateException(tdbb, ex, user_status, "JStatement::fetch");
transliterateException(tdbb, ex, user_status, "JResultSet::fetchNext");
return IStatus::FB_ERROR;
}
trace_warning(tdbb, user_status, "JResultSet::fetch");
trace_warning(tdbb, user_status, "JResultSet::fetchNext");
}
catch (const Exception& ex)
{
@ -4631,17 +4634,27 @@ int JResultSet::fetchNext(CheckStatusWrapper* user_status, void* buffer)
}
successful_completion(user_status);
if (hasMessage)
return IStatus::FB_OK;
return IStatus::FB_EOF;
return (state == 0) ? IStatus::FB_OK : IStatus::FB_NO_DATA;
}
int JResultSet::fetchPrior(CheckStatusWrapper* user_status, void* buffer)
{
try
{
status_exception::raise(Arg::Gds(isc_wish_list));
EngineContextHolder tdbb(user_status, this, FB_FUNCTION);
check_database(tdbb);
try
{
state = cursor->fetchPrior(tdbb, static_cast<UCHAR*>(buffer));
}
catch (const Exception& ex)
{
transliterateException(tdbb, ex, user_status, "JResultSet::fetchPrior");
return IStatus::FB_ERROR;
}
trace_warning(tdbb, user_status, "JResultSet::fetchPrior");
}
catch (const Exception& ex)
{
@ -4650,15 +4663,28 @@ int JResultSet::fetchPrior(CheckStatusWrapper* user_status, void* buffer)
}
successful_completion(user_status);
return IStatus::FB_OK;
return (state == 0) ? IStatus::FB_OK : IStatus::FB_NO_DATA;
}
int JResultSet::fetchFirst(CheckStatusWrapper* user_status, void* buffer)
{
try
{
status_exception::raise(Arg::Gds(isc_wish_list));
EngineContextHolder tdbb(user_status, this, FB_FUNCTION);
check_database(tdbb);
try
{
state = cursor->fetchFirst(tdbb, static_cast<UCHAR*>(buffer));
}
catch (const Exception& ex)
{
transliterateException(tdbb, ex, user_status, "JResultSet::fetchFirst");
return IStatus::FB_ERROR;
}
trace_warning(tdbb, user_status, "JResultSet::fetchFirst");
}
catch (const Exception& ex)
{
@ -4667,15 +4693,28 @@ int JResultSet::fetchFirst(CheckStatusWrapper* user_status, void* buffer)
}
successful_completion(user_status);
return IStatus::FB_OK;
return (state == 0) ? IStatus::FB_OK : IStatus::FB_NO_DATA;
}
int JResultSet::fetchLast(CheckStatusWrapper* user_status, void* buffer)
{
try
{
status_exception::raise(Arg::Gds(isc_wish_list));
EngineContextHolder tdbb(user_status, this, FB_FUNCTION);
check_database(tdbb);
try
{
state = cursor->fetchLast(tdbb, static_cast<UCHAR*>(buffer));
}
catch (const Exception& ex)
{
transliterateException(tdbb, ex, user_status, "JResultSet::fetchLast");
return IStatus::FB_ERROR;
}
trace_warning(tdbb, user_status, "JResultSet::fetchLast");
}
catch (const Exception& ex)
{
@ -4684,15 +4723,28 @@ int JResultSet::fetchLast(CheckStatusWrapper* user_status, void* buffer)
}
successful_completion(user_status);
return IStatus::FB_OK;
return (state == 0) ? IStatus::FB_OK : IStatus::FB_NO_DATA;
}
int JResultSet::fetchAbsolute(CheckStatusWrapper* user_status, unsigned position, void* buffer)
int JResultSet::fetchAbsolute(CheckStatusWrapper* user_status, int position, void* buffer)
{
try
{
status_exception::raise(Arg::Gds(isc_wish_list));
EngineContextHolder tdbb(user_status, this, FB_FUNCTION);
check_database(tdbb);
try
{
state = cursor->fetchAbsolute(tdbb, static_cast<UCHAR*>(buffer), position);
}
catch (const Exception& ex)
{
transliterateException(tdbb, ex, user_status, "JResultSet::fetchAbsolute");
return IStatus::FB_ERROR;
}
trace_warning(tdbb, user_status, "JResultSet::fetchAbsolute");
}
catch (const Exception& ex)
{
@ -4701,15 +4753,28 @@ int JResultSet::fetchAbsolute(CheckStatusWrapper* user_status, unsigned position
}
successful_completion(user_status);
return IStatus::FB_OK;
return (state == 0) ? IStatus::FB_OK : IStatus::FB_NO_DATA;
}
int JResultSet::fetchRelative(CheckStatusWrapper* user_status, int offset, void* buffer)
{
try
{
status_exception::raise(Arg::Gds(isc_wish_list));
EngineContextHolder tdbb(user_status, this, FB_FUNCTION);
check_database(tdbb);
try
{
state = cursor->fetchRelative(tdbb, static_cast<UCHAR*>(buffer), offset);
}
catch (const Exception& ex)
{
transliterateException(tdbb, ex, user_status, "JResultSet::fetchRelative");
return IStatus::FB_ERROR;
}
trace_warning(tdbb, user_status, "JResultSet::fetchRelative");
}
catch (const Exception& ex)
{
@ -4718,26 +4783,37 @@ int JResultSet::fetchRelative(CheckStatusWrapper* user_status, int offset, void*
}
successful_completion(user_status);
return IStatus::FB_OK;
return (state == 0) ? IStatus::FB_OK : IStatus::FB_NO_DATA;
}
FB_BOOLEAN JResultSet::isEof(CheckStatusWrapper* user_status)
{
return (state > 0);
}
FB_BOOLEAN JResultSet::isBof(CheckStatusWrapper* user_status)
{
return (state < 0);
}
int JResultSet::release()
{
if (--refCounter != 0)
return 1;
if (statement)
if (cursor)
{
LocalStatus status;
CheckStatusWrapper statusWrapper(&status);
freeEngineData(&statusWrapper);
}
if (!statement)
{
if (!cursor)
delete this;
}
return 0;
}
@ -4752,8 +4828,8 @@ void JResultSet::freeEngineData(CheckStatusWrapper* user_status)
try
{
DSQL_free_statement(tdbb, getHandle(), DSQL_close);
statement = NULL;
DsqlCursor::close(tdbb, cursor);
cursor = NULL;
}
catch (const Exception& ex)
{
@ -4771,33 +4847,9 @@ void JResultSet::freeEngineData(CheckStatusWrapper* user_status)
}
FB_BOOLEAN JResultSet::isEof(CheckStatusWrapper* user_status)
{
return eof ? FB_TRUE : FB_FALSE;
}
FB_BOOLEAN JResultSet::isBof(CheckStatusWrapper* user_status)
{
try
{
status_exception::raise(Arg::Gds(isc_wish_list));
}
catch (const Exception& ex)
{
ex.stuffException(user_status);
return FB_FALSE;
}
successful_completion(user_status);
return FB_TRUE;
}
IMessageMetadata* JResultSet::getMetadata(CheckStatusWrapper* user_status)
{
return statement->getOutputMetadata(user_status);
return NULL;//statement->getOutputMetadata(user_status);
}
@ -5122,9 +5174,11 @@ void JResultSet::setDelayedOutputFormat(CheckStatusWrapper* user_status, Firebir
try
{
/*
dsql_req* req = getStatement()->getHandle();
fb_assert(req);
req->setDelayedFormat(tdbb, outMetadata);
*/
}
catch (const Exception& ex)
{
@ -6297,7 +6351,7 @@ static void release_attachment(thread_db* tdbb, Jrd::Attachment* attachment)
dbb->dbb_event_mgr->deleteSession(attachment->att_event_session);
// CMP_release() changes att_requests.
while (!attachment->att_requests.isEmpty())
while (attachment->att_requests.hasData())
CMP_release(tdbb, attachment->att_requests.back());
MET_clear_cache(tdbb);

View File

@ -748,7 +748,7 @@ void TRA_invalidate(thread_db* tdbb, ULONG mask)
}
void TRA_link_cursor(jrd_tra* transaction, dsql_req* cursor)
void TRA_link_cursor(jrd_tra* transaction, DsqlCursor* cursor)
{
/**************************************
*
@ -766,7 +766,7 @@ void TRA_link_cursor(jrd_tra* transaction, dsql_req* cursor)
}
void TRA_unlink_cursor(jrd_tra* transaction, dsql_req* cursor)
void TRA_unlink_cursor(jrd_tra* transaction, DsqlCursor* cursor)
{
/**************************************
*
@ -781,9 +781,7 @@ void TRA_unlink_cursor(jrd_tra* transaction, dsql_req* cursor)
FB_SIZE_T pos;
if (transaction->tra_open_cursors.find(cursor, pos))
{
transaction->tra_open_cursors.remove(pos);
}
}
@ -1217,10 +1215,8 @@ void TRA_release_transaction(thread_db* tdbb, jrd_tra* transaction, Jrd::TraceTr
// Close all open DSQL cursors
while (transaction->tra_open_cursors.getCount())
{
DSQL_free_statement(tdbb, transaction->tra_open_cursors.pop(), DSQL_close);
}
while (transaction->tra_open_cursors.hasData())
DsqlCursor::close(tdbb, transaction->tra_open_cursors.pop());
// Release the transaction and its pool

View File

@ -278,7 +278,7 @@ public:
jrd_req* tra_requests; // Doubly linked list of requests active in this transaction
MonitoringSnapshot* tra_mon_snapshot; // Database state snapshot (for monitoring purposes)
RuntimeStatistics tra_stats;
Firebird::Array<dsql_req*> tra_open_cursors;
Firebird::Array<DsqlCursor*> tra_open_cursors;
bool tra_in_use; // transaction in use (can't be committed or rolled back)
jrd_tra* const tra_outer; // outer transaction of an autonomous transaction
CallerName tra_caller_name; // caller object name

View File

@ -45,8 +45,8 @@ void TRA_header_write(Jrd::thread_db* tdbb, Jrd::Database* dbb, TraNumber number
#endif
void TRA_init(Jrd::Attachment*);
void TRA_invalidate(Jrd::thread_db* tdbb, ULONG);
void TRA_link_cursor(Jrd::jrd_tra*, Jrd::dsql_req*);
void TRA_unlink_cursor(Jrd::jrd_tra*, Jrd::dsql_req*);
void TRA_link_cursor(Jrd::jrd_tra*, Jrd::DsqlCursor*);
void TRA_unlink_cursor(Jrd::jrd_tra*, Jrd::DsqlCursor*);
void TRA_post_resources(Jrd::thread_db* tdbb, Jrd::jrd_tra*, Jrd::ResourceList&);
bool TRA_pc_active(Jrd::thread_db*, TraNumber);
bool TRA_precommited(Jrd::thread_db* tdbb, TraNumber old_number, TraNumber new_number);

View File

@ -253,7 +253,7 @@ public:
int fetchPrior(CheckStatusWrapper* status, void* message);
int fetchFirst(CheckStatusWrapper* status, void* message);
int fetchLast(CheckStatusWrapper* status, void* message);
int fetchAbsolute(CheckStatusWrapper* status, unsigned int position, void* message);
int fetchAbsolute(CheckStatusWrapper* status, int position, void* message);
int fetchRelative(CheckStatusWrapper* status, int offset, void* message);
FB_BOOLEAN isEof(CheckStatusWrapper* status);
FB_BOOLEAN isBof(CheckStatusWrapper* status);
@ -311,7 +311,8 @@ public:
IMessageMetadata* inMetadata, void* inBuffer,
IMessageMetadata* outMetadata, void* outBuffer);
ResultSet* openCursor(CheckStatusWrapper* status, ITransaction* tra,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outFormat);
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outFormat,
unsigned int flags);
void setCursorName(CheckStatusWrapper* status, const char* name);
void free(CheckStatusWrapper* status);
unsigned getFlags(CheckStatusWrapper* status);
@ -486,7 +487,7 @@ public:
Firebird::IResultSet* openCursor(CheckStatusWrapper* status, ITransaction* transaction,
unsigned int stmtLength, const char* sqlStmt, unsigned dialect,
IMessageMetadata* inMetadata, void* inBuffer, Firebird::IMessageMetadata* outMetadata,
const char* cursorName);
const char* cursorName, unsigned int cursorFlags);
Firebird::IEvents* queEvents(CheckStatusWrapper* status, Firebird::IEventCallback* callback,
unsigned int length, const unsigned char* events);
void cancelOperation(CheckStatusWrapper* status, int option);
@ -1850,7 +1851,7 @@ Firebird::ITransaction* Statement::execute(CheckStatusWrapper* status, Firebird:
ResultSet* Statement::openCursor(CheckStatusWrapper* status, Firebird::ITransaction* apiTra,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outFormat)
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outFormat, unsigned int flags)
{
/**************************************
*
@ -1986,7 +1987,7 @@ ResultSet* Statement::openCursor(CheckStatusWrapper* status, Firebird::ITransact
IResultSet* Attachment::openCursor(CheckStatusWrapper* status, ITransaction* transaction,
unsigned int stmtLength, const char* sqlStmt, unsigned dialect,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata,
const char* cursorName)
const char* cursorName, unsigned int cursorFlags)
{
Statement* stmt = prepare(status, transaction, stmtLength, sqlStmt, dialect,
(outMetadata ? 0 : IStatement::PREPARE_PREFETCH_OUTPUT_PARAMETERS));
@ -1995,7 +1996,7 @@ IResultSet* Attachment::openCursor(CheckStatusWrapper* status, ITransaction* tra
return NULL;
}
ResultSet* rc = stmt->openCursor(status, transaction, inMetadata, inBuffer, outMetadata);
ResultSet* rc = stmt->openCursor(status, transaction, inMetadata, inBuffer, outMetadata, cursorFlags);
if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
{
stmt->release();
@ -2934,7 +2935,7 @@ int ResultSet::fetchNext(CheckStatusWrapper* status, void* buffer)
//statement->rsr_flags.clear(Rsr::EOF_SET);
statement->rsr_flags.set(Rsr::PAST_EOF);
return IStatus::FB_EOF;
return IStatus::FB_NO_DATA;
}
if (statement->rsr_flags.test(Rsr::STREAM_ERR))
@ -3030,7 +3031,7 @@ int ResultSet::fetchLast(CheckStatusWrapper* user_status, void* buffer)
}
int ResultSet::fetchAbsolute(CheckStatusWrapper* user_status, unsigned position, void* buffer)
int ResultSet::fetchAbsolute(CheckStatusWrapper* user_status, int position, void* buffer)
{
try
{
@ -3384,7 +3385,7 @@ int Blob::getSegment(CheckStatusWrapper* status, unsigned int bufferLength, void
{
if (segmentLength)
*segmentLength = length;
return IStatus::FB_EOF;
return IStatus::FB_NO_DATA;
}
// Here's the loop, passing out data from our basket & refilling it.
@ -3462,7 +3463,7 @@ int Blob::getSegment(CheckStatusWrapper* status, unsigned int bufferLength, void
if (blob->rbl_flags & Rbl::EOF_PENDING)
{
blob->rbl_flags |= Rbl::EOF_SET;
code = IStatus::FB_EOF;
code = IStatus::FB_NO_DATA;
break;
}

View File

@ -3201,7 +3201,8 @@ ISC_STATUS rem_port::execute_statement(P_OP op, P_SQLDATA* sqldata, PACKET* send
statement->rsr_cursor =
statement->rsr_iface->openCursor(&status_vector, tra,
iMsgBuffer.metadata, iMsgBuffer.buffer,
(out_blr_length ? oMsgBuffer.metadata : DELAYED_OUT_FORMAT));
(out_blr_length ? oMsgBuffer.metadata : DELAYED_OUT_FORMAT),
0);
if (!(status_vector.getStatus() & Firebird::IStatus::FB_HAS_ERRORS))
{
transaction->rtr_cursors.add(statement);
@ -3558,9 +3559,9 @@ ISC_STATUS rem_port::get_segment(P_SGMT* segment, PACKET* sendL)
p += 2;
unsigned length;
int cc = blob->rbl_iface->getSegment(&status_vector, buffer_length, p, &length);
if (cc == IStatus::FB_EOF || cc == IStatus::FB_ERROR)
if (cc == IStatus::FB_NO_DATA || cc == IStatus::FB_ERROR)
{
if (cc == IStatus::FB_EOF)
if (cc == IStatus::FB_NO_DATA)
state = 2;
p -= 2;
break;

View File

@ -307,7 +307,7 @@ public:
int fetchPrior(Firebird::CheckStatusWrapper* status, void* message);
int fetchFirst(Firebird::CheckStatusWrapper* status, void* message);
int fetchLast(Firebird::CheckStatusWrapper* status, void* message);
int fetchAbsolute(Firebird::CheckStatusWrapper* status, unsigned int position, void* message);
int fetchAbsolute(Firebird::CheckStatusWrapper* status, int position, void* message);
int fetchRelative(Firebird::CheckStatusWrapper* status, int offset, void* message);
FB_BOOLEAN isEof(Firebird::CheckStatusWrapper* status);
FB_BOOLEAN isBof(Firebird::CheckStatusWrapper* status);
@ -359,7 +359,8 @@ public:
Firebird::IMessageMetadata* inMetadata, void* inBuffer,
Firebird::IMessageMetadata* outMetadata, void* outBuffer);
Firebird::IResultSet* openCursor(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction,
Firebird::IMessageMetadata* inMetadata, void* inBuffer, Firebird::IMessageMetadata* outMetadata);
Firebird::IMessageMetadata* inMetadata, void* inBuffer, Firebird::IMessageMetadata* outMetadata,
unsigned int flags);
void setCursorName(Firebird::CheckStatusWrapper* status, const char* name);
void free(Firebird::CheckStatusWrapper* status);
unsigned getFlags(Firebird::CheckStatusWrapper* status);
@ -439,7 +440,7 @@ public:
Firebird::IResultSet* openCursor(Firebird::CheckStatusWrapper* status, Firebird::ITransaction* transaction,
unsigned int stmtLength, const char* sqlStmt, unsigned int dialect,
Firebird::IMessageMetadata* inMetadata, void* inBuffer, Firebird::IMessageMetadata* outMetadata,
const char* cursorName);
const char* cursorName, unsigned int cursorFlags);
YEvents* queEvents(Firebird::CheckStatusWrapper* status, Firebird::IEventCallback* callback,
unsigned int length, const unsigned char* eventsData);
void cancelOperation(Firebird::CheckStatusWrapper* status, int option);

View File

@ -257,7 +257,7 @@ void dump(CheckStatusWrapper* status, ISC_QUAD* blobId, IAttachment* att, ITrans
switch (blob->getSegment(status, short_length, buffer, &l))
{
case Firebird::IStatus::FB_ERROR:
case Firebird::IStatus::FB_EOF:
case Firebird::IStatus::FB_NO_DATA:
break;
}

View File

@ -1317,7 +1317,7 @@ namespace {
// Transaction is not optional for statement returning result set
RefPtr<YTransaction> transaction = translateHandle(transactions, traHandle);;
statement->openCursor(status, transaction, inMetadata, buffer, outMetadata);
statement->openCursor(status, transaction, inMetadata, buffer, outMetadata, 0);
if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
return;
@ -2938,7 +2938,7 @@ ISC_STATUS API_ROUTINE isc_get_segment(ISC_STATUS* userStatus, FB_API_HANDLE* bl
// Raise pseudo errors
switch (cc)
{
case IStatus::FB_EOF:
case IStatus::FB_NO_DATA:
Arg::Gds(isc_segstr_eof).raise();
break;
case IStatus::FB_SEGMENT:
@ -4310,7 +4310,7 @@ ITransaction* YStatement::execute(CheckStatusWrapper* status, ITransaction* tran
}
IResultSet* YStatement::openCursor(Firebird::CheckStatusWrapper* status, ITransaction* transaction,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata)
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata, unsigned int flags)
{
try
{
@ -4320,7 +4320,7 @@ IResultSet* YStatement::openCursor(Firebird::CheckStatusWrapper* status, ITransa
if (transaction)
attachment->getNextTransaction(status, transaction, trans);
IResultSet* rs = entry.next()->openCursor(status, trans, inMetadata, inBuffer, outMetadata);
IResultSet* rs = entry.next()->openCursor(status, trans, inMetadata, inBuffer, outMetadata, flags);
if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
{
return NULL;
@ -4498,7 +4498,7 @@ int YResultSet::fetchLast(CheckStatusWrapper* status, void* buffer)
return FB_FALSE;
}
int YResultSet::fetchAbsolute(CheckStatusWrapper* status, unsigned int position, void* buffer)
int YResultSet::fetchAbsolute(CheckStatusWrapper* status, int position, void* buffer)
{
try
{
@ -5138,7 +5138,7 @@ void YAttachment::executeDyn(CheckStatusWrapper* status, ITransaction* transacti
IResultSet* YAttachment::openCursor(CheckStatusWrapper* status, ITransaction* transaction,
unsigned int length, const char* string, unsigned int dialect,
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetadata,
const char* cursorName)
const char* cursorName, unsigned int cursorFlags)
{
IResultSet* rs = NULL;
try
@ -5150,7 +5150,7 @@ IResultSet* YAttachment::openCursor(CheckStatusWrapper* status, ITransaction* tr
getNextTransaction(status, transaction, trans);
rs = entry.next()->openCursor(status, trans, length, string, dialect,
inMetadata, inBuffer, outMetadata, cursorName);
inMetadata, inBuffer, outMetadata, cursorName, cursorFlags);
if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
{
return NULL;