| 1128 | } |
| 1129 | |
| 1130 | void BTR_evaluate(thread_db* tdbb, const IndexRetrieval* retrieval, RecordBitmap** bitmap, |
| 1131 | RecordBitmap* bitmap_and) |
| 1132 | { |
| 1133 | /************************************** |
| 1134 | * |
| 1135 | * B T R _ e v a l u a t e |
| 1136 | * |
| 1137 | ************************************** |
| 1138 | * |
| 1139 | * Functional description |
| 1140 | * Do an index scan and return a bitmap |
| 1141 | * of all candidate record numbers. |
| 1142 | * |
| 1143 | **************************************/ |
| 1144 | SET_TDBB(tdbb); |
| 1145 | |
| 1146 | RelationPages* relPages = retrieval->irb_relation->getPages(tdbb); |
| 1147 | WIN window(relPages->rel_pg_space_id, -1); |
| 1148 | |
| 1149 | temporary_key lowerKey, upperKey; |
| 1150 | lowerKey.key_flags = 0; |
| 1151 | lowerKey.key_length = 0; |
| 1152 | upperKey.key_flags = 0; |
| 1153 | upperKey.key_length = 0; |
| 1154 | |
| 1155 | AutoPtr<IndexScanListIterator> iterator = |
| 1156 | retrieval->irb_list ? FB_NEW_POOL(*tdbb->getDefaultPool()) |
| 1157 | IndexScanListIterator(tdbb, retrieval) : nullptr; |
| 1158 | |
| 1159 | temporary_key* lower = &lowerKey; |
| 1160 | temporary_key* upper = &upperKey; |
| 1161 | USHORT forceInclFlag = 0; |
| 1162 | |
| 1163 | if (!BTR_make_bounds(tdbb, retrieval, iterator, lower, upper, forceInclFlag)) |
| 1164 | return; |
| 1165 | |
| 1166 | index_desc idx; |
| 1167 | btree_page* page = nullptr; |
| 1168 | |
| 1169 | do |
| 1170 | { |
| 1171 | if (!page) // scan from the index root |
| 1172 | page = BTR_find_page(tdbb, retrieval, &window, &idx, lower, upper); |
| 1173 | |
| 1174 | const bool descending = (idx.idx_flags & idx_descending); |
| 1175 | bool skipLowerKey = (retrieval->irb_generic & ~forceInclFlag) & irb_exclude_lower; |
| 1176 | const bool partLower = (retrieval->irb_lower_count < idx.idx_count); |
| 1177 | |
| 1178 | // If there is a starting descriptor, search down index to starting position. |
| 1179 | // This may involve sibling buckets if splits are in progress. If there |
| 1180 | // isn't a starting descriptor, walk down the left side of the index. |
| 1181 | |
| 1182 | USHORT prefix; |
| 1183 | UCHAR* pointer; |
| 1184 | if (retrieval->irb_lower_count) |
| 1185 | { |
| 1186 | while (!(pointer = find_node_start_point(page, lower, 0, &prefix, |
| 1187 | descending, (retrieval->irb_generic & (irb_starting | irb_partial))))) |
no test coverage detected