2424#include " ../jrd/align.h"
2525#include " ../jrd/jrd.h"
2626#include " ../jrd/req.h"
27+ #include " ../jrd/tra.h"
2728#include " ../dsql/StmtNodes.h"
2829#include " ../jrd/optimizer/Optimizer.h"
2930#include " ../jrd/dpm_proto.h"
@@ -61,6 +62,9 @@ void LocalTableStream::internalOpen(thread_db* tdbb) const
6162
6263 const auto rpb = &request->req_rpb [m_stream];
6364 rpb->getWindow (tdbb).win_flags = 0 ;
65+ rpb->rpb_number .setValue (BOF_NUMBER );
66+
67+ impure->cursorSavepoint = 0 ;
6468
6569 const auto localTableRequest = impure->localTableRequest = request->getLocalTableRequest (m_outerDecl);
6670
@@ -72,22 +76,16 @@ void LocalTableStream::internalOpen(thread_db* tdbb) const
7276
7377 rpb->rpb_relation = m_table->getRelation (tdbb, localTableRequest);
7478 rpb->rpb_temp_instance_id = tempInstanceId;
75- }
76-
77- rpb->rpb_number .setValue (BOF_NUMBER );
7879
79- // Inside an autonomous transaction block, reading a DLTT uses the parent transaction.
80- // The parent's top savepoint already holds a verb action for this relation (from the
81- // INSERT that made the data visible), so get_undo_data returns udForceBack, hiding
82- // all freshly-inserted rows. Bypass cursor stability for this case only — non-autonomous
83- // reads must keep cursor stability so that INSERT...SELECT from the same DLTT does not
84- // recurse into rows inserted by the current statement.
85- if (m_table->useLtt )
86- {
8780 if (localTableRequest->req_auto_trans .hasData ())
88- rpb->rpb_stream_flags |= RPB_s_unstable;
89- else
90- rpb->rpb_stream_flags &= ~RPB_s_unstable;
81+ {
82+ const auto transaction = localTableRequest->getLocalTableTransaction ();
83+
84+ // Keep rows inserted after this stream was opened out of the scan while
85+ // retaining visibility of rows inserted before the autonomous block.
86+ if (!(transaction->tra_flags & TRA_system) && transaction->tra_save_point )
87+ impure->cursorSavepoint = transaction->startSavepoint ()->getNumber ();
88+ }
9189 }
9290}
9391
@@ -101,6 +99,20 @@ void LocalTableStream::close(thread_db* tdbb) const
10199
102100 if (impure->irsb_flags & irsb_open)
103101 impure->irsb_flags &= ~irsb_open;
102+
103+ if (impure->cursorSavepoint )
104+ {
105+ const auto transaction = impure->localTableRequest ->getLocalTableTransaction ();
106+
107+ while (transaction->tra_save_point &&
108+ transaction->tra_save_point ->getNumber () >= impure->cursorSavepoint )
109+ {
110+ fb_assert (!transaction->tra_save_point ->isChanging ());
111+ transaction->releaseSavepoint (tdbb);
112+ }
113+
114+ impure->cursorSavepoint = 0 ;
115+ }
104116}
105117
106118bool LocalTableStream::internalGetRecord (thread_db* tdbb) const
0 commit comments