@@ -418,7 +418,7 @@ bool DsqlDmlRequest::fetch(thread_db* tdbb, UCHAR* msgBuffer)
418
418
// and outMetadata and outMsg in not used there, so passing NULL's is safe.
419
419
jrd_tra* tra = req_transaction;
420
420
421
- executeReceiveWithRestarts (tdbb, &tra, NULL , msgBuffer, false , false , true );
421
+ executeReceiveWithRestarts (tdbb, &tra, nullptr , nullptr , msgBuffer, false , false , true );
422
422
fb_assert (tra == req_transaction);
423
423
}
424
424
else
@@ -572,7 +572,7 @@ bool DsqlDmlRequest::needRestarts()
572
572
573
573
// Execute a dynamic SQL statement
574
574
void DsqlDmlRequest::doExecute (thread_db* tdbb, jrd_tra** traHandle,
575
- IMessageMetadata* outMetadata, UCHAR* outMsg,
575
+ const UCHAR* inMsg, IMessageMetadata* outMetadata, UCHAR* outMsg,
576
576
bool singleton)
577
577
{
578
578
firstRowFetched = false ;
@@ -584,9 +584,13 @@ void DsqlDmlRequest::doExecute(thread_db* tdbb, jrd_tra** traHandle,
584
584
}
585
585
else
586
586
{
587
- UCHAR* msgBuffer = req_msg_buffers[message->msg_buffer_number ];
587
+ MessageNode* msg = dsqlStatement->getStatement ()->messages [message->msg_number ];
588
+
589
+ fb_assert (msg != nullptr && inMsg != nullptr );
590
+
591
+ ULONG inMsgLength = msg->getFormat (request)->fmt_length ;
588
592
JRD_start_and_send (tdbb, request, req_transaction, message->msg_number ,
589
- message-> msg_length , msgBuffer );
593
+ inMsgLength, inMsg );
590
594
}
591
595
592
596
// Selectable execute block should get the "proc fetch" flag assigned,
@@ -682,7 +686,12 @@ void DsqlDmlRequest::execute(thread_db* tdbb, jrd_tra** traHandle,
682
686
const dsql_msg* message = dsqlStatement->getSendMsg ();
683
687
if (message)
684
688
{
685
- mapInOut (tdbb, false , message, inMetadata, NULL , inMsg);
689
+ // If this is not first call of execute(), metadata most likely is already converted to message
690
+ // but there is no easy way to check if they match so conversion is unconditional.
691
+ // Even if value of inMetadata is the same, other instance could be placed in the same memory.
692
+ // Even if the instance is the same, its content may be different from previous call.
693
+ MessageNode* msg = dsqlStatement->getStatement ()->messages [message->msg_number ];
694
+ metadataToFormat (inMetadata, msg);
686
695
}
687
696
688
697
// we need to mapInOut() before tracing of execution start to let trace
@@ -696,15 +705,16 @@ void DsqlDmlRequest::execute(thread_db* tdbb, jrd_tra** traHandle,
696
705
thread_db::TimerGuard timerGuard (tdbb, req_timer, !have_cursor);
697
706
698
707
if (needRestarts ())
699
- executeReceiveWithRestarts (tdbb, traHandle, outMetadata, outMsg, singleton, true , false );
708
+ executeReceiveWithRestarts (tdbb, traHandle, inMsg, outMetadata, outMsg, singleton, true , false );
700
709
else {
701
- doExecute (tdbb, traHandle, outMetadata, outMsg, singleton);
710
+ doExecute (tdbb, traHandle, inMsg, outMetadata, outMsg, singleton);
702
711
}
703
712
704
713
trace.finish (have_cursor, ITracePlugin::RESULT_SUCCESS);
705
714
}
706
715
707
716
void DsqlDmlRequest::executeReceiveWithRestarts (thread_db* tdbb, jrd_tra** traHandle,
717
+ const UCHAR* inMsg,
708
718
IMessageMetadata* outMetadata, UCHAR* outMsg,
709
719
bool singleton, bool exec, bool fetch)
710
720
{
@@ -724,7 +734,7 @@ void DsqlDmlRequest::executeReceiveWithRestarts(thread_db* tdbb, jrd_tra** traHa
724
734
try
725
735
{
726
736
if (exec)
727
- doExecute (tdbb, traHandle, outMetadata, outMsg, singleton);
737
+ doExecute (tdbb, traHandle, inMsg, outMetadata, outMsg, singleton);
728
738
729
739
if (fetch)
730
740
{
0 commit comments