Skip to content

Commit 09af145

Browse files
committed
Adapt Batch and Cursor, clean unused now routines out
1 parent 1168eb2 commit 09af145

File tree

6 files changed

+87
-354
lines changed

6 files changed

+87
-354
lines changed

src/dsql/DsqlBatch.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ DsqlBatch* DsqlBatch::open(thread_db* tdbb, DsqlDmlRequest* req, IMessageMetadat
224224
}
225225

226226
const dsql_msg* message = statement->getSendMsg();
227-
if (! (inMetadata && message && req->parseMetadata(inMetadata, message->msg_parameters)))
227+
if (! (inMetadata && message && message->msg_parameter > 0))
228228
{
229229
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
230230
Arg::Gds(isc_batch_param));
@@ -654,18 +654,22 @@ Firebird::IBatchCompletionState* DsqlBatch::execute(thread_db* tdbb)
654654
// execute request
655655
m_dsqlRequest->req_transaction = transaction;
656656
Request* req = m_dsqlRequest->getRequest();
657+
DsqlStatement* dStmt = m_dsqlRequest->getDsqlStatement();
657658
fb_assert(req);
658659

659660
// prepare completion interface
660661
AutoPtr<BatchCompletionState, SimpleDispose> completionState
661662
(FB_NEW BatchCompletionState(m_flags & (1 << IBatch::TAG_RECORD_COUNTS), m_detailed));
662663
AutoSetRestore<bool> batchFlag(&req->req_batch_mode, true);
663-
const dsql_msg* message = m_dsqlRequest->getDsqlStatement()->getSendMsg();
664+
const dsql_msg* sendMessage = dStmt->getSendMsg();
665+
MessageNode* message = dStmt->getStatement()->messages[sendMessage->msg_number];
666+
// map message to internal engine format
667+
// Do it one time only to avoid parsing its metadata for every message
668+
m_dsqlRequest->metadataToFormat(m_meta, message);
664669
bool startRequest = true;
665670

666-
bool isExecBlock = m_dsqlRequest->getDsqlStatement()->getType() == DsqlStatement::TYPE_EXEC_BLOCK;
667-
const auto receiveMessage = isExecBlock ? m_dsqlRequest->getDsqlStatement()->getReceiveMsg() : nullptr;
668-
auto receiveMsgBuffer = isExecBlock ? m_dsqlRequest->req_msg_buffers[receiveMessage->msg_buffer_number] : nullptr;
671+
bool isExecBlock = dStmt->getType() == DsqlStatement::TYPE_EXEC_BLOCK;
672+
const dsql_msg* receiveMessage = isExecBlock ? dStmt->getReceiveMsg() : nullptr;
669673

670674
// process messages
671675
ULONG remains;
@@ -721,25 +725,18 @@ Firebird::IBatchCompletionState* DsqlBatch::execute(thread_db* tdbb)
721725
*id = newId;
722726
}
723727

724-
// map message to internal engine format
725-
// pass m_meta one time only to avoid parsing its metadata for every message
726-
m_dsqlRequest->mapInOut(tdbb, false, message, start ? m_meta : nullptr, nullptr, data);
727-
data += m_messageSize;
728-
remains -= m_messageSize;
729-
730-
UCHAR* msgBuffer = m_dsqlRequest->req_msg_buffers[message->msg_buffer_number];
731728
try
732729
{
733730
// runsend data to request and collect stats
734731
ULONG before = req->req_records_inserted + req->req_records_updated +
735732
req->req_records_deleted;
736-
EXE_send(tdbb, req, message->msg_number, message->msg_length, msgBuffer);
733+
EXE_send(tdbb, req, sendMessage->msg_number, m_messageSize, data);
737734
ULONG after = req->req_records_inserted + req->req_records_updated +
738735
req->req_records_deleted;
739736
completionState->regUpdate(after - before);
740737

741738
if (isExecBlock)
742-
EXE_receive(tdbb, req, receiveMessage->msg_number, receiveMessage->msg_length, receiveMsgBuffer);
739+
EXE_receive(tdbb, req, receiveMessage->msg_number, receiveMessage->msg_length, nullptr); // We don't care about returned record
743740
}
744741
catch (const Exception& ex)
745742
{
@@ -761,6 +758,9 @@ Firebird::IBatchCompletionState* DsqlBatch::execute(thread_db* tdbb)
761758
}
762759
}
763760

761+
data += m_messageSize;
762+
remains -= m_messageSize;
763+
764764
UCHAR* alignedData = FB_ALIGN(data, m_alignment);
765765
m_messages.remained(remains, alignedData - data);
766766
}

src/dsql/DsqlCursor.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include "../dsql/dsql_proto.h"
3030
#include "../dsql/DsqlCursor.h"
31+
#include "../dsql/StmtNodes.h"
3132

3233
using namespace Firebird;
3334
using namespace Jrd;
@@ -36,7 +37,8 @@ static const char* const SCRATCH = "fb_cursor_";
3637
static const ULONG PREFETCH_SIZE = 65536; // 64 KB
3738

