Commit 5b0fa0c2 authored by Tom Lane's avatar Tom Lane

Fix make_tuple_from_row to support nested rowtypes, per gripe from

Roman Neuhauser.  Update some obsolete comments for exec_eval_datum, too.
parent d6bc885b
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.151 2005/07/28 07:51:13 neilc Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.152 2005/09/13 16:16:17 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -3388,11 +3388,12 @@ exec_assign_value(PLpgSQL_execstate *estate, ...@@ -3388,11 +3388,12 @@ exec_assign_value(PLpgSQL_execstate *estate,
* *
* If expectedtypeid isn't InvalidOid, it is checked against the actual type. * If expectedtypeid isn't InvalidOid, it is checked against the actual type.
* *
* This obviously only handles scalar datums (not whole records or rows); * At present this doesn't handle PLpgSQL_expr or PLpgSQL_arrayelem datums.
* at present it doesn't need to handle PLpgSQL_expr datums, either.
* *
* NOTE: caller must not modify the returned value, since it points right * NOTE: caller must not modify the returned value, since it points right
* at the stored value in the case of pass-by-reference datatypes. * at the stored value in the case of pass-by-reference datatypes. In some
* cases we have to palloc a return value, and in such cases we put it into
* the estate's short-term memory context.
*/ */
static void static void
exec_eval_datum(PLpgSQL_execstate *estate, exec_eval_datum(PLpgSQL_execstate *estate,
...@@ -3997,34 +3998,34 @@ make_tuple_from_row(PLpgSQL_execstate *estate, ...@@ -3997,34 +3998,34 @@ make_tuple_from_row(PLpgSQL_execstate *estate,
int natts = tupdesc->natts; int natts = tupdesc->natts;
HeapTuple tuple; HeapTuple tuple;
Datum *dvalues; Datum *dvalues;
char *nulls; bool *nulls;
int i; int i;
if (natts != row->nfields) if (natts != row->nfields)
return NULL; return NULL;
dvalues = (Datum *) palloc0(natts * sizeof(Datum)); dvalues = (Datum *) palloc0(natts * sizeof(Datum));
nulls = (char *) palloc(natts * sizeof(char)); nulls = (bool *) palloc(natts * sizeof(bool));
MemSet(nulls, 'n', natts);
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
{ {
PLpgSQL_var *var; Oid fieldtypeid;
if (tupdesc->attrs[i]->attisdropped) if (tupdesc->attrs[i]->attisdropped)
continue; /* leave the column as null */ {
nulls[i] = true; /* leave the column as null */
continue;
}
if (row->varnos[i] < 0) /* should not happen */ if (row->varnos[i] < 0) /* should not happen */
elog(ERROR, "dropped rowtype entry for non-dropped column"); elog(ERROR, "dropped rowtype entry for non-dropped column");
var = (PLpgSQL_var *) (estate->datums[row->varnos[i]]); exec_eval_datum(estate, estate->datums[row->varnos[i]],
if (var->datatype->typoid != tupdesc->attrs[i]->atttypid) InvalidOid, &fieldtypeid, &dvalues[i], &nulls[i]);
if (fieldtypeid != tupdesc->attrs[i]->atttypid)
return NULL; return NULL;
dvalues[i] = var->value;
if (!var->isnull)
nulls[i] = ' ';
} }
tuple = heap_formtuple(tupdesc, dvalues, nulls); tuple = heap_form_tuple(tupdesc, dvalues, nulls);
pfree(dvalues); pfree(dvalues);
pfree(nulls); pfree(nulls);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment