Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions src/dsql/DsqlRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,19 +596,28 @@ void DsqlDmlRequest::doExecute(thread_db* tdbb, jrd_tra** traHandle,

// if this is a singleton select that return some data, make sure there's in fact one record

if (singleton && (request->req_flags & req_active) && outMsgLength > 0)
if (singleton)
{
// Create a temp message buffer and try one more receive.
// If it succeed then the next record exists.
if (outMsgLength > 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why there is check for outMsgLength > 0 - is it possible to be false when singleton == true ?
Even if out message with zero length is possible (???), what should happens for the singleton && outMsgLength == 0 case ?
This place is very unclear for me.
In v5 there was just check for singleton == true, btw

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case. If the function was called with outMetadata == nullptr - just assume success. The difference from v5 is that buffers here are provided by application rather than of engine itself.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have singleton == true && outMetadata == nullptr ?
In any case, why two nested if here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially check for request's activity was out of inner if. Then I realized that some BLR code can intentionally run to the end without entering blr_send and an application aware of it can provide no output buffer.

If you are sure that I'm wrong feel free to change this piece later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure that this code is not clear. And you changed it this way.
Formally,

if (a) {
  if (b) {
...
  }
}

is the same as

if (a && b) {
...
}

thus I ask why you choose first one. If there is no real reason, change it.
If there is a reasons - provide it, and put in comments to avoid similar misunderstanding for the future readers.

{
// No record returned though expected
if (!(request->req_flags & req_active))
{
status_exception::raise(Arg::Gds(isc_stream_eof));
}

std::unique_ptr<UCHAR[]> message_buffer(new UCHAR[outMsgLength]);
// Create a temp message buffer and try one more receive.
// If it succeed then the next record exists.

JRD_receive(tdbb, request, message->msg_number, outMsgLength, message_buffer.get());
HalfStaticArray<UCHAR, BUFFER_SMALL> message_buffer(getPool(), outMsgLength);

// Still active request means that second record exists
if ((request->req_flags & req_active))
{
status_exception::raise(Arg::Gds(isc_sing_select_err));
JRD_receive(tdbb, request, message->msg_number, outMsgLength, message_buffer.getBuffer(outMsgLength, false));

// Still active request means that second record exists
if ((request->req_flags & req_active))
{
status_exception::raise(Arg::Gds(isc_sing_select_err));
}
}
}
}
Expand Down
Loading