summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2009-04-03 16:59:43 +0000
committerTom Lane2009-04-03 16:59:43 +0000
commitb231a2326cbc033e8bca516bf630fdf83806f819 (patch)
tree2a376b0b2e7e72ac0eb8c2f77151e19a15558e6f
parent81d06cf76d60c2d496c2d1b2dcd19b0ac3932922 (diff)
Defend against possible crash if a plpython function does not specify names
for its arguments. Also add a regression test, since someone apparently changed every single plpython test case to use only named parameters; else we'd have noticed this sooner. Euler Taveira de Oliveira, per a report from Alvaro
-rw-r--r--src/pl/plpython/expected/plpython_function.out5
-rw-r--r--src/pl/plpython/expected/plpython_test.out8
-rw-r--r--src/pl/plpython/plpython.c11
-rw-r--r--src/pl/plpython/sql/plpython_function.sql6
-rw-r--r--src/pl/plpython/sql/plpython_test.sql3
5 files changed, 25 insertions, 8 deletions
diff --git a/src/pl/plpython/expected/plpython_function.out b/src/pl/plpython/expected/plpython_function.out
index 4ace0445d9..79e225398e 100644
--- a/src/pl/plpython/expected/plpython_function.out
+++ b/src/pl/plpython/expected/plpython_function.out
@@ -357,8 +357,11 @@ CREATE FUNCTION test_return_none() RETURNS int AS $$
None
$$ LANGUAGE plpythonu;
--
--- Test named parameters
+-- Test named and nameless parameters
--
+CREATE FUNCTION test_param_names0(integer, integer) RETURNS int AS $$
+return args[0] + args[1]
+$$ LANGUAGE plpythonu;
CREATE FUNCTION test_param_names1(a0 integer, a1 text) RETURNS boolean AS $$
assert a0 == args[0]
assert a1 == args[1]
diff --git a/src/pl/plpython/expected/plpython_test.out b/src/pl/plpython/expected/plpython_test.out
index 3bba37cf50..b84660da43 100644
--- a/src/pl/plpython/expected/plpython_test.out
+++ b/src/pl/plpython/expected/plpython_test.out
@@ -197,7 +197,13 @@ SELECT test_return_none(), test_return_none() IS NULL AS "is null";
| t
(1 row)
--- Test for functions with named parameters
+-- Test for functions with named and nameless parameters
+SELECT test_param_names0(2,7);
+ test_param_names0
+-------------------
+ 9
+(1 row)
+
SELECT test_param_names1(1,'text');
test_param_names1
-------------------
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 5e3bbb938a..e29a02eb74 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -1052,9 +1052,11 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
arg = Py_None;
}
- if (PyList_SetItem(args, i, arg) == -1 ||
- (proc->argnames &&
- PyDict_SetItemString(proc->globals, proc->argnames[i], arg) == -1))
+ if (PyList_SetItem(args, i, arg) == -1)
+ PLy_elog(ERROR, "PyList_SetItem() failed for PL/Python function \"%s\" while setting up arguments", proc->proname);
+
+ if (proc->argnames && proc->argnames[i] &&
+ 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,7 +1083,8 @@ PLy_function_delete_args(PLyProcedure * proc)
return;
for (i = 0; i < proc->nargs; i++)
- PyDict_DelItemString(proc->globals, proc->argnames[i]);
+ if (proc->argnames[i])
+ PyDict_DelItemString(proc->globals, proc->argnames[i]);
}
diff --git a/src/pl/plpython/sql/plpython_function.sql b/src/pl/plpython/sql/plpython_function.sql
index cf01e8e0cd..a1544f3c42 100644
--- a/src/pl/plpython/sql/plpython_function.sql
+++ b/src/pl/plpython/sql/plpython_function.sql
@@ -391,8 +391,12 @@ $$ LANGUAGE plpythonu;
--
--- Test named parameters
+-- Test named and nameless parameters
--
+CREATE FUNCTION test_param_names0(integer, integer) RETURNS int AS $$
+return args[0] + args[1]
+$$ LANGUAGE plpythonu;
+
CREATE FUNCTION test_param_names1(a0 integer, a1 text) RETURNS boolean AS $$
assert a0 == args[0]
assert a1 == args[1]
diff --git a/src/pl/plpython/sql/plpython_test.sql b/src/pl/plpython/sql/plpython_test.sql
index f7321ab9e0..633d940e5d 100644
--- a/src/pl/plpython/sql/plpython_test.sql
+++ b/src/pl/plpython/sql/plpython_test.sql
@@ -74,7 +74,8 @@ SELECT test_void_func1(), test_void_func1() IS NULL AS "is null";
SELECT test_void_func2(); -- should fail
SELECT test_return_none(), test_return_none() IS NULL AS "is null";
--- Test for functions with named parameters
+-- Test for functions with named and nameless parameters
+SELECT test_param_names0(2,7);
SELECT test_param_names1(1,'text');
SELECT test_param_names2(users) from users;
SELECT test_param_names3(1);