Skip to content

Commit 00447a6

Browse files
committed
Rework fix for #8290: Unique scan is incorrectly reported in the explained plan for unique index and IS NULL predicate
1 parent 5581ea6 commit 00447a6

File tree

3 files changed

+20
-9
lines changed

3 files changed

+20
-9
lines changed

src/jrd/btr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ const int irb_exclude_lower = 32; // exclude lower bound keys while scanning i
237237
const int irb_exclude_upper = 64; // exclude upper bound keys while scanning index
238238
const int irb_multi_starting = 128; // Use INTL_KEY_MULTI_STARTING
239239
const int irb_root_list_scan = 256; // Locate list items from the root
240+
const int irb_unique = 512; // Unique match (currently used only for plan output)
240241

241242
// Force include flags - always include appropriate key while scanning index
242243
const int irb_force_lower = irb_exclude_lower;

src/jrd/optimizer/Retrieval.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,9 @@ InversionNode* Retrieval::makeIndexScanNode(IndexScratch* indexScratch) const
12511251
// Check to see if this is really an equality retrieval
12521252
if (retrieval->irb_lower_count == retrieval->irb_upper_count)
12531253
{
1254+
const bool fullMatch = (retrieval->irb_lower_count == idx->idx_count);
1255+
bool uniqueMatch = false;
1256+
12541257
retrieval->irb_generic |= irb_equality;
12551258

12561259
for (unsigned i = 0; i < retrieval->irb_lower_count; i++)
@@ -1260,7 +1263,22 @@ InversionNode* Retrieval::makeIndexScanNode(IndexScratch* indexScratch) const
12601263
retrieval->irb_generic &= ~irb_equality;
12611264
break;
12621265
}
1266+
1267+
if (segments[i].scanType == segmentScanMissing ||
1268+
segments[i].scanType == segmentScanEquivalent)
1269+
{
1270+
if (fullMatch && (idx->idx_flags & idx_primary))
1271+
uniqueMatch = true;
1272+
}
1273+
else if (segments[i].scanType == segmentScanEqual)
1274+
{
1275+
if (fullMatch && (idx->idx_flags & idx_unique))
1276+
uniqueMatch = true;
1277+
}
12631278
}
1279+
1280+
if ((retrieval->irb_generic & irb_equality) && uniqueMatch)
1281+
retrieval->irb_generic |= irb_unique;
12641282
}
12651283

12661284
// If we are matching less than the full index, this is a partial match

src/jrd/recsrc/RecordSource.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,26 +150,18 @@ void RecordSource::printInversion(thread_db* tdbb, const InversionNode* inversio
150150
plan += "Bitmap" + printIndent(++level);
151151

152152
const index_desc& idx = retrieval->irb_desc;
153-
const bool primaryIdx = (idx.idx_flags & idx_primary);
154-
const bool uniqueIdx = (idx.idx_flags & idx_unique);
155153
const USHORT segCount = idx.idx_count;
156154

157155
const USHORT minSegs = MIN(retrieval->irb_lower_count, retrieval->irb_upper_count);
158156
const USHORT maxSegs = MAX(retrieval->irb_lower_count, retrieval->irb_upper_count);
159157

160158
const bool equality = (retrieval->irb_generic & irb_equality);
159+
const bool unique = (retrieval->irb_generic & irb_unique);
161160
const bool partial = (retrieval->irb_generic & irb_partial);
162161

163162
const bool fullscan = (maxSegs == 0);
164163
const bool list = (retrieval->irb_list != nullptr);
165164

166-
bool unique = false;
167-
if (!list && equality && minSegs == segCount)
168-
{
169-
unique = (retrieval->irb_generic & irb_ignore_null_value_key) ?
170-
uniqueIdx : primaryIdx;
171-
}
172-
173165
string bounds;
174166
if (!unique && !fullscan)
175167
{

0 commit comments

Comments
 (0)