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
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 841a8d6..01b3c10 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -500,34 +500,16 @@ decl_statement    : decl_varname decl_const decl_datatype 
decl_collate decl_notnull
                                                                                
                         $3, true);
                                                if ($2)
                                                {
-                                                       if (var->dtype == 
PLPGSQL_DTYPE_VAR)
                                                                ((PLpgSQL_var 
*) var)->isconst = $2;
-                                                       else
-                                                               ereport(ERROR,
-                                                                               
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                                               
 errmsg("row or record variable cannot be CONSTANT"),
-                                                                               
 parser_errposition(@2)));
                                                }
                                                if ($5)
                                                {
-                                                       if (var->dtype == 
PLPGSQL_DTYPE_VAR)
                                                                ((PLpgSQL_var 
*) var)->notnull = $5;
-                                                       else
-                                                               ereport(ERROR,
-                                                                               
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                                               
 errmsg("row or record variable cannot be NOT NULL"),
-                                                                               
 parser_errposition(@4)));
 
                                                }
                                                if ($6 != NULL)
                                                {
-                                                       if (var->dtype == 
PLPGSQL_DTYPE_VAR)
                                                                ((PLpgSQL_var 
*) var)->default_val = $6;
-                                                       else
-                                                               ereport(ERROR,
-                                                                               
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                                               
 errmsg("default value for row or record variable is not supported"),
-                                                                               
 parser_errposition(@5)));
                                                }
                                        }
                                | decl_varname K_ALIAS K_FOR decl_aliasitem ';'
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to