]> granicus.if.org Git - postgresql/commitdiff
Make plpython cope with funny characters in function names.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 17 Feb 2016 02:08:15 +0000 (21:08 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 17 Feb 2016 02:08:15 +0000 (21:08 -0500)
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.

src/pl/plpython/expected/plpython_test.out
src/pl/plpython/plpython.c
src/pl/plpython/sql/plpython_test.sql

index f2dda66532e525f1ae79a9d92beb4bdde6cd51bd..46392e420e90355035c852fafc4e1c949921fcea 100644 (file)
@@ -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}
index 3db6f7d23a72a80c2b806227c1afd84d3f9bd4ec..7dd59783b4397adfcb872e912d38d6328e5e0c77 100644 (file)
@@ -1612,6 +1612,7 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
        bool            isnull;
        int                     i,
                                rv;
+       char       *ptr;
 
        procStruct = (Form_pg_proc) GETSTRUCT(procTup);
        rv = snprintf(procName, sizeof(procName),
@@ -1621,6 +1622,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 = '_';
+       }
+
        proc = PLy_malloc(sizeof(PLyProcedure));
        proc->proname = PLy_strdup(NameStr(procStruct->proname));
        proc->pyname = PLy_strdup(procName);
index c8d5ef5f534613320f857863ade9d39cdb7287e1..3a761047a09119ce60f9d35f3a68cb5b60bbed44 100644 (file)
@@ -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