Re: BUG #13960: plpython fails with certain function names - Mailing list pgsql-bugs
| From | Tom Lane |
|---|---|
| Subject | Re: BUG #13960: plpython fails with certain function names |
| Date | |
| Msg-id | 25529.1455673778@sss.pgh.pa.us Whole thread Raw |
| In response to | Re: BUG #13960: plpython fails with certain function names (Jim Nasby <Jim.Nasby@BlueTreble.com>) |
| Responses |
Re: BUG #13960: plpython fails with certain function names
Re: BUG #13960: plpython fails with certain function names |
| List | pgsql-bugs |
Jim Nasby <Jim.Nasby@bluetreble.com> writes:
> On 2/14/16 7:09 PM, Tom Lane wrote:
>> Yeah, that's what I was thinking about. But yes, if we append the OID
>> anyway then we might as well just strip all non-alphanumeric chars
>> from the name. Safe and you still get some debuggability.
> Attached. I opted not to modify the name in-place. If it's safe to
> modify in place, might want to just replace invalid characters with '_'
> instead of making a copy.
I like the idea of replacing invalid characters with '_'. It's definitely
not safe to scribble on the pg_proc tuple, but we could get the same
result with a few wasted cycles by rescanning the procName string after
building it, as per attached.
regards, tom lane
diff --git a/src/pl/plpython/expected/plpython_test.out b/src/pl/plpython/expected/plpython_test.out
index 7b76faf..f8270a7 100644
*** a/src/pl/plpython/expected/plpython_test.out
--- b/src/pl/plpython/expected/plpython_test.out
*************** select stupidn();
*** 16,23 ****
zarkon
(1 row)
! -- test multiple arguments
! CREATE FUNCTION argument_test_one(u users, a1 text, a2 text) RETURNS text
AS
'keys = list(u.keys())
keys.sort()
--- 16,23 ----
zarkon
(1 row)
! -- test multiple arguments and odd characters in function name
! CREATE FUNCTION "Argument test #1"(u users, a1 text, a2 text) RETURNS text
AS
'keys = list(u.keys())
keys.sort()
*************** for key in keys:
*** 27,34 ****
words = a1 + " " + a2 + " => {" + ", ".join(out) + "}"
return words'
LANGUAGE plpythonu;
! select argument_test_one(users, fname, lname) from users where lname = 'doe' order by 1;
! argument_test_one
-----------------------------------------------------------------------
jane doe => {fname: jane, lname: doe, userid: 1, username: j_doe}
john doe => {fname: john, lname: doe, userid: 2, username: johnd}
--- 27,34 ----
words = a1 + " " + a2 + " => {" + ", ".join(out) + "}"
return words'
LANGUAGE plpythonu;
! select "Argument test #1"(users, fname, lname) from users where lname = 'doe' order by 1;
! Argument test #1
-----------------------------------------------------------------------
jane doe => {fname: jane, lname: doe, userid: 1, username: j_doe}
john doe => {fname: john, lname: doe, userid: 2, username: johnd}
diff --git a/src/pl/plpython/plpy_procedure.c b/src/pl/plpython/plpy_procedure.c
index e1f5620..a0d0792 100644
*** a/src/pl/plpython/plpy_procedure.c
--- b/src/pl/plpython/plpy_procedure.c
*************** PLy_procedure_create(HeapTuple procTup,
*** 146,151 ****
--- 146,152 ----
MemoryContext cxt;
MemoryContext oldcxt;
int rv;
+ char *ptr;
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
rv = snprintf(procName, sizeof(procName),
*************** PLy_procedure_create(HeapTuple procTup,
*** 155,160 ****
--- 156,170 ----
if (rv >= sizeof(procName) || rv < 0)
elog(ERROR, "procedure name would overrun buffer");
+ /* Replace any not-legal-in-Python-names characters with '_' */
+ for (ptr = procName; *ptr; ptr++)
+ {
+ if (!((*ptr >= 'A' && *ptr <= 'Z') ||
+ (*ptr >= 'a' && *ptr <= 'z') ||
+ (*ptr >= '0' && *ptr <= '9')))
+ *ptr = '_';
+ }
+
cxt = AllocSetContextCreate(TopMemoryContext,
procName,
ALLOCSET_DEFAULT_MINSIZE,
diff --git a/src/pl/plpython/sql/plpython_test.sql b/src/pl/plpython/sql/plpython_test.sql
index c8d5ef5..3a76104 100644
*** a/src/pl/plpython/sql/plpython_test.sql
--- b/src/pl/plpython/sql/plpython_test.sql
*************** CREATE FUNCTION stupidn() RETURNS text A
*** 11,18 ****
select stupidn();
! -- test multiple arguments
! CREATE FUNCTION argument_test_one(u users, a1 text, a2 text) RETURNS text
AS
'keys = list(u.keys())
keys.sort()
--- 11,18 ----
select stupidn();
! -- test multiple arguments and odd characters in function name
! CREATE FUNCTION "Argument test #1"(u users, a1 text, a2 text) RETURNS text
AS
'keys = list(u.keys())
keys.sort()
*************** words = a1 + " " + a2 + " => {" + ", ".j
*** 23,29 ****
return words'
LANGUAGE plpythonu;
! select argument_test_one(users, fname, lname) from users where lname = 'doe' order by 1;
-- check module contents
--- 23,29 ----
return words'
LANGUAGE plpythonu;
! select "Argument test #1"(users, fname, lname) from users where lname = 'doe' order by 1;
-- check module contents
pgsql-bugs by date: