2017-05-19 5:48 GMT+02:00 Pavel Stehule <[email protected]>:
>
>
> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers