Strange behaviour on function

Started by Lorusso Domenicoalmost 3 years ago6 messagesgeneral
Jump to latest
#1Lorusso Domenico
domenico.l76@gmail.com

Hello guys,
here a simple function

CREATE OR REPLACE FUNCTION bind_action(
sqlstr text,
hrec hstore)
RETURNS text
LANGUAGE 'plpgsql'
COST 100
immutable PARALLEL SAFE
AS $BODY$
declare
_sqlstr text=sqlstr;
_k text;
_debug text;
begin
_debug= '--Start' || _sqlstr;
foreach _k in array akeys(hrec) loop
_debug =_debug || format($$
hstore: %s %s
sqlStr:$$, _k, hrec[_k]);
_sqlstr=replace(_sqlstr, ':'||_k||':', hrec[_k]);
_debug =_debug || _sqlstr;

end loop;

raise notice 'final %',_debug;
return _sqlstr;
end;
$BODY$;

and here a simple test
do
$$
declare
sqlstr text=':id::bignt,:surpa:,:disfa:';
hs hstore;
begin
hs['id']=789;
hs['disfa']='ssssssss';
raise notice '%',bind_action(sqlstr,hs);
end;
$$;

and it works.
But...
When I call this function in a function called by a trigger it down't work
_debug variable becomes null, also _sqlstr becomes null...

I can't identify what is going to happens...

any idea?

thanks

--
Domenico L.

per stupire mezz'ora basta un libro di storia,
io cercai di imparare la Treccani a memoria... [F.d.A.]

#2Erik Wienhold
ewie@ewie.name
In reply to: Lorusso Domenico (#1)
Re: Strange behaviour on function

On 05/07/2023 14:23 CEST Lorusso Domenico <domenico.l76@gmail.com> wrote:

Hello guys,
here a simple function

CREATE OR REPLACE FUNCTION bind_action(
sqlstr text,
hrec hstore)
RETURNS text
LANGUAGE 'plpgsql'
COST 100
immutable PARALLEL SAFE
AS $BODY$
declare
_sqlstr text=sqlstr;
_k text;
_debug text;
begin
_debug= '--Start' || _sqlstr;
foreach _k in array akeys(hrec) loop
_debug =_debug || format($$
hstore: %s %s
sqlStr:$$, _k, hrec[_k]);
_sqlstr=replace(_sqlstr, ':'||_k||':', hrec[_k]);
_debug =_debug || _sqlstr;

end loop;

raise notice 'final %',_debug;
return _sqlstr;
end;
$BODY$;

and here a simple test
do
$$
declare
sqlstr text=':id::bignt,:surpa:,:disfa:';
hs hstore;
begin
hs['id']=789;
hs['disfa']='ssssssss';
raise notice '%',bind_action(sqlstr,hs);
end;
$$;

and it works.
But...
When I call this function in a function called by a trigger it down't work
_debug variable becomes null, also _sqlstr becomes null...

Does the hstore contain nulls? Function replace returns null in that case.

Please show us the trigger, its function, and a reproducer.

--
Erik

#3Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Lorusso Domenico (#1)
Re: Strange behaviour on function

On 7/5/23 05:23, Lorusso Domenico wrote:

Hello guys,
here a simple function

CREATE OR REPLACE FUNCTION bind_action(
sqlstr text,
hrec hstore)
    RETURNS text
    LANGUAGE 'plpgsql'
    COST 100
    immutable PARALLEL SAFE
AS $BODY$
declare
_sqlstr text=sqlstr;
_k text;
_debug text;
begin
_debug= '--Start' || _sqlstr;
foreach _k in array akeys(hrec) loop
_debug =_debug || format($$
hstore: %s %s
sqlStr:$$, _k,  hrec[_k]);
_sqlstr=replace(_sqlstr, ':'||_k||':', hrec[_k]);
_debug =_debug ||  _sqlstr;

end loop;

raise notice 'final %',_debug;
return _sqlstr;
end;
$BODY$;

and here a simple test
do
$$
declare
sqlstr text=':id::bignt,:surpa:,:disfa:';
hs hstore;
begin
hs['id']=789;
hs['disfa']='ssssssss';
raise notice '%',bind_action(sqlstr,hs);
end;
$$;

and it works.
But...
When I call this function in a function called by a trigger it down't work
_debug variable becomes null, also _sqlstr becomes null...

https://www.postgresql.org/docs/current/plpgsql-trigger.html

1)
"A trigger function must return either NULL or a record/row value having
exactly the structure of the table the trigger was fired for."

2) I am not seeing where you use:

"TG_ARGV[]

