* exec_eval_datum Get current value of a PLpgSQL_datum * * The type oid, typmod, value in Datum format, and null flag are returned. * * At present this doesn't handle PLpgSQL_expr datums; that's not needed * because we never pass references to such datums to SPI. * * NOTE: the returned Datum points right at the stored value in the case of * pass-by-reference datatypes. Generally caller
| 5235 | * it into the estate's eval_mcontext. |
| 5236 | */ |
| 5237 | static void |
| 5238 | exec_eval_datum(PLpgSQL_execstate *estate, |
| 5239 | PLpgSQL_datum *datum, |
| 5240 | Oid *typeid, |
| 5241 | int32 *typetypmod, |
| 5242 | Datum *value, |
| 5243 | bool *isnull) |
| 5244 | { |
| 5245 | MemoryContext oldcontext; |
| 5246 | |
| 5247 | switch (datum->dtype) |
| 5248 | { |
| 5249 | case PLPGSQL_DTYPE_PROMISE: |
| 5250 | /* fulfill promise if needed, then handle like regular var */ |
| 5251 | plpgsql_fulfill_promise(estate, (PLpgSQL_var *) datum); |
| 5252 | |
| 5253 | /* FALL THRU */ |
| 5254 | |
| 5255 | case PLPGSQL_DTYPE_VAR: |
| 5256 | { |
| 5257 | PLpgSQL_var *var = (PLpgSQL_var *) datum; |
| 5258 | |
| 5259 | *typeid = var->datatype->typoid; |
| 5260 | *typetypmod = var->datatype->atttypmod; |
| 5261 | *value = var->value; |
| 5262 | *isnull = var->isnull; |
| 5263 | break; |
| 5264 | } |
| 5265 | |
| 5266 | case PLPGSQL_DTYPE_ROW: |
| 5267 | { |
| 5268 | PLpgSQL_row *row = (PLpgSQL_row *) datum; |
| 5269 | HeapTuple tup; |
| 5270 | |
| 5271 | /* We get here if there are multiple OUT parameters */ |
| 5272 | if (!row->rowtupdesc) /* should not happen */ |
| 5273 | elog(ERROR, "row variable has no tupdesc"); |
| 5274 | /* Make sure we have a valid type/typmod setting */ |
| 5275 | BlessTupleDesc(row->rowtupdesc); |
| 5276 | oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate)); |
| 5277 | tup = make_tuple_from_row(estate, row, row->rowtupdesc); |
| 5278 | if (tup == NULL) /* should not happen */ |
| 5279 | elog(ERROR, "row not compatible with its own tupdesc"); |
| 5280 | *typeid = row->rowtupdesc->tdtypeid; |
| 5281 | *typetypmod = row->rowtupdesc->tdtypmod; |
| 5282 | *value = HeapTupleGetDatum(tup); |
| 5283 | *isnull = false; |
| 5284 | MemoryContextSwitchTo(oldcontext); |
| 5285 | break; |
| 5286 | } |
| 5287 | |
| 5288 | case PLPGSQL_DTYPE_REC: |
| 5289 | { |
| 5290 | PLpgSQL_rec *rec = (PLpgSQL_rec *) datum; |
| 5291 | |
| 5292 | if (rec->erh == NULL) |
| 5293 | { |
| 5294 | /* Treat uninstantiated record as a simple NULL */ |
no test coverage detected