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

Reply via email to