* plpgsql_param_eval_recfield evaluation of EEOP_PARAM_CALLBACK step * * This is specialized to the case of DTYPE_RECFIELD variables, for which * we never need to invoke MakeExpandedObjectReadOnly. */
| 6512 | * we never need to invoke MakeExpandedObjectReadOnly. |
| 6513 | */ |
| 6514 | static void |
| 6515 | plpgsql_param_eval_recfield(ExprState *state, ExprEvalStep *op, |
| 6516 | ExprContext *econtext) |
| 6517 | { |
| 6518 | ParamListInfo params; |
| 6519 | PLpgSQL_execstate *estate; |
| 6520 | int dno = op->d.cparam.paramid - 1; |
| 6521 | PLpgSQL_recfield *recfield; |
| 6522 | PLpgSQL_rec *rec; |
| 6523 | ExpandedRecordHeader *erh; |
| 6524 | |
| 6525 | /* fetch back the hook data */ |
| 6526 | params = econtext->ecxt_param_list_info; |
| 6527 | estate = (PLpgSQL_execstate *) params->paramFetchArg; |
| 6528 | Assert(dno >= 0 && dno < estate->ndatums); |
| 6529 | |
| 6530 | /* now we can access the target datum */ |
| 6531 | recfield = (PLpgSQL_recfield *) estate->datums[dno]; |
| 6532 | Assert(recfield->dtype == PLPGSQL_DTYPE_RECFIELD); |
| 6533 | |
| 6534 | /* inline the relevant part of exec_eval_datum */ |
| 6535 | rec = (PLpgSQL_rec *) (estate->datums[recfield->recparentno]); |
| 6536 | erh = rec->erh; |
| 6537 | |
| 6538 | /* |
| 6539 | * If record variable is NULL, instantiate it if it has a named composite |
| 6540 | * type, else complain. (This won't change the logical state of the |
| 6541 | * record: it's still NULL.) |
| 6542 | */ |
| 6543 | if (erh == NULL) |
| 6544 | { |
| 6545 | instantiate_empty_record_variable(estate, rec); |
| 6546 | erh = rec->erh; |
| 6547 | } |
| 6548 | |
| 6549 | /* |
| 6550 | * Look up the field's properties if we have not already, or if the tuple |
| 6551 | * descriptor ID changed since last time. |
| 6552 | */ |
| 6553 | if (unlikely(recfield->rectupledescid != erh->er_tupdesc_id)) |
| 6554 | { |
| 6555 | if (!expanded_record_lookup_field(erh, |
| 6556 | recfield->fieldname, |
| 6557 | &recfield->finfo)) |
| 6558 | ereport(ERROR, |
| 6559 | (errcode(ERRCODE_UNDEFINED_COLUMN), |
| 6560 | errmsg("record \"%s\" has no field \"%s\"", |
| 6561 | rec->refname, recfield->fieldname))); |
| 6562 | recfield->rectupledescid = erh->er_tupdesc_id; |
| 6563 | } |
| 6564 | |
| 6565 | /* OK to fetch the field value. */ |
| 6566 | *op->resvalue = expanded_record_get_field(erh, |
| 6567 | recfield->finfo.fnumber, |
| 6568 | op->resnull); |
| 6569 | |
| 6570 | /* safety check -- needed for, eg, record fields */ |
| 6571 | if (unlikely(recfield->finfo.ftypeid != op->d.cparam.paramtype)) |
nothing calls this directly
no test coverage detected