Re: can't load plpython - Mailing list pgsql-hackers
| From | Euler Taveira de Oliveira |
|---|---|
| Subject | Re: can't load plpython |
| Date | |
| Msg-id | 49D268C3.8060503@timbira.com Whole thread Raw |
| In response to | Re: can't load plpython (Alvaro Herrera <alvherre@commandprompt.com>) |
| Responses |
Re: can't load plpython
|
| List | pgsql-hackers |
Alvaro Herrera escreveu:
> Euler Taveira de Oliveira wrote:
>> Tom Lane escreveu:
>>> Alvaro Herrera <alvherre@commandprompt.com> writes:
>>>> ... However, on HEAD this is crashing for me, and it's right when plpython
>>>> loads. Backtrace below.
>>> Does plpython pass its regression tests for you (I'd suppose not)?
>>>
>>> For me on Fedora 10 x86_64, CVS HEAD plus python 2.5.2 passes regression
>>> but the given example still dumps core. postmaster log says
>>>
>>> postgres: tgl regression [local] SELECT: Objects/stringobject.c:107: PyString_FromString: Assertion `str != ((void
*)0)'failed.
>>> LOG: server process (PID 4714) was terminated by signal 6: Aborted
>>> LOG: terminating any other active server processes
>>>
>> PyString_FromString() [1] fails to return something useful, i.e, null pointer
>> when its argument is null. The trivial fix (that is attached) is to ensure
>> that we don't pass a null pointer as the second argument of
>> PyDict_SetItemString(). Of course, it's a Python bug and I filled it [3].
>
> I'm not sure I'm reading this right, but isn't this preventing a
> plpytHon function to work if parameters don't have names assigned?
No. See the proc->argnames test before PyDict_SetItemString(). The other test
is just tightening the check.
Indeed, the PyDict_*ItemString() functions suffer from the same disease. :( I
reported upstream too.
Attached is another patch that add another test before PyDict_DelItemString();
it's safe because if we don't have a key we don't know what to remove.
Here is my test case (I'm not a python programmer, sorry!).
euler@harman $ cat /tmp/{f,g}.sql
create or replace function unaccent(text) returns text language plpythonu as $$
import unicodedata
s = unicodedata.normalize("NFKD", args[0])
s = ''.join(c for c in s if ord(c) < 127)
return s
$$ ;
drop function add(int, int);
drop function add2(int, int);
create or replace function add(a int, b int) returns int language plpythonu as $$
return a + b
$$ ;
create or replace function add2(int, int) returns int language plpythonu as $$
return args[0] + args[1]
$$ ;
euler@harman $ ./install/bin/psql
psql (8.4devel)
Type "help" for help.
euler=# select unaccent('até');
NOTA: PL/Python: args[0]: (null)
ERRO: PL/Python: PL/Python function "unaccent" failed
DETALHE: <type 'exceptions.TypeError'>: normalize() argument 2 must be
unicode, not str
euler=# select add(1,2);
NOTA: PL/Python: args[0]: a
NOTA: PL/Python: args[1]: b
NOTA: PL/Python: args[0]: a
NOTA: PL/Python: args[1]: b
add
-----
3
(1 registro)
euler=# select add2(1,2);
NOTA: PL/Python: args[0]: (null)
NOTA: PL/Python: args[1]: (null)
NOTA: PL/Python: args[0]: (null)
NOTA: PL/Python: args[1]: (null)
add2
------
3
(1 registro)
--
Euler Taveira de Oliveira
http://www.timbira.com/
Index: plpython.c
===================================================================
RCS file: /a/pgsql/dev/anoncvs/pgsql/src/pl/plpython/plpython.c,v
retrieving revision 1.118
diff -c -r1.118 plpython.c
*** plpython.c 15 Jan 2009 13:49:56 -0000 1.118
--- plpython.c 31 Mar 2009 18:50:54 -0000
***************
*** 1053,1059 ****
}
if (PyList_SetItem(args, i, arg) == -1 ||
! (proc->argnames &&
PyDict_SetItemString(proc->globals, proc->argnames[i], arg) == -1))
PLy_elog(ERROR, "PyDict_SetItemString() failed for PL/Python function \"%s\" while setting up
arguments",proc->proname);
arg = NULL;
--- 1053,1059 ----
}
if (PyList_SetItem(args, i, arg) == -1 ||
! (proc->argnames && proc->argnames[i] != NULL &&
PyDict_SetItemString(proc->globals, proc->argnames[i], arg) == -1))
PLy_elog(ERROR, "PyDict_SetItemString() failed for PL/Python function \"%s\" while setting up
arguments",proc->proname);
arg = NULL;
***************
*** 1081,1087 ****
return;
for (i = 0; i < proc->nargs; i++)
! PyDict_DelItemString(proc->globals, proc->argnames[i]);
}
--- 1081,1088 ----
return;
for (i = 0; i < proc->nargs; i++)
! if (proc->argnames[i] != NULL)
! PyDict_DelItemString(proc->globals, proc->argnames[i]);
}
pgsql-hackers by date: