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 @@ -16,8 +16,8 @@ select stupidn(); zarkon (1 row) --- test multiple arguments -CREATE FUNCTION argument_test_one(u users, a1 text, a2 text) RETURNS text +-- 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() @@ -27,8 +27,8 @@ for key in keys: 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 +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..4bfc43d 100644 --- a/src/pl/plpython/plpy_procedure.c +++ b/src/pl/plpython/plpy_procedure.c @@ -141,6 +141,8 @@ static PLyProcedure * PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger) { char procName[NAMEDATALEN + 256]; + char rawProcName[NAMEDATALEN]; + char *ptr, *ptr2; Form_pg_proc procStruct; PLyProcedure *volatile proc; MemoryContext cxt; @@ -148,9 +150,22 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger) int rv; procStruct = (Form_pg_proc) GETSTRUCT(procTup); + + /* Swap invalid chars with '_' before building full name */ + ptr = NameStr(procStruct->proname); + ptr2 = rawProcName; + while (*ptr) + { + if ( (*ptr >= 'A' && *ptr <= 'Z' ) || + (*ptr >= 'a' && *ptr <= 'z' ) || + (*ptr >= '0' && *ptr <= '9' ) ) + *ptr2++ = *ptr; + ptr++; + } + *ptr2 = 0; rv = snprintf(procName, sizeof(procName), "__plpython_procedure_%s_%u", - NameStr(procStruct->proname), + rawProcName, fn_oid); if (rv >= sizeof(procName) || rv < 0) elog(ERROR, "procedure name would overrun buffer"); 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 @@ -11,8 +11,8 @@ CREATE FUNCTION stupidn() RETURNS text AS 'return "zarkon"' LANGUAGE plpython2u; select stupidn(); --- test multiple arguments -CREATE FUNCTION argument_test_one(u users, a1 text, a2 text) RETURNS text +-- 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() @@ -23,7 +23,7 @@ words = a1 + " " + a2 + " => {" + ", ".join(out) + "}" return words' LANGUAGE plpythonu; -select argument_test_one(users, fname, lname) from users where lname = 'doe' order by 1; +select "Argument test #1"(users, fname, lname) from users where lname = 'doe' order by 1; -- check module contents