* ExecIndexBuildScanKeys * Build the index scan keys from the index qualification expressions * * The index quals are passed to the index AM in the form of a ScanKey array. * This routine sets up the ScanKeys, fills in all constant fields of the * ScanKeys, and prepares information about the keys that have non-constant * comparison values. We divide index qual expressions into five types:
| 1166 | * IndexArrayKeyInfos are not supported. |
| 1167 | */ |
| 1168 | void |
| 1169 | ExecIndexBuildScanKeys(PlanState *planstate, Relation index, |
| 1170 | List *quals, bool isorderby, |
| 1171 | ScanKey *scanKeys, int *numScanKeys, |
| 1172 | IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys, |
| 1173 | IndexArrayKeyInfo **arrayKeys, int *numArrayKeys) |
| 1174 | { |
| 1175 | ListCell *qual_cell; |
| 1176 | ScanKey scan_keys; |
| 1177 | IndexRuntimeKeyInfo *runtime_keys; |
| 1178 | IndexArrayKeyInfo *array_keys; |
| 1179 | int n_scan_keys; |
| 1180 | int n_runtime_keys; |
| 1181 | int max_runtime_keys; |
| 1182 | int n_array_keys; |
| 1183 | int j; |
| 1184 | |
| 1185 | /* Allocate array for ScanKey structs: one per qual */ |
| 1186 | n_scan_keys = list_length(quals); |
| 1187 | scan_keys = (ScanKey) palloc(n_scan_keys * sizeof(ScanKeyData)); |
| 1188 | |
| 1189 | /* |
| 1190 | * runtime_keys array is dynamically resized as needed. We handle it this |
| 1191 | * way so that the same runtime keys array can be shared between |
| 1192 | * indexquals and indexorderbys, which will be processed in separate calls |
| 1193 | * of this function. Caller must be sure to pass in NULL/0 for first |
| 1194 | * call. |
| 1195 | */ |
| 1196 | runtime_keys = *runtimeKeys; |
| 1197 | n_runtime_keys = max_runtime_keys = *numRuntimeKeys; |
| 1198 | |
| 1199 | /* Allocate array_keys as large as it could possibly need to be */ |
| 1200 | array_keys = (IndexArrayKeyInfo *) |
| 1201 | palloc0(n_scan_keys * sizeof(IndexArrayKeyInfo)); |
| 1202 | n_array_keys = 0; |
| 1203 | |
| 1204 | /* |
| 1205 | * for each opclause in the given qual, convert the opclause into a single |
| 1206 | * scan key |
| 1207 | */ |
| 1208 | j = 0; |
| 1209 | foreach(qual_cell, quals) |
| 1210 | { |
| 1211 | Expr *clause = (Expr *) lfirst(qual_cell); |
| 1212 | ScanKey this_scan_key = &scan_keys[j++]; |
| 1213 | Oid opno; /* operator's OID */ |
| 1214 | RegProcedure opfuncid; /* operator proc id used in scan */ |
| 1215 | Oid opfamily; /* opfamily of index column */ |
| 1216 | int op_strategy; /* operator's strategy number */ |
| 1217 | Oid op_lefttype; /* operator's declared input types */ |
| 1218 | Oid op_righttype; |
| 1219 | Expr *leftop; /* expr on lhs of operator */ |
| 1220 | Expr *rightop; /* expr on rhs ... */ |
| 1221 | AttrNumber varattno; /* att number used in scan */ |
| 1222 | int indnkeyatts; |
| 1223 | |
| 1224 | indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index); |
| 1225 | if (IsA(clause, OpExpr)) |
no test coverage detected