plpgsql fails to reinitialize record variables at block re-entry
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: pgsql-hackers@lists.postgresql.org
Date: 2017-12-09T06:24:31Z
Lists: pgsql-hackers
Attachments
- reinit-record-variables-at-block-reentry.patch (text/x-diff) patch
Consider regression=# do $$ regression$# declare r record; regression$# begin regression$# raise notice '%', r; regression$# end$$; ERROR: record "r" is not assigned yet DETAIL: The tuple structure of a not-yet-assigned record is indeterminate. CONTEXT: SQL statement "SELECT r" PL/pgSQL function inline_code_block line 4 at RAISE Fine, you're supposed to assign something to the record before you use it. But look at this: regression=# do $$ regression$# begin regression$# for i in 1..3 loop regression$# declare r record; regression$# begin regression$# if i = 1 then regression$# r := row(i); regression$# end if; regression$# raise notice '%', r; regression$# end; regression$# end loop; regression$# end$$; NOTICE: (1) NOTICE: (1) NOTICE: (1) DO Surely that ought to have failed at the i=2 iteration. There is code in plpgsql's exec_stmt_block() that tries to reinitialize PLPGSQL_DTYPE_REC variables, but it's never reached (as a quick look at coverage.postgresql.org will confirm), because what it scans is only the variables attached to the block by plpgsql_add_initdatums() --- and that function thinks it should only pay attention to PLPGSQL_DTYPE_VAR variables. The attached patch fixes this by teaching plpgsql_add_initdatums() to also list PLPGSQL_DTYPE_REC variables, though I failed to resist the temptation to make a couple of nearby cosmetic improvements. What I'm not sure about is whether to back-patch this. The current behavior is indubitably not right, but we've had no field complaints, and it's not entirely far-fetched that some poor sod might have written code that depends on it working this way. So maybe we should leave it alone in the back branches. Thoughts? regards, tom lane
Commits
-
Fix plpgsql to reinitialize record variables at block re-entry.
- 390d58135b22 11.0 landed