2017-05-19 5:48 GMT+02:00 Pavel Stehule <pavel.steh...@gmail.com>: > > > 2017-05-19 3:14 GMT+02:00 Peter Eisentraut <peter.eisentraut@2ndquadrant. > com>: > >> On 5/15/17 14:34, Pavel Stehule wrote: >> > Now, I when I working on plpgsql_check, I have to check function >> > parameters. I can use fn_vargargnos and out_param_varno for list of >> > arguments and related varno(s). when I detect some issue, I am using >> > refname. It is not too nice now, because these refnames are $ based. >> > Long names are alias only. There are not a possibility to find >> > related alias. >> > >> > So, my proposal. Now, we can use names as refname of parameter >> > variable. $ based name can be used as alias. From user perspective >> > there are not any change. >> > >> > Comments, notes? >> > >> > here is a patch >> >> I don't understand what this is changing. There are not documentation >> or test changes. >> > > This change is visible only for tools like plpgsql_check probably and > similar tools. Now, this info is not available from user space (maybe only > from some error message, I have to recheck it) > > What is changed. > > PLpgSQL variables has field refname - it can be used if you iterate over > variables or it is used for some error messages. When some variables is > searching, then namespace aliases are used. Now for any function argument > is created variable with refname "$x" and namespace aliases "$x" and "name" > if name exists. There are not any way, how to get a aliases related to > variable. When I raise a warning in plpgsql about function arguments I have > to print $x based messages, what is not too readable if function has lot of > parameters. > > The proposal is the change of refname "$x" to "name" for all variables > created for function arguments. > > There are another possibilities - maintain list of all aliases for > variables or dynamically search all related aliases in namespace tree. Both > little bit more code. >
I wrote small regression test, where expected behave is visible master: postgres=# create or replace function fx(x ct) returns void as $$ begin perform 1; get diagnostics x = row_count; end; $$ language plpgsql; ERROR: "$1" is not a scalar variable LINE 5: get diagnostics x = row_count; patched: postgres=# create or replace function fx(x ct) returns void as $$ begin perform 1; get diagnostics x = row_count; end; $$ language plpgsql; ERROR: "x" is not a scalar variable LINE 5: get diagnostics x = row_count; > Regards > > Pavel > > >> >> -- >> Peter Eisentraut http://www.2ndQuadrant.com/ >> PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services >> > >
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index a637551..49327b2 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -409,6 +409,7 @@ do_compile(FunctionCallInfo fcinfo, for (i = 0; i < numargs; i++) { char buf[32]; + char *argname = NULL; Oid argtypeid = argtypes[i]; char argmode = argmodes ? argmodes[i] : PROARGMODE_IN; PLpgSQL_type *argdtype; @@ -433,9 +434,12 @@ do_compile(FunctionCallInfo fcinfo, errmsg("PL/pgSQL functions cannot accept type %s", format_type_be(argtypeid)))); + argname = (argnames && argnames[i][0] != 0) ? argnames[i] : NULL; + /* Build variable and add to datum list */ - argvariable = plpgsql_build_variable(buf, 0, - argdtype, false); + argvariable = plpgsql_build_variable(argname != NULL ? + argname : buf, + 0, argdtype, false); if (argvariable->dtype == PLPGSQL_DTYPE_VAR) { @@ -461,9 +465,9 @@ do_compile(FunctionCallInfo fcinfo, add_parameter_name(argitemtype, argvariable->dno, buf); /* If there's a name for the argument, make an alias */ - if (argnames && argnames[i][0] != '\0') + if (argname != '\0') add_parameter_name(argitemtype, argvariable->dno, - argnames[i]); + argname); } /* diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 7ebbde6..a9fe736 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -5979,3 +5979,15 @@ LINE 1: SELECT (SELECT string_agg(id || '=' || name, ',') FROM d) ^ QUERY: SELECT (SELECT string_agg(id || '=' || name, ',') FROM d) CONTEXT: PL/pgSQL function alter_table_under_transition_tables_upd_func() line 3 at RAISE +-- should fail -- message should to contain argument name +CREATE TYPE ct AS (a int, b int); +CREATE OR REPLACE FUNCTION fx(x ct) +RETURNS void AS $$ +BEGIN + GET DIAGNOSTICS x = ROW_COUNT; +end; +$$ language plpgsql; +ERROR: "x" is not a scalar variable +LINE 4: GET DIAGNOSTICS x = ROW_COUNT; + ^ +DROP TYPE ct; diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index 60d1d38..4716ac0 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -4766,3 +4766,15 @@ ALTER TABLE alter_table_under_transition_tables DROP column name; UPDATE alter_table_under_transition_tables SET id = id; + +-- should fail -- message should to contain argument name +CREATE TYPE ct AS (a int, b int); + +CREATE OR REPLACE FUNCTION fx(x ct) +RETURNS void AS $$ +BEGIN + GET DIAGNOSTICS x = ROW_COUNT; +end; +$$ language plpgsql; + +DROP TYPE ct;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers