diff --git a/src/dsql/DsqlCursor.cpp b/src/dsql/DsqlCursor.cpp index 4c3fef675a..dcb040aa48 100644 --- a/src/dsql/DsqlCursor.cpp +++ b/src/dsql/DsqlCursor.cpp @@ -34,10 +34,10 @@ static const char* const SCRATCH = "fb_cursor_"; static const ULONG PREFETCH_SIZE = 65536; // 64 KB DsqlCursor::DsqlCursor(dsql_req* req, ULONG flags) - : m_request(req), m_resultSet(NULL), m_flags(flags), + : m_request(req), m_message(req->getStatement()->getReceiveMsg()), + m_resultSet(NULL), 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) + m_state(BOS), m_eof(false), m_position(0), m_cachedCount(0) { TRA_link_cursor(m_request->req_transaction, this); } @@ -232,9 +232,14 @@ int DsqlCursor::fetchFromCache(thread_db* tdbb, UCHAR* buffer, FB_UINT64 positio 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); + UCHAR* const msgBuffer = m_request->req_msg_buffers[m_message->msg_buffer_number]; + + const FB_UINT64 offset = position * m_message->msg_length; + const FB_UINT64 readBytes = m_space.read(offset, msgBuffer, m_message->msg_length); + fb_assert(readBytes == m_message->msg_length); + + m_request->mapInOut(tdbb, true, m_message, NULL, buffer); + m_position = position; m_state = POSITIONED; return 0; @@ -244,34 +249,23 @@ 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); + const ULONG prefetchCount = MAX(PREFETCH_SIZE / m_message->msg_length, 1); + const UCHAR* const msgBuffer = m_request->req_msg_buffers[m_message->msg_buffer_number]; while (position >= m_cachedCount) { - ULONG count = 0; - - for (; count < prefetchCount; count++) + for (ULONG count = 0; count < prefetchCount; count++) { - UCHAR* const ptr = buffer + count * m_messageSize; - - if (!m_request->fetch(tdbb, ptr)) + if (!m_request->fetch(tdbb, NULL)) { 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; + const FB_UINT64 offset = m_cachedCount * m_message->msg_length; + const FB_UINT64 writtenBytes = m_space.write(offset, msgBuffer, m_message->msg_length); + fb_assert(writtenBytes == m_message->msg_length); + m_cachedCount++; } if (m_eof) diff --git a/src/dsql/DsqlCursor.h b/src/dsql/DsqlCursor.h index 04824ffa5b..864a8b3817 100644 --- a/src/dsql/DsqlCursor.h +++ b/src/dsql/DsqlCursor.h @@ -66,6 +66,7 @@ private: bool cacheInput(thread_db* tdbb, FB_UINT64 position = MAX_UINT64); dsql_req* const m_request; + const dsql_msg* const m_message; JResultSet* m_resultSet; const ULONG m_flags; TempSpace m_space; @@ -73,7 +74,6 @@ private: bool m_eof; FB_UINT64 m_position; FB_UINT64 m_cachedCount; - ULONG m_messageSize; }; } // namespace diff --git a/src/dsql/dsql.cpp b/src/dsql/dsql.cpp index 9254249133..f13d1467ae 100644 --- a/src/dsql/dsql.cpp +++ b/src/dsql/dsql.cpp @@ -80,9 +80,6 @@ using namespace Firebird; 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(Jrd::thread_db*, dsql_req*, bool, const dsql_msg*, IMessageMetadata*, UCHAR*, - const UCHAR* = NULL); -static USHORT parse_metadata(dsql_req*, IMessageMetadata*, const Array&); static dsql_req* prepareRequest(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, bool); static dsql_req* prepareStatement(thread_db*, dsql_dbb*, jrd_tra*, ULONG, const TEXT*, USHORT, bool); static UCHAR* put_item(UCHAR, const USHORT, const UCHAR*, UCHAR*, const UCHAR* const); @@ -272,6 +269,12 @@ bool DsqlDmlRequest::fetch(thread_db* tdbb, UCHAR* msgBuffer) dsql_msg* message = (dsql_msg*) statement->getReceiveMsg(); + if (delayedFormat && message) + { + parseMetadata(delayedFormat, message->msg_parameters); + delayedFormat = NULL; + } + // Set up things for tracing this call Jrd::Attachment* att = req_dbb->dbb_attachment; TraceDSQLFetch trace(att, this); @@ -285,13 +288,12 @@ bool DsqlDmlRequest::fetch(thread_db* tdbb, UCHAR* msgBuffer) if (eofReached) { - delayedFormat = NULL; trace.fetch(true, ITracePlugin::RESULT_SUCCESS); return false; } - map_in_out(tdbb, this, true, message, delayedFormat, msgBuffer); - delayedFormat = NULL; + if (msgBuffer) + mapInOut(tdbb, true, message, NULL, msgBuffer); trace.fetch(false, ITracePlugin::RESULT_SUCCESS); return true; @@ -679,9 +681,9 @@ void DsqlDmlRequest::execute(thread_db* tdbb, jrd_tra** traHandle, const dsql_msg* message = statement->getSendMsg(); if (message) - map_in_out(tdbb, this, false, message, inMetadata, NULL, inMsg); + mapInOut(tdbb, false, message, inMetadata, NULL, inMsg); - // we need to map_in_out before tracing of execution start to let trace + // we need to mapInOut before tracing of execution start to let trace // manager know statement parameters values TraceDSQLExecute trace(req_dbb->dbb_attachment, this); @@ -713,7 +715,7 @@ void DsqlDmlRequest::execute(thread_db* tdbb, jrd_tra** traHandle, } if (outMetadata && message) - parse_metadata(this, outMetadata, message->msg_parameters); + parseMetadata(outMetadata, message->msg_parameters); if ((outMsg && message) || isBlock) { @@ -736,7 +738,7 @@ void DsqlDmlRequest::execute(thread_db* tdbb, jrd_tra** traHandle, JRD_receive(tdbb, req_request, message->msg_number, message->msg_length, msgBuffer); if (outMsg) - map_in_out(tdbb, this, true, message, NULL, outMsg); + mapInOut(tdbb, true, message, NULL, outMsg); // if this is a singleton select, make sure there's in fact one record @@ -989,13 +991,12 @@ static dsql_dbb* init(thread_db* tdbb, Jrd::Attachment* attachment) /** - map_in_out + mapInOut @brief Map data from external world into message or from message to external world. - @param request @param toExternal @param message @param meta @@ -1003,10 +1004,10 @@ static dsql_dbb* init(thread_db* tdbb, Jrd::Attachment* attachment) @param in_dsql_msg_buf **/ -static void map_in_out(thread_db* tdbb, dsql_req* request, bool toExternal, const dsql_msg* message, +void dsql_req::mapInOut(thread_db* tdbb, bool toExternal, const dsql_msg* message, IMessageMetadata* meta, UCHAR* dsql_msg_buf, const UCHAR* in_dsql_msg_buf) { - USHORT count = parse_metadata(request, meta, message->msg_parameters); + USHORT count = parseMetadata(meta, message->msg_parameters); // Sanity check @@ -1041,7 +1042,7 @@ static void map_in_out(thread_db* tdbb, dsql_req* request, bool toExternal, cons // Make sure the message given to us is long enough dsc desc; - if (!request->req_user_descs.get(parameter, desc)) + if (!req_user_descs.get(parameter, desc)) desc.clear(); /*** @@ -1059,14 +1060,14 @@ static void map_in_out(thread_db* tdbb, dsql_req* request, bool toExternal, cons Arg::Gds(isc_dsql_sqlvar_index) << Arg::Num(parameter->par_index-1)); } - UCHAR* msgBuffer = request->req_msg_buffers[parameter->par_message->msg_buffer_number]; + UCHAR* msgBuffer = req_msg_buffers[parameter->par_message->msg_buffer_number]; SSHORT* flag = NULL; dsql_par* const null_ind = parameter->par_null; if (null_ind != NULL) { dsc userNullDesc; - if (!request->req_user_descs.get(null_ind, userNullDesc)) + if (!req_user_descs.get(null_ind, userNullDesc)) userNullDesc.clear(); const ULONG null_offset = (IPTR) userNullDesc.dsc_address; @@ -1129,7 +1130,7 @@ static void map_in_out(thread_db* tdbb, dsql_req* request, bool toExternal, cons Arg::Gds(isc_dsql_wrong_param_num) << Arg::Num(count) <getStatement(); + const DsqlCompiledStatement* statement = getStatement(); const dsql_par* parameter; const dsql_par* dbkey; @@ -1138,7 +1139,7 @@ static void map_in_out(thread_db* tdbb, dsql_req* request, bool toExternal, cons { UCHAR* parentMsgBuffer = statement->getParentRequest() ? statement->getParentRequest()->req_msg_buffers[dbkey->par_message->msg_buffer_number] : NULL; - UCHAR* msgBuffer = request->req_msg_buffers[parameter->par_message->msg_buffer_number]; + UCHAR* msgBuffer = req_msg_buffers[parameter->par_message->msg_buffer_number]; fb_assert(parentMsgBuffer); @@ -1168,7 +1169,7 @@ static void map_in_out(thread_db* tdbb, dsql_req* request, bool toExternal, cons UCHAR* parentMsgBuffer = statement->getParentRequest() ? statement->getParentRequest()->req_msg_buffers[rec_version->par_message->msg_buffer_number] : NULL; - UCHAR* msgBuffer = request->req_msg_buffers[parameter->par_message->msg_buffer_number]; + UCHAR* msgBuffer = req_msg_buffers[parameter->par_message->msg_buffer_number]; fb_assert(parentMsgBuffer); @@ -1195,18 +1196,16 @@ static void map_in_out(thread_db* tdbb, dsql_req* request, bool toExternal, cons /** - parse_metadata + parseMetadata @brief Parse the message of a request. - @param request @param meta @param parameters_list **/ -static USHORT parse_metadata(dsql_req* request, IMessageMetadata* meta, - const Array& parameters_list) +USHORT dsql_req::parseMetadata(IMessageMetadata* meta, const Array& parameters_list) { HalfStaticArray parameters; @@ -1280,7 +1279,7 @@ static USHORT parse_metadata(dsql_req* request, IMessageMetadata* meta, if (desc.isText() && desc.getTextType() == ttype_dynamic) desc.setTextType(ttype_none); - request->req_user_descs.put(parameter, desc); + req_user_descs.put(parameter, desc); dsql_par* null = parameter->par_null; if (null) @@ -1291,7 +1290,7 @@ static USHORT parse_metadata(dsql_req* request, IMessageMetadata* meta, desc.dsc_length = sizeof(SSHORT); desc.dsc_address = (UCHAR*)(IPTR) nullOffset; - request->req_user_descs.put(null, desc); + req_user_descs.put(null, desc); } } diff --git a/src/dsql/dsql.h b/src/dsql/dsql.h index a5f359f33d..401d89195d 100644 --- a/src/dsql/dsql.h +++ b/src/dsql/dsql.h @@ -573,6 +573,10 @@ public: virtual void setDelayedFormat(thread_db* tdbb, Firebird::IMessageMetadata* metadata); + USHORT parseMetadata(Firebird::IMessageMetadata* meta, const Firebird::Array& parameters_list); + void mapInOut(Jrd::thread_db* tdbb, bool toExternal, const dsql_msg* message, Firebird::IMessageMetadata* meta, + UCHAR* dsql_msg_buf, const UCHAR* in_dsql_msg_buf = NULL); + static void destroy(thread_db* tdbb, dsql_req* request, bool drop); private: