Changeset: ef65f7c2e378 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ef65f7c2e378 Modified Files: sql/backends/monet5/UDF/pyapi/connection.c sql/backends/monet5/UDF/pyapi/connection.h sql/backends/monet5/UDF/pyapi/conversion.c sql/backends/monet5/UDF/pyapi/conversion.h sql/backends/monet5/UDF/pyapi/convert_loops.h sql/backends/monet5/UDF/pyapi/emit.c sql/backends/monet5/UDF/pyapi/emit.h sql/backends/monet5/UDF/pyapi/formatinput.c sql/backends/monet5/UDF/pyapi/formatinput.h sql/backends/monet5/UDF/pyapi/pyapi.c sql/backends/monet5/UDF/pyapi/pyapi.h sql/backends/monet5/UDF/pyapi/pyheader.h sql/backends/monet5/UDF/pyapi/pyloader.c sql/backends/monet5/UDF/pyapi/pytypes.c sql/backends/monet5/UDF/pyapi/pytypes.h sql/backends/monet5/UDF/pyapi/type_conversion.c sql/backends/monet5/UDF/pyapi/type_conversion.h sql/backends/monet5/UDF/pyapi/undef.h sql/backends/monet5/UDF/pyapi/unicode.c sql/backends/monet5/UDF/pyapi/unicode.h Branch: default Log Message:
Merge heads. diffs (truncated from 9831 to 300 lines): diff --git a/sql/backends/monet5/UDF/pyapi/connection.c b/sql/backends/monet5/UDF/pyapi/connection.c --- a/sql/backends/monet5/UDF/pyapi/connection.c +++ b/sql/backends/monet5/UDF/pyapi/connection.c @@ -13,269 +13,281 @@ #include "type_conversion.h" #include "gdk_interprocess.h" -CREATE_SQL_FUNCTION_PTR(void,SQLdestroyResult); -CREATE_SQL_FUNCTION_PTR(str,SQLstatementIntern); -CREATE_SQL_FUNCTION_PTR(str,create_table_from_emit); +CREATE_SQL_FUNCTION_PTR(void, SQLdestroyResult); +CREATE_SQL_FUNCTION_PTR(str, SQLstatementIntern); +CREATE_SQL_FUNCTION_PTR(str, create_table_from_emit); -static PyObject * -_connection_execute(Py_ConnectionObject *self, PyObject *args) +static PyObject *_connection_execute(Py_ConnectionObject *self, PyObject *args) { - if (!PyString_CheckExact(args)) { - PyErr_Format(PyExc_TypeError, - "expected a query string, but got an object of type %s", Py_TYPE(args)->tp_name); - return NULL; - } - if (!self->mapped) - { - // This is not a mapped process, so we can just directly execute the query here - PyObject *result; - res_table* output = NULL; - char *res = NULL; - char *query; + if (!PyString_CheckExact(args)) { + PyErr_Format(PyExc_TypeError, + "expected a query string, but got an object of type %s", + Py_TYPE(args)->tp_name); + return NULL; + } + if (!self->mapped) { + // This is not a mapped process, so we can just directly execute the + // query here + PyObject *result; + res_table *output = NULL; + char *res = NULL; + char *query; #ifndef IS_PY3K - query = ((PyStringObject*)args)->ob_sval; + query = ((PyStringObject *)args)->ob_sval; #else - query = PyUnicode_AsUTF8(args); + query = PyUnicode_AsUTF8(args); #endif - res = _connection_query(self->cntxt, query, &output); - if (res != MAL_SUCCEED) { - PyErr_Format(PyExc_Exception, "SQL Query Failed: %s", (res ? res : "<no error>")); - return NULL; - } + res = _connection_query(self->cntxt, query, &output); + if (res != MAL_SUCCEED) { + PyErr_Format(PyExc_Exception, "SQL Query Failed: %s", + (res ? res : "<no error>")); + return NULL; + } - result = PyDict_New(); - if (output && output->nr_cols > 0) { - PyInput input; - PyObject *numpy_array; - int i; - for (i = 0; i < output->nr_cols; i++) { - res_col col = output->cols[i]; - BAT* b = BATdescriptor(col.b); + result = PyDict_New(); + if (output && output->nr_cols > 0) { + PyInput input; + PyObject *numpy_array; + int i; + for (i = 0; i < output->nr_cols; i++) { + res_col col = output->cols[i]; + BAT *b = BATdescriptor(col.b); - input.bat = b; - input.count = BATcount(b); - input.bat_type = getBatType(b->ttype); - input.scalar = false; - input.sql_subtype = &col.type; + input.bat = b; + input.count = BATcount(b); + input.bat_type = getBatType(b->ttype); + input.scalar = false; + input.sql_subtype = &col.type; - numpy_array = PyMaskedArray_FromBAT(&input, 0, input.count, &res, true); - if (!numpy_array) { - _connection_cleanup_result(output); - PyErr_Format(PyExc_Exception, "SQL Query Failed: %s", (res ? res : "<no error>")); - return NULL; - } - PyDict_SetItem(result, PyString_FromString(output->cols[i].name), numpy_array); - Py_DECREF(numpy_array); - BBPunfix(input.bat->batCacheid); - } - _connection_cleanup_result(output); - return result; - } else { - Py_RETURN_NONE; - } - } - else + numpy_array = + PyMaskedArray_FromBAT(&input, 0, input.count, &res, true); + if (!numpy_array) { + _connection_cleanup_result(output); + PyErr_Format(PyExc_Exception, "SQL Query Failed: %s", + (res ? res : "<no error>")); + return NULL; + } + PyDict_SetItem(result, + PyString_FromString(output->cols[i].name), + numpy_array); + Py_DECREF(numpy_array); + BBPunfix(input.bat->batCacheid); + } + _connection_cleanup_result(output); + return result; + } else { + Py_RETURN_NONE; + } + } else #ifdef HAVE_FORK - { - str msg; - char *query; + { + str msg; + char *query; #ifndef IS_PY3K - query = ((PyStringObject*)args)->ob_sval; + query = ((PyStringObject *)args)->ob_sval; #else - query = PyUnicode_AsUTF8(args); + query = PyUnicode_AsUTF8(args); #endif - // This is a mapped process, we do not want forked processes to touch the database - // Only the main process may touch the database, so we ship the query back to the main process - // copy the query into shared memory and tell the main process there is a query to handle - strncpy(self->query_ptr->query, query, 8192); - self->query_ptr->pending_query = true; - //free the main process so it can work on the query - GDKchangesemval(self->query_sem, 0, 1, &msg); - //now wait for the main process to finish - GDKchangesemval(self->query_sem, 1, -1, &msg); - if (self->query_ptr->pending_query) { - //the query failed in the main process - // life is hopeless - //there is no reason to continue to live - // so we commit sudoku - exit(0); - } + // This is a mapped process, we do not want forked processes to touch + // the database + // Only the main process may touch the database, so we ship the query + // back to the main process + // copy the query into shared memory and tell the main process there is + // a query to handle + strncpy(self->query_ptr->query, query, 8192); + self->query_ptr->pending_query = true; + // free the main process so it can work on the query + GDKchangesemval(self->query_sem, 0, 1, &msg); + // now wait for the main process to finish + GDKchangesemval(self->query_sem, 1, -1, &msg); + if (self->query_ptr->pending_query) { + // the query failed in the main process + // life is hopeless + // there is no reason to continue to live + // so we commit sudoku + exit(0); + } - if (self->query_ptr->memsize > 0) // check if there are return values - { - char *msg; - char *ptr; - PyObject *numpy_array; - size_t position = 0; - PyObject *result; - int i; + if (self->query_ptr->memsize > 0) // check if there are return values + { + char *msg; + char *ptr; + PyObject *numpy_array; + size_t position = 0; + PyObject *result; + int i; - // get a pointer to the shared memory holding the return values - if (GDKinitmmap(self->query_ptr->mmapid + 0, self->query_ptr->memsize, (void**) &ptr, NULL, &msg) != GDK_SUCCEED) { - PyErr_Format(PyExc_Exception, "%s", msg); - return NULL; - } + // get a pointer to the shared memory holding the return values + if (GDKinitmmap(self->query_ptr->mmapid + 0, + self->query_ptr->memsize, (void **)&ptr, NULL, + &msg) != GDK_SUCCEED) { + PyErr_Format(PyExc_Exception, "%s", msg); + return NULL; + } - result = PyDict_New(); - for(i = 0; i < self->query_ptr->nr_cols; i++) - { - BAT *b; - str colname; - PyInput input; - position += GDKbatread(ptr + position, &b, &colname); - //initialize the PyInput structure - input.bat = b; - input.count = BATcount(b); - input.bat_type = b->ttype; - input.scalar = false; - input.sql_subtype = NULL; + result = PyDict_New(); + for (i = 0; i < self->query_ptr->nr_cols; i++) { + BAT *b; + str colname; + PyInput input; + position += GDKbatread(ptr + position, &b, &colname); + // initialize the PyInput structure + input.bat = b; + input.count = BATcount(b); + input.bat_type = b->ttype; + input.scalar = false; + input.sql_subtype = NULL; - numpy_array = PyMaskedArray_FromBAT(&input, 0, input.count, &msg, true); - if (!numpy_array) { - PyErr_Format(PyExc_Exception, "SQL Query Failed: %s", (msg ? msg : "<no error>")); - GDKreleasemmap(ptr, self->query_ptr->memsize, self->query_ptr->mmapid, &msg); - return NULL; - } - PyDict_SetItem(result, PyString_FromString(colname), numpy_array); - Py_DECREF(numpy_array); - } - GDKreleasemmap(ptr, self->query_ptr->memsize, self->query_ptr->mmapid, &msg); - return result; - } + numpy_array = + PyMaskedArray_FromBAT(&input, 0, input.count, &msg, true); + if (!numpy_array) { + PyErr_Format(PyExc_Exception, "SQL Query Failed: %s", + (msg ? msg : "<no error>")); + GDKreleasemmap(ptr, self->query_ptr->memsize, + self->query_ptr->mmapid, &msg); + return NULL; + } + PyDict_SetItem(result, PyString_FromString(colname), + numpy_array); + Py_DECREF(numpy_array); + } + GDKreleasemmap(ptr, self->query_ptr->memsize, + self->query_ptr->mmapid, &msg); + return result; + } - Py_RETURN_NONE; - } + Py_RETURN_NONE; + } #else - { - PyErr_Format(PyExc_Exception, "Mapped is not supported on Windows."); - return NULL; - } + { + PyErr_Format(PyExc_Exception, "Mapped is not supported on Windows."); + return NULL; + } #endif } static PyMethodDef _connectionObject_methods[] = { - {"execute", (PyCFunction)_connection_execute, METH_O,"execute(query) -> executes a SQL query on the database in the current client context"}, - {NULL,NULL,0,NULL} /* Sentinel */ + {"execute", (PyCFunction)_connection_execute, METH_O, + "execute(query) -> executes a SQL query on the database in the current " + "client context"}, + {NULL, NULL, 0, NULL} /* Sentinel */ }; PyTypeObject Py_ConnectionType = { - _PyObject_EXTRA_INIT -// in python3 they use structs within structs to represent this information, and many compilers throw warnings if you don't use separate braces -// to initialize these separate structs. However, in Python2, they use #defines to put this information in, so we have these nice #ifdefs + _PyObject_EXTRA_INIT +// in python3 they use structs within structs to represent this information, and +// many compilers throw warnings if you don't use separate braces +// to initialize these separate structs. However, in Python2, they use #defines +// to put this information in, so we have these nice #ifdefs #ifdef IS_PY3K - { { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list