aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-02-16 21:08:15 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2016-02-16 21:08:15 -0500
commit66f503868b2ac1163aaf48a2f76d8be02af0bc81 (patch)
treecc927ee3a7243d25b1c0bad5a18f17ae69292920 /src
parenta65313f28bfc264573a066271a11172d109dc2c4 (diff)
downloadpostgresql-66f503868b2ac1163aaf48a2f76d8be02af0bc81.tar.gz
postgresql-66f503868b2ac1163aaf48a2f76d8be02af0bc81.zip
Make plpython cope with funny characters in function names.
A function name that's double-quoted in SQL can contain almost any characters, but we were using that name directly as part of the name generated for the Python-level function, and Python doesn't like anything that isn't pretty much a standard identifier. To fix, replace anything that isn't an ASCII letter or digit with an underscore in the generated name. This doesn't create any risk of duplicate Python function names because we were already appending the function OID to the generated name to ensure uniqueness. Per bug #13960 from Jim Nasby. Patch by Jim Nasby, modified a bit by me. Back-patch to all supported branches.
Diffstat (limited to 'src')
-rw-r--r--src/pl/plpython/expected/plpython_test.out8
-rw-r--r--src/pl/plpython/plpy_procedure.c10
-rw-r--r--src/pl/plpython/sql/plpython_test.sql6
3 files changed, 17 insertions, 7 deletions
diff --git a/src/pl/plpython/expected/plpython_test.out b/src/pl/plpython/expected/plpython_test.out
index 7b76faf4ee6..f8270a7c5ad 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 e1f56209ef0..a0d0792297a 100644
--- a/src/pl/plpython/plpy_procedure.c
+++ b/src/pl/plpython/plpy_procedure.c
@@ -146,6 +146,7 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
MemoryContext cxt;
MemoryContext oldcxt;
int rv;
+ char *ptr;
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
rv = snprintf(procName, sizeof(procName),
@@ -155,6 +156,15 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
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 c8d5ef5f534..3a761047a09 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