3839
DsqlCursor::DsqlCursor(DsqlDmlRequest* req, ULONG flags)
39-
: m_dsqlRequest(req), m_message(req->getDsqlStatement()->getReceiveMsg()),
40+
: m_dsqlRequest(req), m_message(req->getDsqlStatement()->getReceiveMsg()->msg_number),
41+
m_messageLength(0),
4042
m_resultSet(NULL), m_flags(flags),
4143
m_space(req->getPool(), SCRATCH),
4244
m_state(BOS), m_eof(false), m_position(0), m_cachedCount(0)
@@ -163,7 +165,7 @@ int DsqlCursor::fetchAbsolute(thread_db* tdbb, UCHAR* buffer, SLONG position)
163165
{
164166
if (!m_eof)
165167
{
166-
cacheInput(tdbb);
168+
cacheInput(tdbb, buffer);
167169
fb_assert(m_eof);
168170
}
169171

@@ -248,7 +250,7 @@ void DsqlCursor::getInfo(thread_db* tdbb,
248250
case IResultSet::INF_RECORD_COUNT:
249251
if (isScrollable && !m_eof)
250252
{
251-
cacheInput(tdbb);
253+
cacheInput(tdbb, nullptr);
252254
fb_assert(m_eof);
253255
}
254256
response.insertInt(tag, isScrollable ? m_cachedCount : -1);
@@ -291,48 +293,62 @@ int DsqlCursor::fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 positio
291293
{
292294
if (position >= m_cachedCount)
293295
{
294-
if (m_eof || !cacheInput(tdbb, position))
296+
if (m_eof || !cacheInput(tdbb, buffer, position))
295297
{
296298
m_state = EOS;
297299
return 1;
298300
}
299301
}
300302

301303
fb_assert(position < m_cachedCount);
304+
fb_assert(m_messageLength > 0); // At this point m_messageLength must be set by cacheInput
302305

303-
UCHAR* const msgBuffer = m_dsqlRequest->req_msg_buffers[m_message->msg_buffer_number];
304-
305-
const FB_UINT64 offset = position * m_message->msg_length;
306-
const FB_UINT64 readBytes = m_space.read(offset, msgBuffer, m_message->msg_length);
307-
fb_assert(readBytes == m_message->msg_length);
308-
309-
m_dsqlRequest->mapInOut(tdbb, true, m_message, NULL, buffer);
306+
const FB_UINT64 offset = position * m_messageLength;
307+
const FB_UINT64 readBytes = m_space.read(offset, buffer, m_messageLength);
308+
fb_assert(readBytes == m_messageLength);
310309

311310
m_position = position;
312311
m_state = POSITIONED;
313312
return 0;
314313
}
315314

316-
bool DsqlCursor::cacheInput(thread_db* tdbb, FB_UINT64 position)
315+
bool DsqlCursor::cacheInput(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position)
317316
{
318317
fb_assert(!m_eof);
319318

320-
const ULONG prefetchCount = MAX(PREFETCH_SIZE / m_message->msg_length, 1);
321-
const UCHAR* const msgBuffer = m_dsqlRequest->req_msg_buffers[m_message->msg_buffer_number];
319+
// It could not be done before: user buffer length may be unknown until call setDelayedOutputMetadata()
320+
if (m_messageLength == 0)
321+
{
322+
Request* req = m_dsqlRequest->getRequest();
323+
const MessageNode* msg = req->getStatement()->messages[m_message];
324+
m_messageLength = msg->getFormat(req)->fmt_length;
325+
}
326+
327+
std::unique_ptr<UCHAR[]> ownBuffer;
328+
if (buffer == nullptr)
329+
{
330+
// We are called from getInfo() and there is no user-provided buffer for data.
331+
// Create a temporary one.
332+
// This code cannot be moved into getInfo() itself because it is most likely called before fetch()
333+
// so m_messageLength is still unknown there.
334+
ownBuffer.reset(buffer = new UCHAR[m_messageLength]);
335+
}
336+
337+
const ULONG prefetchCount = MAX(PREFETCH_SIZE / m_messageLength, 1);
322338

323339
while (position >= m_cachedCount)
324340
{
325341
for (ULONG count = 0; count < prefetchCount; count++)
326342
{
327-
if (!m_dsqlRequest->fetch(tdbb, NULL))
343+
if (!m_dsqlRequest->fetch(tdbb, buffer))
328344
{
329345
m_eof = true;
330346
break;
331347
}
332348

333-
const FB_UINT64 offset = m_cachedCount * m_message->msg_length;
334-
const FB_UINT64 writtenBytes = m_space.write(offset, msgBuffer, m_message->msg_length);
335-
fb_assert(writtenBytes == m_message->msg_length);
349+
const FB_UINT64 offset = m_cachedCount * m_messageLength;
350+
const FB_UINT64 writtenBytes = m_space.write(offset, buffer, m_messageLength);
351+
fb_assert(writtenBytes == m_messageLength);
336352
m_cachedCount++;
337353
}
338354

src/dsql/DsqlCursor.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ class DsqlCursor
6767

6868
private:
6969
int fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position);
70-
bool cacheInput(thread_db* tdbb, FB_UINT64 position = MAX_UINT64);
70+
bool cacheInput(thread_db* tdbb, UCHAR* buffer, FB_UINT64 position = MAX_UINT64);
7171

7272
DsqlDmlRequest* const m_dsqlRequest;
73-
const dsql_msg* const m_message;
73+
const USHORT m_message;
74+
ULONG m_messageLength;
7475
JResultSet* m_resultSet;
7576
const ULONG m_flags;
7677
TempSpace m_space;

0 commit comments

Comments
 (0)