| 1124 | // |
| 1125 | |
| 1126 | InversionNode* Retrieval::makeIndexScanNode(IndexScratch* indexScratch) const |
| 1127 | { |
| 1128 | if (!createIndexScanNodes) |
| 1129 | return nullptr; |
| 1130 | |
| 1131 | const auto idx = indexScratch->index; |
| 1132 | auto& segments = indexScratch->segments; |
| 1133 | |
| 1134 | // Check whether this is during a compile or during a SET INDEX operation |
| 1135 | if (csb) |
| 1136 | CMP_post_resource(&csb->csb_resources, relation, Resource::rsc_index, idx->idx_id); |
| 1137 | else |
| 1138 | { |
| 1139 | CMP_post_resource(&tdbb->getRequest()->getStatement()->resources, relation, |
| 1140 | Resource::rsc_index, idx->idx_id); |
| 1141 | } |
| 1142 | |
| 1143 | // For external requests, determine index name (to be reported in plans) |
| 1144 | MetaName indexName; |
| 1145 | if (!(csb->csb_g_flags & csb_internal)) |
| 1146 | MET_lookup_index(tdbb, indexName, relation->rel_name, idx->idx_id + 1); |
| 1147 | |
| 1148 | const auto retrieval = |
| 1149 | FB_NEW_POOL(getPool()) IndexRetrieval(getPool(), relation, idx, indexName); |
| 1150 | |
| 1151 | // Pick up lower bound segment values |
| 1152 | ValueExprNode** lower = retrieval->irb_value; |
| 1153 | ValueExprNode** upper = retrieval->irb_value + idx->idx_count; |
| 1154 | retrieval->irb_lower_count = indexScratch->lowerCount; |
| 1155 | retrieval->irb_upper_count = indexScratch->upperCount; |
| 1156 | |
| 1157 | if (idx->idx_flags & idx_descending) |
| 1158 | { |
| 1159 | // switch upper/lower information |
| 1160 | upper = retrieval->irb_value; |
| 1161 | lower = retrieval->irb_value + idx->idx_count; |
| 1162 | retrieval->irb_lower_count = indexScratch->upperCount; |
| 1163 | retrieval->irb_upper_count = indexScratch->lowerCount; |
| 1164 | retrieval->irb_generic |= irb_descending; |
| 1165 | } |
| 1166 | |
| 1167 | if (const auto count = MAX(indexScratch->lowerCount, indexScratch->upperCount)) |
| 1168 | { |
| 1169 | bool ignoreNullsOnScan = true; |
| 1170 | |
| 1171 | for (unsigned i = 0; i < count; i++) |
| 1172 | { |
| 1173 | if (segments[i].scanType == segmentScanMissing) |
| 1174 | { |
| 1175 | *lower++ = *upper++ = NullNode::instance(); |
| 1176 | ignoreNullsOnScan = false; |
| 1177 | } |
| 1178 | else |
| 1179 | { |
| 1180 | if (i < indexScratch->lowerCount) |
| 1181 | *lower++ = segments[i].lowerValue; |
| 1182 | |
| 1183 | if (i < indexScratch->upperCount) |
nothing calls this directly
no test coverage detected