From: | Bryn Llewellyn <bryn(at)yugabyte(dot)com> |
---|---|
To: | pgsql-general list <pgsql-general(at)lists(dot)postgresql(dot)org> |
Subject: | « The PL/pgSQL interpreter parses the function's source text and produces an internal binary instruction tree... » |
Date: | 2022-07-29 01:04:29 |
Message-ID: | DD03DCB0-1946-4CEB-8D72-D94EE7A85A7A@yugabyte.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
The subject line is copied from "PL/pgSQL under the Hood" (https://www.postgresql.org/docs/current/plpgsql-implementation.html) It implies the question:
« What does the term "parse" mean? »
I couldn't find more than what I quoted. Have I missed something?
Anyway, I tried some tests. Here's an example that aims to make a reasonable compromise between brevity and its capacity to illustrate. First, I create a domain and then leave it unchanged:
create domain tt as text[];
Then I do this:
create or replace function f()
returns text
language plpgsql
as $body$
declare
n int;
arr tt := array['dog', 'cat'];
begin
n := (select count(*) from (select unnest(art)) as a);
return n::text;
end;
$body$;
\sf+ f()
select f();
The "create or replace" completes without error and the "select" runs to produce the result, 2, that I expect.
If I simulate a typo by changing "n" on the LHS of the assignments to "m", then I get this error at "create or replace" time:
"m" is not a known variable
Moreover, "\sf+" shows that the former definition has remained intact—as I've come to expect.
If I fix the "n" typo and simulate a second typo by changing "tt" in the declaration of "arr" to "tz", then I get this error at "create or replace" time:
type "tz" does not exist
If I fix the "tz" typo and simulate a third typo by changing "arr" in the scalar subquery expression to "art", then "create or replace" completes without error and "\sf+" confirms that the new source is in place. Then, at "select" time, I get this error:
column "art" does not exist
So far, I'm tempted to think that "parse" covers everything about "regular" (i.e. not embedded SQL) PL/pgSQL statements, including syntactic analysis *and* the resolution of identifiers—both within the scope of the to-be-created subprogram and within schema scopes.
But, as it seems, embedded SQL statements receive only syntactic analysis—leaving the resolution of identifiers (even when this can be done in the scope of the to-be-created subprogram) to runtime. (I tried changing "from" to "frim" and that caused a syntax error.)
Then I dropped "f()" and extended the test, thus:
create or replace function f()
returns table(z text)
language plpgsql
as $body$
declare
v_sqlstate text not null := '';
v_message text not null := '';
n int;
arr tt := array['dog', 'cat'];
begin
z := (select count(*) from (select unnest(arr)) as a)::text; return next;
exception when others then
get stacked diagnostics
v_sqlstate = returned_sqlstate,
v_message = message_text;
z := ''; return next;
z := v_sqlstate; return next;
z := v_message; return next;
end;
$body$;
\sf+ f()
select f();
"create or replace" succeeds and "select" reports what I expect: 2. Now if I change "arr" to "art", I get the error report from my "others" handler that I expect:
42703
column "art" does not exist
If I fix "art" back to "arr" and change "v_message" in "z := v_message; return next;" to "q_message", then "create or replace" succeeds—very much to my surprise. Moreover; "select" succeeds too—presumably because the point of execution never enters the "others" handler. Only if (with the "q_message"" typo still in place) I change "arr" to "art" again, do I get this error on "select":
column "q_message" does not exist
Is this expected? In other words, is there a careful explanation of what "parse" means in the context of "create or replace" for a subprogram that predicts all of the outcomes that I reported here?
Or might my final observation be considered to be a bug—and if so, might it be fixed?
From | Date | Subject | |
---|---|---|---|
Next Message | Christophe Pettus | 2022-07-29 01:23:30 | Re: « The PL/pgSQL interpreter parses the function's source text and produces an internal binary instruction tree... » |
Previous Message | Adrian Klaver | 2022-07-28 23:36:13 | Re: Syntax error when combining --set and --command has me stumped |