Thread: Plpython bug with int8?

Plpython bug with int8?

From
Bradley McLean
Date:
Can someone else run this and confirm the results against the tip
of the CVS repository?

I'm trying to trace this bug (help welcome too).

(it was hidden in a trigger and a pain to narrow to this point)
-Brad

-----

drop function mul1(int4,int4);
drop function mul2(int4,int4);
drop function callmul1();
drop function callmul2a();
drop function callmul2b();
create function mul1(int4,int4) returns int8 as 'select int8($1) * int8($2)' language 'sql';
create function mul2(int4,int4) returns int8 as 'select int8($1) * 4294967296::int8 + int8($2)' language 'sql';
create function callmul1() returns int8 as 'return plpy.execute("select mul1(6,7) as x")[0]["x"]' language 'plpython';
create function callmul2a() returns int8 as 'select mul2(7,8)' language 'sql';
create function callmul2b() returns int8 as 'return plpy.execute("select mul2(7,8) as x")[0]["x"]' language
'plpython';
select mul1(3,4);
select callmul1();
select mul2(5,6);
select callmul2a();
select callmul2b();

Results:

...callmul1 
----------      42
(1 row)
   mul2     
-------------21474836486
(1 row)
 callmul2a  
-------------30064771080
(1 row)

psql:bug:14: pqReadData() -- backend closed the channel unexpectedly.This probably means the backend terminated
abnormallybeforeor while processing the request.
 
psql:bug:14: connection to server was lost


Re: Plpython bug with int8 - Found, need advice

From
Bradley McLean
Date:
Replying to my own method.

In src/pl/plpython/plpython.c around line 1381, PLy_input_datum_func2
erroneously assigns PLyInt_FromString to handle int8 types.

Because PLyInt_FromString uses strtol at line 1461, it fails as
soon as you pass it a parameter exceed the bounds of an int4.

There are two problems to solve here:

1)  All of the conversion functions that return NULL ( line 1463 as
an example, page up and down from there) will cause the backend to terminate
abnormally.  I'm not sure if this is considered a correct behavior,
or if elog(ERROR, ...) is a better approach.  Comments?

2) I need an input conversion from string to int8, like perhaps
PLyLongLong_FromString() as an proposal.  src/backend/utils
/adt/int8.c has one, but it's not really well designed for access
from C.  Should I duplicate the functionality, figure out how to
wrap it for the call from plpython.c, or is there an existing
standard for factoring the body of the int8in function into a
widely available utility location.

Hope those questions are clear.  I'd like to get a patch in
before Beta.

-Brad

* Bradley McLean (brad@bradm.net) [010929 01:55]:
> Can someone else run this and confirm the results against the tip
> of the CVS repository?
> 
> I'm trying to trace this bug (help welcome too).
> 
> (it was hidden in a trigger and a pain to narrow to this point)
> -Brad
> 
> -----
> 
> drop function mul1(int4,int4);
> drop function mul2(int4,int4);
> drop function callmul1();
> drop function callmul2a();
> drop function callmul2b();
> create function mul1(int4,int4) returns int8 as 'select int8($1) * int8($2)' language 'sql';
> create function mul2(int4,int4) returns int8 as 'select int8($1) * 4294967296::int8 + int8($2)' language 'sql';
> create function callmul1() returns int8 as 'return plpy.execute("select mul1(6,7) as x")[0]["x"]' language
'plpython';
> create function callmul2a() returns int8 as 'select mul2(7,8)' language 'sql';
> create function callmul2b() returns int8 as 'return plpy.execute("select mul2(7,8) as x")[0]["x"]' language
'plpython';
> select mul1(3,4);
> select callmul1();
> select mul2(5,6);
> select callmul2a();
> select callmul2b();
> 
> Results:
> 
> ...
>  callmul1 
> ----------
>        42
> (1 row)
> 
>     mul2     
> -------------
>  21474836486
> (1 row)
> 
>   callmul2a  
> -------------
>  30064771080
> (1 row)
> 
> psql:bug:14: pqReadData() -- backend closed the channel unexpectedly.
>     This probably means the backend terminated abnormally
>     before or while processing the request.
> psql:bug:14: connection to server was lost
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)


Re: Plpython bug with int8 - Found, need advice

From
Tom Lane
Date:
Bradley McLean <brad@bradm.net> writes:
> 1)  All of the conversion functions that return NULL ( line 1463 as
> an example, page up and down from there) will cause the backend to terminate
> abnormally.  I'm not sure if this is considered a correct behavior,
> or if elog(ERROR, ...) is a better approach.  Comments?

Backend coredump is never a correct behavior.  I'd recommend elog ...
        regards, tom lane