Data type array of text; the arguments from the CREATE TRIGGER
statement. The index counts from 0. Invalid indexes (less than 0 or
greater than or equal to tg_nargs) result in a null value."

So I don't see how sqlstr is being set?

I can't identify what is going to happens...

any idea?

thanks

--
Domenico L.

per stupire mezz'ora basta un libro di storia,
io cercai di imparare la Treccani a memoria... [F.d.A.]

--
Adrian Klaver
adrian.klaver@aklaver.com

#4Erik Wienhold
ewie@ewie.name
In reply to: Adrian Klaver (#3)
Re: Strange behaviour on function

On 05/07/2023 17:16 CEST Adrian Klaver <adrian.klaver@aklaver.com> wrote:

https://www.postgresql.org/docs/current/plpgsql-trigger.html

1)
"A trigger function must return either NULL or a record/row value having
exactly the structure of the table the trigger was fired for."

2) I am not seeing where you use:

"TG_ARGV[]

Data type array of text; the arguments from the CREATE TRIGGER
statement. The index counts from 0. Invalid indexes (less than 0 or
greater than or equal to tg_nargs) result in a null value."

So I don't see how sqlstr is being set?

Domenico did not provide the trigger definition, only function bind_action
which he calls from a trigger function. Also bind_action cannot be a trigger
function because it does not return trigger.

--
Erik

#5Lorusso Domenico
domenico.l76@gmail.com
In reply to: Erik Wienhold (#2)
Re: Strange behaviour on function

yes!!
I solved using quote_nullable on hrec[k].

I was convinced string || NULL --> string

but I'm wrong.

Thanks!!

Il giorno mer 5 lug 2023 alle ore 15:53 Erik Wienhold <ewie@ewie.name> ha
scritto:

On 05/07/2023 14:23 CEST Lorusso Domenico <domenico.l76@gmail.com>

wrote:

Hello guys,
here a simple function

CREATE OR REPLACE FUNCTION bind_action(
sqlstr text,
hrec hstore)
RETURNS text
LANGUAGE 'plpgsql'
COST 100
immutable PARALLEL SAFE
AS $BODY$
declare
_sqlstr text=sqlstr;
_k text;
_debug text;
begin
_debug= '--Start' || _sqlstr;
foreach _k in array akeys(hrec) loop
_debug =_debug || format($$
hstore: %s %s
sqlStr:$$, _k, hrec[_k]);
_sqlstr=replace(_sqlstr, ':'||_k||':', hrec[_k]);
_debug =_debug || _sqlstr;

end loop;

raise notice 'final %',_debug;
return _sqlstr;
end;
$BODY$;

and here a simple test
do
$$
declare
sqlstr text=':id::bignt,:surpa:,:disfa:';
hs hstore;
begin
hs['id']=789;
hs['disfa']='ssssssss';
raise notice '%',bind_action(sqlstr,hs);
end;
$$;

and it works.
But...
When I call this function in a function called by a trigger it down't

work

_debug variable becomes null, also _sqlstr becomes null...

Does the hstore contain nulls? Function replace returns null in that case.

Please show us the trigger, its function, and a reproducer.

--
Erik

--
Domenico L.

per stupire mezz'ora basta un libro di storia,
io cercai di imparare la Treccani a memoria... [F.d.A.]

#6Lorusso Domenico
domenico.l76@gmail.com
In reply to: Erik Wienhold (#4)
Re: Strange behaviour on function

Erik, Adrian,

The trigger function is very long and complex (and not yet well
documented), but bind_action is a normal function callable everywhere, the
problem as discovered by Erik was in the null value contained in the hstore.

Anyway, when the ecosystem of functions will work correctly I can share, so
you can give me how improve :-D

Il giorno mer 5 lug 2023 alle ore 17:33 Erik Wienhold <ewie@ewie.name> ha
scritto:

On 05/07/2023 17:16 CEST Adrian Klaver <adrian.klaver@aklaver.com>

wrote:

https://www.postgresql.org/docs/current/plpgsql-trigger.html

1)
"A trigger function must return either NULL or a record/row value having
exactly the structure of the table the trigger was fired for."

2) I am not seeing where you use:

"TG_ARGV[]

Data type array of text; the arguments from the CREATE TRIGGER
statement. The index counts from 0. Invalid indexes (less than 0 or
greater than or equal to tg_nargs) result in a null value."

So I don't see how sqlstr is being set?

Domenico did not provide the trigger definition, only function bind_action
which he calls from a trigger function. Also bind_action cannot be a
trigger
function because it does not return trigger.

--
Erik

--
Domenico L.

per stupire mezz'ora basta un libro di storia,
io cercai di imparare la Treccani a memoria... [F.d.A.]