Changeset: ed79e7465506 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ed79e7465506 Modified Files: sql/backends/monet5/UDF/pyapi/emit.c sql/backends/monet5/UDF/pyapi/pyheader.h 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 Branch: default Log Message:
Add blob support to Python loader. diffs (238 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 @@ -216,56 +216,69 @@ PyObject *PyEmit_Emit(PyEmitObject *self PyObject *dictEntry = PyDict_GetItemString(args, self->cols[i].name); if (dictEntry && dictEntry != Py_None) { if (PyType_IsPyScalar(dictEntry)) { - switch (self->cols[i].b->ttype) { - case TYPE_bit: - scalar_convert(bit); - break; - case TYPE_bte: - scalar_convert(bte); - break; - case TYPE_sht: - scalar_convert(sht); - break; - case TYPE_int: - scalar_convert(int); - break; - case TYPE_oid: - scalar_convert(oid); - break; - case TYPE_lng: - scalar_convert(lng); - break; - case TYPE_flt: - scalar_convert(flt); - break; - case TYPE_dbl: - scalar_convert(dbl); - break; + if (self->cols[i].b->ttype == TYPE_blob || self->cols[i].b->ttype == TYPE_sqlblob) { + blob s; + blob* val = &s; + val->nitems = ~(size_t) 0; + msg = pyobject_to_blob(&dictEntry, 42, &val); + if (msg != MAL_SUCCEED || + BUNappend(self->cols[i].b, val, 0) != GDK_SUCCEED) { + if (msg == MAL_SUCCEED) + msg = GDKstrdup("BUNappend failed."); + goto wrapup; + } + } else { + switch (self->cols[i].b->ttype) { + case TYPE_bit: + scalar_convert(bit); + break; + case TYPE_bte: + scalar_convert(bte); + break; + case TYPE_sht: + scalar_convert(sht); + break; + case TYPE_int: + scalar_convert(int); + break; + case TYPE_oid: + scalar_convert(oid); + break; + case TYPE_lng: + scalar_convert(lng); + break; + case TYPE_flt: + scalar_convert(flt); + break; + case TYPE_dbl: + scalar_convert(dbl); + break; #ifdef HAVE_HGE - case TYPE_hge: - scalar_convert(hge); - break; + case TYPE_hge: + scalar_convert(hge); + break; #endif - case TYPE_str: { - str val = NULL; - gdk_return retval; - msg = pyobject_to_str(&dictEntry, 42, &val); - if (msg != MAL_SUCCEED) { + case TYPE_str: { + str val = NULL; + gdk_return retval; + msg = pyobject_to_str(&dictEntry, 42, &val); + if (msg != MAL_SUCCEED) { + goto wrapup; + } + assert(val); + retval = BUNappend(self->cols[i].b, val, 0); + free(val); + if (retval != GDK_SUCCEED) { + msg = GDKstrdup("BUNappend failed."); + goto wrapup; + } + } break; + default: + PyErr_Format(PyExc_TypeError, "Unsupported BAT Type %s", + BatType_Format(self->cols[i].b->ttype)); + error = true; goto wrapup; - } - assert(val); - retval = BUNappend(self->cols[i].b, val, 0); - free(val); - if (retval != GDK_SUCCEED) { - msg = GDKstrdup("BUNappend failed."); - goto wrapup; - } - } break; - default: - PyErr_Format(PyExc_TypeError, "Unsupported BAT Type %s", - BatType_Format(self->cols[i].b->ttype)); - error = true; - goto wrapup; + } } } else { bool *mask = NULL; @@ -282,7 +295,7 @@ PyObject *PyEmit_Emit(PyEmitObject *self msg = PyObject_GetReturnValues(dictEntry, ret); if (msg != MAL_SUCCEED) { goto wrapup; - } + } if (ret->array_data == NULL) { msg = GDKstrdup("No return value stored in the structure."); goto wrapup; diff --git a/sql/backends/monet5/UDF/pyapi/pyheader.h b/sql/backends/monet5/UDF/pyapi/pyheader.h --- a/sql/backends/monet5/UDF/pyapi/pyheader.h +++ b/sql/backends/monet5/UDF/pyapi/pyheader.h @@ -24,6 +24,7 @@ #include "gdk_utils.h" #include "gdk_posix.h" #include "gdk.h" +#include "blob.h" #include "sql_catalog.h" #include "sql_scenario.h" #include "sql_cast.h" diff --git a/sql/backends/monet5/UDF/pyapi/pytypes.c b/sql/backends/monet5/UDF/pyapi/pytypes.c --- a/sql/backends/monet5/UDF/pyapi/pytypes.c +++ b/sql/backends/monet5/UDF/pyapi/pytypes.c @@ -109,6 +109,11 @@ char *PyType_Format(int type) char *BatType_Format(int type) { + if (type == TYPE_blob) { + return "BLOB"; + } else if (type == TYPE_sqlblob) { + return "SQLBLOB"; + } switch (type) { case TYPE_bit: return "BOOL"; @@ -177,6 +182,11 @@ int PyType_ToBat(int type) int BatType_ToPyType(int type) { + if (type == TYPE_blob) { + return NPY_OBJECT; + } else if (type == TYPE_sqlblob) { + return NPY_OBJECT; + } switch (type) { case TYPE_bit: return NPY_BOOL; diff --git a/sql/backends/monet5/UDF/pyapi/pytypes.h b/sql/backends/monet5/UDF/pyapi/pytypes.h --- a/sql/backends/monet5/UDF/pyapi/pytypes.h +++ b/sql/backends/monet5/UDF/pyapi/pytypes.h @@ -1,4 +1,4 @@ -/* + /* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/sql/backends/monet5/UDF/pyapi/type_conversion.c b/sql/backends/monet5/UDF/pyapi/type_conversion.c --- a/sql/backends/monet5/UDF/pyapi/type_conversion.c +++ b/sql/backends/monet5/UDF/pyapi/type_conversion.c @@ -78,6 +78,46 @@ size_t pyobject_get_size(PyObject *obj) return size; } + +str pyobject_to_blob(PyObject **ptr, size_t maxsize, blob **value) { + size_t size; + char* bytes_data; + PyObject *obj; + str msg = MAL_SUCCEED; + if (ptr == NULL || *ptr == NULL) { + msg = createException(MAL, "pyapi.eval", "Invalid PyObject."); + goto wrapup; + } + obj = *ptr; + + (void)maxsize; +#ifndef IS_PY3K + if (PyString_CheckExact(obj)) { + size = PyString_Size(obj); + bytes_data = ((PyStringObject *)obj)->ob_sval; + } else +#endif + if (PyByteArray_CheckExact(obj)) { + size = PyByteArray_Size(obj); + bytes_data = ((PyByteArrayObject *)obj)->ob_bytes; + } else { + msg = createException( + MAL, "pyapi.eval", + "Unrecognized Python object. Could not convert to blob.\n"); + goto wrapup; + } + + *value = GDKmalloc(sizeof(blob) + size); + if (!*value) { + msg = createException(MAL, "pyapi.eval", MAL_MALLOC_FAIL); + goto wrapup; + } + (*value)->nitems = size; + memcpy((*value)->data, bytes_data, size); +wrapup: + return msg; +} + str pyobject_to_str(PyObject **ptr, size_t maxsize, str *value) { PyObject *obj; diff --git a/sql/backends/monet5/UDF/pyapi/type_conversion.h b/sql/backends/monet5/UDF/pyapi/type_conversion.h --- a/sql/backends/monet5/UDF/pyapi/type_conversion.h +++ b/sql/backends/monet5/UDF/pyapi/type_conversion.h @@ -43,6 +43,8 @@ size_t pyobject_get_size(PyObject *obj); //! Converts a PyObject to a str; the output string will be a newly allocated //! string (if *value == NULL) or stored in *value (if *value != NULL) str pyobject_to_str(PyObject **ptr, size_t maxsize, str *value); +//! Converts a PyObject to a blob +str pyobject_to_blob(PyObject **ptr, size_t maxsize, blob **value); //using macros, create a number of str_to_<type>, unicode_to_<type> and pyobject_to_<type> functions (we are Java now) #define CONVERSION_FUNCTION_HEADER_FACTORY(tpe) \ _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list