* plpgsql_param_fetch paramFetch callback for dynamic parameter fetch * * We always use the caller's workspace to construct the returned struct. * * Note: this is no longer used during query execution. It is used during * planning (with speculative == true) and when the ParamListInfo we supply * to the executor is copied into a cursor portal or transferred to a * parallel child process.
| 6241 | * parallel child process. |
| 6242 | */ |
| 6243 | static ParamExternData * |
| 6244 | plpgsql_param_fetch(ParamListInfo params, |
| 6245 | int paramid, bool speculative, |
| 6246 | ParamExternData *prm) |
| 6247 | { |
| 6248 | int dno; |
| 6249 | PLpgSQL_execstate *estate; |
| 6250 | PLpgSQL_expr *expr; |
| 6251 | PLpgSQL_datum *datum; |
| 6252 | bool ok = true; |
| 6253 | int32 prmtypmod; |
| 6254 | |
| 6255 | /* paramid's are 1-based, but dnos are 0-based */ |
| 6256 | dno = paramid - 1; |
| 6257 | Assert(dno >= 0 && dno < params->numParams); |
| 6258 | |
| 6259 | /* fetch back the hook data */ |
| 6260 | estate = (PLpgSQL_execstate *) params->paramFetchArg; |
| 6261 | expr = (PLpgSQL_expr *) params->parserSetupArg; |
| 6262 | Assert(params->numParams == estate->ndatums); |
| 6263 | |
| 6264 | /* now we can access the target datum */ |
| 6265 | datum = estate->datums[dno]; |
| 6266 | |
| 6267 | /* |
| 6268 | * Since copyParamList() or SerializeParamList() will try to materialize |
| 6269 | * every single parameter slot, it's important to return a dummy param |
| 6270 | * when asked for a datum that's not supposed to be used by this SQL |
| 6271 | * expression. Otherwise we risk failures in exec_eval_datum(), or |
| 6272 | * copying a lot more data than necessary. |
| 6273 | */ |
| 6274 | if (!bms_is_member(dno, expr->paramnos)) |
| 6275 | ok = false; |
| 6276 | |
| 6277 | /* |
| 6278 | * If the access is speculative, we prefer to return no data rather than |
| 6279 | * to fail in exec_eval_datum(). Check the likely failure cases. |
| 6280 | */ |
| 6281 | else if (speculative) |
| 6282 | { |
| 6283 | switch (datum->dtype) |
| 6284 | { |
| 6285 | case PLPGSQL_DTYPE_VAR: |
| 6286 | case PLPGSQL_DTYPE_PROMISE: |
| 6287 | /* always safe */ |
| 6288 | break; |
| 6289 | |
| 6290 | case PLPGSQL_DTYPE_ROW: |
| 6291 | /* should be safe in all interesting cases */ |
| 6292 | break; |
| 6293 | |
| 6294 | case PLPGSQL_DTYPE_REC: |
| 6295 | /* always safe (might return NULL, that's fine) */ |
| 6296 | break; |
| 6297 | |
| 6298 | case PLPGSQL_DTYPE_RECFIELD: |
| 6299 | { |
| 6300 | PLpgSQL_recfield *recfield = (PLpgSQL_recfield *) datum; |
nothing calls this directly
no test coverage detected