| 136 | |
| 137 | |
| 138 | Retrieval::Retrieval(thread_db* aTdbb, Optimizer* opt, StreamType streamNumber, |
| 139 | bool outer, bool inner, SortNode* sortNode, bool costOnly) |
| 140 | : PermanentStorage(*aTdbb->getDefaultPool()), |
| 141 | tdbb(aTdbb), |
| 142 | optimizer(opt), |
| 143 | csb(opt->getCompilerScratch()), |
| 144 | stream(streamNumber), |
| 145 | innerFlag(inner), |
| 146 | outerFlag(outer), |
| 147 | sort(sortNode), |
| 148 | createIndexScanNodes(!costOnly), |
| 149 | setConjunctionsMatched(!costOnly), |
| 150 | alias(getPool()), |
| 151 | indexScratches(getPool()), |
| 152 | inversionCandidates(getPool()) |
| 153 | { |
| 154 | const auto dbb = tdbb->getDatabase(); |
| 155 | |
| 156 | const auto tail = &csb->csb_rpt[stream]; |
| 157 | relation = tail->csb_relation; |
| 158 | fb_assert(relation); |
| 159 | |
| 160 | if (!tail->csb_idx) |
| 161 | return; |
| 162 | |
| 163 | MatchedBooleanList matches; |
| 164 | |
| 165 | for (auto& index : *tail->csb_idx) |
| 166 | { |
| 167 | matches.clear(); |
| 168 | |
| 169 | index.idx_fraction = MAXIMUM_SELECTIVITY; |
| 170 | |
| 171 | if ((index.idx_flags & idx_condition) && !checkIndexCondition(index, matches)) |
| 172 | continue; |
| 173 | |
| 174 | const auto length = ROUNDUP(BTR_key_length(tdbb, relation, &index), sizeof(SLONG)); |
| 175 | |
| 176 | // AB: Calculate the cardinality which should reflect the total number |
| 177 | // of index pages for this index. |
| 178 | // We assume that the average index-key can be compressed by a factor 0.5 |
| 179 | // In the future the average key-length should be stored and retrieved |
| 180 | // from a system table (RDB$INDICES for example). |
| 181 | // Multiplying the selectivity with this cardinality gives the estimated |
| 182 | // number of index pages that are read for the index retrieval. |
| 183 | // Compound indexes are generally less compressed. |
| 184 | const double factor = (index.idx_count == 1) ? 0.5 : 0.7; |
| 185 | |
| 186 | double cardinality = tail->csb_cardinality * index.idx_fraction; |
| 187 | cardinality *= (2 + length * factor); |
| 188 | cardinality /= (dbb->dbb_page_size - BTR_SIZE); |
| 189 | cardinality = MAX(cardinality, MINIMUM_CARDINALITY); |
| 190 | |
| 191 | IndexScratch scratch(getPool(), &index); |
| 192 | scratch.cardinality = cardinality; |
| 193 | scratch.matches.assign(matches); |
| 194 | |
| 195 | indexScratches.add(scratch); |
nothing calls this directly
no test coverage detected