Skip to content

Commit 2b4ec44

Browse files
committed
Fix problems with autonomous transaction and DLTT - thanks Pavel Zotov
1 parent ba7ca6c commit 2b4ec44

2 files changed

Lines changed: 27 additions & 14 deletions

File tree

src/jrd/recsrc/LocalTableStream.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
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

106118
bool LocalTableStream::internalGetRecord(thread_db* tdbb) const

src/jrd/recsrc/RecordSource.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,7 @@ namespace Jrd
14701470
struct Impure : public RecordSource::Impure
14711471
{
14721472
Request* localTableRequest;
1473+
SavNumber cursorSavepoint;
14731474
};
14741475

14751476
private:

0 commit comments

Comments
 (0)