On 10/19/15 5:16 PM, Jim Nasby wrote:
> Yeah, was hoping someone knew offhand why this was a problem. Guess I'll
> rip the checks out and see what explodes.
... and what blows up is exec_eval_datum():
> case PLPGSQL_DTYPE_ROW:
> {
> PLpgSQL_row *row = (PLpgSQL_row *) datum;
> HeapTuple tup;
>
> if (!row->rowtupdesc) /* should not happen */
> elog(ERROR, "row variable has no tupdesc");
> /* Make sure we have a valid type/typmod setting */
> BlessTupleDesc(row->rowtupdesc);
> oldcontext = MemoryContextSwitchTo(estate->eval_econtext->ecxt_per_tuple_memory);
> tup = make_tuple_from_row(estate, row, row->rowtupdesc);
> if (tup == NULL) /* should not happen */
> elog(ERROR, "row not compatible with its own tupdesc");
running this:
create type tt as (a int, b int);
do $$
declare
c CONSTANT tt := '(1,2)'::tt;
begin
raise notice 'c = %', c;
end
$$;
ERROR: row not compatible with its own tupdesc
CONTEXT: PL/pgSQL function inline_code_block line 5 at RAISE
STATEMENT: do $$
declare
c CONSTANT tt := '(1,2)'::tt;
begin
raise notice 'c = %', c;
end
$$;
ERROR: row not compatible with its own tupdesc
CONTEXT: PL/pgSQL function inline_code_block line 5 at RAISE
row.tupledesc looked normal to me.
What did seem odd is that while processing the DECLARE section there
were plpgsql datums for tt.a and tt.b. I would have expected the
assignment to produce a row datum of type tt. When exec_stmt_block is
finally called, the initialization for loop initializes tt.a and tt.b,
but does nothing with c.
--
Jim Nasby, Data Architect, Blue Treble Consulting, Austin TX
Experts in Analytics, Data Architecture and PostgreSQL
Data in Trouble? Get it in Treble! http://BlueTreble.com