Changeset: 7b27944c15ed for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7b27944c15ed
Modified Files:
sql/backends/monet5/UDF/pyapi/emit.c
sql/backends/monet5/UDF/pyapi/emit.h
sql/backends/monet5/UDF/pyapi/pyloader.c
Branch: default
Log Message:
Fix crash when no rows are emitted, and allow users to return (instead of emit)
a dictionary as well.
diffs (143 lines):
diff --git a/sql/backends/monet5/UDF/pyapi/emit.c
b/sql/backends/monet5/UDF/pyapi/emit.c
--- a/sql/backends/monet5/UDF/pyapi/emit.c
+++ b/sql/backends/monet5/UDF/pyapi/emit.c
@@ -28,8 +28,9 @@
return NULL; \
}}
-static PyObject *
-_emit_emit(Py_EmitObject *self, PyObject *args) {
+
+PyObject *
+PyEmit_Emit(PyEmitObject *self, PyObject *args) {
size_t i, ai; // iterators
ssize_t el_count = -1; // the amount of elements this emit call will write
to the table
size_t dict_elements, matched_elements;
@@ -306,15 +307,15 @@ wrapup:
static PyMethodDef _emitObject_methods[] = {
- {"emit", (PyCFunction)_emit_emit, METH_O,"emit(dictionary) -> returns
parsed values for table insertion"},
+ {"emit", (PyCFunction)PyEmit_Emit, METH_O,"emit(dictionary) -> returns
parsed values for table insertion"},
{NULL,NULL,0,NULL} /* Sentinel */
};
-PyTypeObject Py_EmitType = {
+PyTypeObject PyEmitType = {
PyObject_HEAD_INIT(NULL)
0,
"monetdb._emit",
- sizeof(Py_EmitObject),
+ sizeof(PyEmitObject),
0,
0, /* tp_dealloc */
0, /* tp_print */
@@ -366,14 +367,14 @@ PyTypeObject Py_EmitType = {
-PyObject *Py_Emit_Create(sql_emit_col *cols, size_t ncols)
+PyObject *PyEmit_Create(sql_emit_col *cols, size_t ncols)
{
- register Py_EmitObject *op;
+ register PyEmitObject *op;
- op = (Py_EmitObject *)PyObject_MALLOC(sizeof(Py_EmitObject));
+ op = (PyEmitObject *)PyObject_MALLOC(sizeof(PyEmitObject));
if (op == NULL)
return PyErr_NoMemory();
- PyObject_Init((PyObject*)op, &Py_EmitType);
+ PyObject_Init((PyObject*)op, &PyEmitType);
op->cols = cols;
op->ncols = ncols;
op->maxcols = ncols;
@@ -385,7 +386,7 @@ PyObject *Py_Emit_Create(sql_emit_col *c
str _emit_init(void)
{
_import_array();
- if (PyType_Ready(&Py_EmitType) < 0)
+ if (PyType_Ready(&PyEmitType) < 0)
return createException(MAL, "pyapi.eval", "Failed to initialize emit
type.");
return MAL_SUCCEED;
}
diff --git a/sql/backends/monet5/UDF/pyapi/emit.h
b/sql/backends/monet5/UDF/pyapi/emit.h
--- a/sql/backends/monet5/UDF/pyapi/emit.h
+++ b/sql/backends/monet5/UDF/pyapi/emit.h
@@ -23,11 +23,12 @@ typedef struct {
BUN nvals;
size_t maxcols;
bool create_table;
-} Py_EmitObject;
+} PyEmitObject;
-extern PyTypeObject Py_EmitType;
+extern PyTypeObject PyEmitType;
-PyObject *Py_Emit_Create(sql_emit_col *cols, size_t ncols);
+PyObject *PyEmit_Create(sql_emit_col *cols, size_t ncols);
+PyObject *PyEmit_Emit(PyEmitObject *self, PyObject *args);
str _emit_init(void);
diff --git a/sql/backends/monet5/UDF/pyapi/pyloader.c
b/sql/backends/monet5/UDF/pyapi/pyloader.c
--- a/sql/backends/monet5/UDF/pyapi/pyloader.c
+++ b/sql/backends/monet5/UDF/pyapi/pyloader.c
@@ -151,7 +151,7 @@ str PyAPIevalLoader(Client cntxt, MalBlk
retvals = 0;
create_table = true;
}
- pEmit = Py_Emit_Create(cols, retvals);
+ pEmit = PyEmit_Create(cols, retvals);
if (!pConnection || !pEmit) {
msg = createException(MAL, "pyapi.eval_loader", MAL_MALLOC_FAIL"python
object");
@@ -168,7 +168,7 @@ str PyAPIevalLoader(Client cntxt, MalBlk
}
{
- PyObject *pFunc, *pModule, *v, *d;
+ PyObject *pFunc, *pModule, *v, *d, *ret;
// First we will load the main module, this is required
pModule = PyImport_AddModule("__main__");
@@ -200,17 +200,33 @@ str PyAPIevalLoader(Client cntxt, MalBlk
goto wrapup;
}
}
- PyObject_CallObject(pFunc, pArgs);
+ ret = PyObject_CallObject(pFunc, pArgs);
- cols = ((Py_EmitObject *) pEmit)->cols;
- nval = ((Py_EmitObject *) pEmit)->nvals;
- retvals = (int) ((Py_EmitObject *) pEmit)->ncols;
+ if (PyErr_Occurred()) {
+ Py_DECREF(pFunc);
+ Py_DECREF(pArgs);
+ msg = PyError_CreateException("Python exception", pycall);
+ if (code_object == NULL) { PyRun_SimpleString("del pyfun"); }
+ goto wrapup;
+ }
+
+ if (ret != Py_None) {
+ if (PyEmit_Emit((PyEmitObject *) pEmit, ret) == NULL) {
+ Py_DECREF(pFunc);
+ Py_DECREF(pArgs);
+ msg = PyError_CreateException("Python exception", pycall);
+ goto wrapup;
+ }
+ }
+
+ cols = ((PyEmitObject *) pEmit)->cols;
+ nval = ((PyEmitObject *) pEmit)->nvals;
+ retvals = (int) ((PyEmitObject *) pEmit)->ncols;
Py_DECREF(pFunc);
Py_DECREF(pArgs);
- if (PyErr_Occurred()) {
- msg = PyError_CreateException("Python exception", pycall);
- if (code_object == NULL) { PyRun_SimpleString("del pyfun"); }
+ if (retvals == 0) {
+ msg = createException(MAL, "pyapi.eval_loader", "No elements
emitted by the loader.");
goto wrapup;
}
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list