Changeset: c9cd76227bde for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c9cd76227bde Added Files: sql/backends/monet5/Tests/pyapi18.sql sql/backends/monet5/Tests/pyapi18.stable.err sql/backends/monet5/Tests/pyapi18.stable.out sql/backends/monet5/Tests/pyapi19.sql sql/backends/monet5/Tests/pyapi19.stable.err sql/backends/monet5/Tests/pyapi19.stable.out Modified Files: monetdb5/extras/pyapi/pyapi.c Branch: pyapi Log Message:
Throw error when user tries to store input argument in _values dictionary. diffs (truncated from 346 to 300 lines): diff --git a/monetdb5/extras/pyapi/pyapi.c b/monetdb5/extras/pyapi/pyapi.c --- a/monetdb5/extras/pyapi/pyapi.c +++ b/monetdb5/extras/pyapi/pyapi.c @@ -868,6 +868,21 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb // The function has been successfully created/compiled, all that remains is to actually call the function pResult = PyObject_CallObject(pFunc, pArgs); + { + //check the _values dictionary to see if any of the stored values are input values + PyObject *key, *value; + Py_ssize_t pos = 0; + while (PyDict_Next(pDict, &pos, &key, &value)) { + for(i = 0; i < pci->argc - (pci->retc + 2); i ++) { + PyObject *arg = PyTuple_GetItem(pArgs, i); + if (arg == value) { + msg = createException(MAL, "pyapi.eval", "You cannot directly store input arguments in the _values dictionary, instead use _values[key] = numpy.copy(input)."); + goto wrapup; + } + } + } + } + Py_DECREF(pFunc); Py_DECREF(pArgs); Py_DECREF(pColumns); diff --git a/sql/backends/monet5/Tests/pyapi18.sql b/sql/backends/monet5/Tests/pyapi18.sql new file mode 100644 --- /dev/null +++ b/sql/backends/monet5/Tests/pyapi18.sql @@ -0,0 +1,22 @@ +START TRANSACTION; + +CREATE TABLE vals(i INTEGER); +INSERT INTO vals VALUES (1), (2), (3), (4), (5), (6), (7); + +CREATE FUNCTION pyapi18a(i integer) returns integer +language P +{ + _values['number'] = 42 + return(i) +}; + +CREATE FUNCTION pyapi18b(i integer) returns integer +language P +{ + return _values['number'] * i +}; +SELECT pyapi18b(pyapi18a(i)) FROM vals; +DROP FUNCTION pyapi18a; DROP FUNCTION pyapi18b; +DROP TABLE vals; + +ROLLBACK; diff --git a/sql/backends/monet5/Tests/pyapi18.stable.err b/sql/backends/monet5/Tests/pyapi18.stable.err new file mode 100644 --- /dev/null +++ b/sql/backends/monet5/Tests/pyapi18.stable.err @@ -0,0 +1,38 @@ +stderr of test 'pyapi18` in directory 'sql/backends/monet5` itself: + + +# 11:47:23 > +# 11:47:23 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=38937" "--set" "mapi_usock=/var/tmp/mtest-3052/.s.monetdb.38937" "--set" "monet_prompt=" "--forcemito" "--set" "mal_listing=2" "--dbpath=/home/mytherin/opt/var/MonetDB/mTests_sql_backends_monet5" "--set" "mal_listing=0" "--set" "embedded_r=true" "--set" "embedded_py=true" +# 11:47:23 > + +# builtin opt gdk_dbpath = /home/mytherin/opt/var/monetdb5/dbfarm/demo +# builtin opt gdk_debug = 0 +# builtin opt gdk_vmtrim = no +# builtin opt monet_prompt = > +# builtin opt monet_daemon = no +# builtin opt mapi_port = 50000 +# builtin opt mapi_open = false +# builtin opt mapi_autosense = false +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# cmdline opt gdk_nr_threads = 0 +# cmdline opt mapi_open = true +# cmdline opt mapi_port = 38937 +# cmdline opt mapi_usock = /var/tmp/mtest-3052/.s.monetdb.38937 +# cmdline opt monet_prompt = +# cmdline opt mal_listing = 2 +# cmdline opt gdk_dbpath = /home/mytherin/opt/var/MonetDB/mTests_sql_backends_monet5 +# cmdline opt mal_listing = 0 +# cmdline opt embedded_r = true +# cmdline opt embedded_py = true +# cmdline opt gdk_debug = 536870922 + +# 11:47:23 > +# 11:47:23 > "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-3052" "--port=38937" +# 11:47:23 > + + +# 11:47:59 > +# 11:47:59 > "Done." +# 11:47:59 > + diff --git a/sql/backends/monet5/Tests/pyapi18.stable.out b/sql/backends/monet5/Tests/pyapi18.stable.out new file mode 100644 --- /dev/null +++ b/sql/backends/monet5/Tests/pyapi18.stable.out @@ -0,0 +1,63 @@ +stdout of test 'pyapi18` in directory 'sql/backends/monet5` itself: + + +# 11:47:23 > +# 11:47:23 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=38937" "--set" "mapi_usock=/var/tmp/mtest-3052/.s.monetdb.38937" "--set" "monet_prompt=" "--forcemito" "--set" "mal_listing=2" "--dbpath=/home/mytherin/opt/var/MonetDB/mTests_sql_backends_monet5" "--set" "mal_listing=0" "--set" "embedded_r=true" "--set" "embedded_py=true" +# 11:47:23 > + +# MonetDB 5 server v11.22.0 +# This is an unreleased version +# Serving database 'mTests_sql_backends_monet5', using 8 threads +# Compiled for x86_64-unknown-linux-gnu/64bit with 64bit OIDs and 128bit integers dynamically linked +# Found 7.684 GiB available main-memory. +# Copyright (c) 1993-July 2008 CWI. +# Copyright (c) August 2008-2015 MonetDB B.V., all rights reserved +# Visit http://www.monetdb.org/ for further information +# Listening for connection requests on mapi:monetdb://mytherin-N750JV:38937/ +# Listening for UNIX domain connection requests on mapi:monetdb:///var/tmp/mtest-3052/.s.monetdb.38937 +# Start processing logs sql/sql_logs version 52200 +# Finished processing logs sql/sql_logs +# MonetDB/SQL module loaded +# MonetDB/Python module loaded +# MonetDB/R module loaded + +Ready. + +# 11:47:23 > +# 11:47:23 > "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-3052" "--port=38937" +# 11:47:23 > + +#START TRANSACTION; +#CREATE TABLE vals(i INTEGER); +#INSERT INTO vals VALUES (1), (2), (3), (4), (5), (6), (7); +[ 7 ] +#CREATE FUNCTION pyapi18_a(i integer) returns integer +#language P +#{ +# _values['number'] = 42 +# return(i) +#}; +#CREATE FUNCTION pyapi18_b(i integer) returns integer +#language P +#{ +# return _values['number'] * i +#}; +#SELECT pyapi18_b(pyapi18_a(i)) FROM vals; +% sys.L # table_name +% pyapi18b_pyapi18a_i # name +% int # type +% 3 # length +[ 42 ] +[ 84 ] +[ 126 ] +[ 168 ] +[ 210 ] +[ 252 ] +[ 294 ] +#DROP FUNCTION pyapi18_a; DROP FUNCTION pyapi18_b; +#DROP FUNCTION pyapi18_a; DROP FUNCTION pyapi18_b; + +# 11:47:23 > +# 11:47:23 > "Done." +# 11:47:23 > + diff --git a/sql/backends/monet5/Tests/pyapi19.sql b/sql/backends/monet5/Tests/pyapi19.sql new file mode 100644 --- /dev/null +++ b/sql/backends/monet5/Tests/pyapi19.sql @@ -0,0 +1,39 @@ +START TRANSACTION; + +CREATE TABLE vals(i INTEGER); +INSERT INTO vals VALUES (1), (2), (3), (4), (5), (6), (7); + +# Directly store input in the dictionary doesn't work (because we do zero copy) +CREATE FUNCTION pyapi19a(i integer) returns integer +language P +{ + _values['array'] = i; + return(i * 2) +}; +SELECT pyapi19a(i * 2) FROM vals; #so this throws an error +ROLLBACK; + +START TRANSACTION; +CREATE TABLE vals(i INTEGER); +INSERT INTO vals VALUES (1), (2), (3), (4), (5), (6), (7); + +# Correct way of doing it +CREATE FUNCTION pyapi19a(i integer) returns integer +language P +{ + _values['array'] = numpy.copy(i); + return(i * 2) +}; +CREATE FUNCTION pyapi19b(i integer) returns integer +language P +{ + return _values['array'] * 2 +}; + +SELECT pyapi19a(i) FROM vals; #so this throws an error +SELECT pyapi19b(i) FROM vals; + +DROP FUNCTION pyapi19a; DROP FUNCTION pyapi19b; +DROP TABLE vals; + +ROLLBACK; diff --git a/sql/backends/monet5/Tests/pyapi19.stable.err b/sql/backends/monet5/Tests/pyapi19.stable.err new file mode 100644 --- /dev/null +++ b/sql/backends/monet5/Tests/pyapi19.stable.err @@ -0,0 +1,41 @@ +stderr of test 'pyapi19` in directory 'sql/backends/monet5` itself: + + +# 12:13:29 > +# 12:13:29 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=30774" "--set" "mapi_usock=/var/tmp/mtest-6324/.s.monetdb.30774" "--set" "monet_prompt=" "--forcemito" "--set" "mal_listing=2" "--dbpath=/home/mytherin/opt/var/MonetDB/mTests_sql_backends_monet5" "--set" "mal_listing=0" "--set" "embedded_r=true" "--set" "embedded_py=true" +# 12:13:29 > + +# builtin opt gdk_dbpath = /home/mytherin/opt/var/monetdb5/dbfarm/demo +# builtin opt gdk_debug = 0 +# builtin opt gdk_vmtrim = no +# builtin opt monet_prompt = > +# builtin opt monet_daemon = no +# builtin opt mapi_port = 50000 +# builtin opt mapi_open = false +# builtin opt mapi_autosense = false +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# cmdline opt gdk_nr_threads = 0 +# cmdline opt mapi_open = true +# cmdline opt mapi_port = 30774 +# cmdline opt mapi_usock = /var/tmp/mtest-6324/.s.monetdb.30774 +# cmdline opt monet_prompt = +# cmdline opt mal_listing = 2 +# cmdline opt gdk_dbpath = /home/mytherin/opt/var/MonetDB/mTests_sql_backends_monet5 +# cmdline opt mal_listing = 0 +# cmdline opt embedded_r = true +# cmdline opt embedded_py = true +# cmdline opt gdk_debug = 536870922 + +# 12:13:29 > +# 12:13:29 > "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-6324" "--port=30774" +# 12:13:29 > + +MAPI = (monetdb) /var/tmp/mtest-6324/.s.monetdb.30774 +QUERY = SELECT pyapi19a(i * 2) FROM vals; #so this throws an error +ERROR = !You cannot directly store input arguments in the _values dictionary, instead use _values[key] = numpy.copy(input). + +# 12:13:29 > +# 12:13:29 > "Done." +# 12:13:29 > + diff --git a/sql/backends/monet5/Tests/pyapi19.stable.out b/sql/backends/monet5/Tests/pyapi19.stable.out new file mode 100644 --- /dev/null +++ b/sql/backends/monet5/Tests/pyapi19.stable.out @@ -0,0 +1,88 @@ +stdout of test 'pyapi19` in directory 'sql/backends/monet5` itself: + + +# 12:13:29 > +# 12:13:29 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=30774" "--set" "mapi_usock=/var/tmp/mtest-6324/.s.monetdb.30774" "--set" "monet_prompt=" "--forcemito" "--set" "mal_listing=2" "--dbpath=/home/mytherin/opt/var/MonetDB/mTests_sql_backends_monet5" "--set" "mal_listing=0" "--set" "embedded_r=true" "--set" "embedded_py=true" +# 12:13:29 > + +# MonetDB 5 server v11.22.0 +# This is an unreleased version +# Serving database 'mTests_sql_backends_monet5', using 8 threads +# Compiled for x86_64-unknown-linux-gnu/64bit with 64bit OIDs and 128bit integers dynamically linked +# Found 7.684 GiB available main-memory. +# Copyright (c) 1993-July 2008 CWI. +# Copyright (c) August 2008-2015 MonetDB B.V., all rights reserved +# Visit http://www.monetdb.org/ for further information +# Listening for connection requests on mapi:monetdb://mytherin-N750JV:30774/ +# Listening for UNIX domain connection requests on mapi:monetdb:///var/tmp/mtest-6324/.s.monetdb.30774 +# Start processing logs sql/sql_logs version 52200 +# Finished processing logs sql/sql_logs +# MonetDB/SQL module loaded +# MonetDB/Python module loaded +# MonetDB/R module loaded + +Ready. + +# 12:13:29 > +# 12:13:29 > "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-6324" "--port=30774" +# 12:13:29 > + +#START TRANSACTION; +#CREATE TABLE vals(i INTEGER); +#INSERT INTO vals VALUES (1), (2), (3), (4), (5), (6), (7); +[ 7 ] +#CREATE FUNCTION pyapi19a(i integer) returns integer +#language P +#{ +# _values['array'] = i; +# return(i * 2) +#}; +#ROLLBACK; +#START TRANSACTION; +#CREATE TABLE vals(i INTEGER); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list