---------- * make_tuple_from_row Make a tuple from the values of a row object * * A NULL return indicates rowtype mismatch; caller must raise suitable error * * The result tuple is freshly palloc'd in caller's context. Some junk * may be left behind in eval_mcontext, too. * ---------- */
| 7262 | * ---------- |
| 7263 | */ |
| 7264 | static HeapTuple |
| 7265 | make_tuple_from_row(PLpgSQL_execstate *estate, |
| 7266 | PLpgSQL_row *row, |
| 7267 | TupleDesc tupdesc) |
| 7268 | { |
| 7269 | int natts = tupdesc->natts; |
| 7270 | HeapTuple tuple; |
| 7271 | Datum *dvalues; |
| 7272 | bool *nulls; |
| 7273 | int i; |
| 7274 | |
| 7275 | if (natts != row->nfields) |
| 7276 | return NULL; |
| 7277 | |
| 7278 | dvalues = (Datum *) eval_mcontext_alloc0(estate, natts * sizeof(Datum)); |
| 7279 | nulls = (bool *) eval_mcontext_alloc(estate, natts * sizeof(bool)); |
| 7280 | |
| 7281 | for (i = 0; i < natts; i++) |
| 7282 | { |
| 7283 | Oid fieldtypeid; |
| 7284 | int32 fieldtypmod; |
| 7285 | |
| 7286 | if (TupleDescAttr(tupdesc, i)->attisdropped) |
| 7287 | { |
| 7288 | nulls[i] = true; /* leave the column as null */ |
| 7289 | continue; |
| 7290 | } |
| 7291 | |
| 7292 | exec_eval_datum(estate, estate->datums[row->varnos[i]], |
| 7293 | &fieldtypeid, &fieldtypmod, |
| 7294 | &dvalues[i], &nulls[i]); |
| 7295 | if (fieldtypeid != TupleDescAttr(tupdesc, i)->atttypid) |
| 7296 | return NULL; |
| 7297 | /* XXX should we insist on typmod match, too? */ |
| 7298 | } |
| 7299 | |
| 7300 | tuple = heap_form_tuple(tupdesc, dvalues, nulls); |
| 7301 | |
| 7302 | return tuple; |
| 7303 | } |
| 7304 | |
| 7305 | /* |
| 7306 | * deconstruct_composite_datum extract tuple+tupdesc from composite Datum |
no test coverage detected