Changeset: 1e3eeda6fd33 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1e3eeda6fd33 Modified Files: monetdb5/extras/pyapi/Tests/pyapi_types_huge.malC monetdb5/extras/pyapi/formatinput.c monetdb5/extras/pyapi/pyapi.c sql/backends/monet5/Tests/All Branch: pyapi Log Message:
Added _values dictionary that users can use to store values between PyAPI function calls. diffs (157 lines): diff --git a/monetdb5/extras/pyapi/Tests/pyapi_types_huge.malC b/monetdb5/extras/pyapi/Tests/pyapi_types_huge.malC --- a/monetdb5/extras/pyapi/Tests/pyapi_types_huge.malC +++ b/monetdb5/extras/pyapi/Tests/pyapi_types_huge.malC @@ -22,48 +22,3 @@ io.print(rhge, shge); # convert double to huge (rhge:bat[:oid,:hge], shge:bat[:oid,:hge]) := pyapi.eval(nil:ptr,"return(numpy.array([[3200.3,12.7],[44.1,22.8]]))",bhge); io.print(rhge, shge); - -# convert hge to string -rhge:bat[:oid,:str] := pyapi.eval(nil:ptr,"return(arg1)",bhge); -io.print(rhge); - -# convert string to hge -bstr:= bat.new(:oid,:str); -bat.append(bstr,"412412":str); -bat.append(bstr,"13231414":str); -bat.append(bstr,"895233278923448975389573895731":str); -rhge:bat[:oid,:hge] := pyapi.eval(nil:ptr,"return(arg1)", bstr); -io.print(rhge); - - -# return multidimensional huge -(rhge:bat[:oid,:hge], shge:bat[:oid,:hge]) := pyapi.eval(nil:ptr,"return(numpy.ma.masked_array([arg1, arg1], [arg1.mask,arg1.mask]))",bhge); -io.print(rhge, shge); - -z:= bat.new(:oid,:hge); -bat.append(z,44:hge); -bat.append(z,22:hge); -bat.append(z,11:hge); -bat.append(z,23:hge); -bat.append(z,nil:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); -bat.append(z,23:hge); - -# convert huge to int -rint:bat[:oid,:int] := pyapi.eval(nil:ptr,"return(arg1)",z); -io.print(rint); - - -# convert huge to double -rdbl:bat[:oid,:dbl] := pyapi.eval(nil:ptr,"return(arg1)",z); -io.print(rdbl); - diff --git a/monetdb5/extras/pyapi/formatinput.c b/monetdb5/extras/pyapi/formatinput.c --- a/monetdb5/extras/pyapi/formatinput.c +++ b/monetdb5/extras/pyapi/formatinput.c @@ -10,8 +10,8 @@ #include "gdk.h" #include "mal_exception.h" -const size_t additional_argcount = 2; -const char * additional_args[] = {"_columns", "_column_types"}; +const size_t additional_argcount = 3; +const char * additional_args[] = {"_columns", "_column_types", "_values"}; //! Parse a PyCodeObject from a string, the string is expected to be in the format {@<encoded_function>};, where <encoded_function> is all the PyCodeObject properties in order PyObject *PyCodeObject_ParseString(char *string, char **msg); 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 @@ -86,6 +86,37 @@ int PyAPIEnabled(void) { static MT_Lock pyapiLock; static int pyapiInitialized = FALSE; + +static PyObject **dictionaries = NULL; +static Client *clients = NULL; +static int dictionary_count = 0, max_dictionaries = 0; + +static PyObject *GetDictionary(Client c) +{ + int i = 0; + for(i = 0; i < dictionary_count; i++) { + if (clients[i] == c) { + return dictionaries[i]; + } + } + + if (dictionary_count >= max_dictionaries) { + PyObject **new_dictionaries = GDKzalloc((max_dictionaries + 2) * sizeof(PyObject*)); + Client *new_clients = GDKzalloc((max_dictionaries + 2) * sizeof(Client)); + for(i = 0; i < dictionary_count; i++) { + new_dictionaries[i] = dictionaries[i]; + new_clients[i] = clients[i]; + } + if (clients != NULL) { GDKfree(clients); GDKfree(dictionaries); } + dictionaries = new_dictionaries; clients = new_clients; + } + + clients[dictionary_count] = c; + dictionaries[dictionary_count] = PyDict_New(); + dictionary_count++; + return dictionaries[dictionary_count - 1]; +} + #ifdef _PYAPI_TESTING_ // This #define converts a BAT 'bat' of BAT type 'TYPE_mtpe' to a Numpy array of type 'nptpe' // This only works with numeric types (bit, byte, int, long, float, double), strings are handled separately @@ -372,7 +403,7 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb BAT *b = NULL; node * argnode; int seengrp = FALSE; - PyObject *pArgs = NULL, *pColumns = NULL, *pColumnTypes = NULL, *pResult = NULL; // this is going to be the parameter tuple + PyObject *pArgs = NULL, *pColumns = NULL, *pColumnTypes = NULL, *pDict = NULL, *pResult = NULL; // this is going to be the parameter tuple PyObject *code_object = NULL; PyReturn *pyreturn_values = NULL; PyInput *pyinput_values = NULL; @@ -733,9 +764,10 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb // Now we will do the input handling (aka converting the input BATs to numpy arrays) // We will put the python arrays in a PyTuple object, we will use this PyTuple object as the set of arguments to call the Python function - pArgs = PyTuple_New(pci->argc - (pci->retc + 2) + (code_object == NULL ? 2 : 0)); + pArgs = PyTuple_New(pci->argc - (pci->retc + 2) + (code_object == NULL ? 3 : 0)); pColumns = PyDict_New(); pColumnTypes = PyDict_New(); + pDict = GetDictionary(cntxt); // Now we will loop over the input BATs and convert them to python objects for (i = pci->retc + 2; i < pci->argc; i++) { @@ -790,6 +822,8 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb if (code_object == NULL) { PyTuple_SetItem(pArgs, ai++, pColumns); PyTuple_SetItem(pArgs, ai++, pColumnTypes); + PyTuple_SetItem(pArgs, ai++, pDict); + Py_INCREF(pDict); } /*[EXECUTE_CODE]*/ @@ -845,7 +879,7 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb goto wrapup; } - if (code_object == NULL) { PyRun_SimpleString("del pyfun"); } + //if (code_object == NULL) { PyRun_SimpleString("del pyfun"); } if (PyDict_Check(pResult)) { // Handle dictionary returns // For dictionary returns we need to map each of the (key,value) pairs to the proper return value diff --git a/sql/backends/monet5/Tests/All b/sql/backends/monet5/Tests/All --- a/sql/backends/monet5/Tests/All +++ b/sql/backends/monet5/Tests/All @@ -16,6 +16,7 @@ HAVE_LIBPY?pyapi13 HAVE_LIBPY?pyapi14 HAVE_LIBPY?pyapi16 HAVE_LIBPY?pyapi17 +HAVE_LIBPY?pyapi18 #HAVE_LIBR?rapi00 #HAVE_LIBR?rapi01 _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list