diff --git a/include/mariadb_python.h b/include/mariadb_python.h index 705e7fc..1f1853e 100755 --- a/include/mariadb_python.h +++ b/include/mariadb_python.h @@ -319,6 +319,7 @@ extern PyTypeObject Mariadb_Fieldinfo_Type; extern PyTypeObject MrdbConnection_Type; extern PyTypeObject MrdbCursor_Type; +PyObject *ListOrTuple_GetItem(PyObject *obj, Py_ssize_t index); int Mariadb_traverse(PyObject *self, visitproc visit, void *arg); diff --git a/mariadb/cursors.py b/mariadb/cursors.py index 19ee5c4..4addaf5 100644 --- a/mariadb/cursors.py +++ b/mariadb/cursors.py @@ -294,11 +294,10 @@ def execute(self, statement: str, data: Sequence = (), buffered=None): if self._force_binary: self._text = False - for val in data: - if isinstance(val, (bytes, bytearray, datetime.datetime, - datetime.date, datetime.time)): - self._text = False - break + # if one of the provided parameters has byte or datetime value, + # we don't use text protocol + if self._check_text_types() == True: + self._text = False if self._text: # in text mode we need to substitute parameters diff --git a/mariadb/mariadb_codecs.c b/mariadb/mariadb_codecs.c index 4bb614e..1b4e8e9 100644 --- a/mariadb/mariadb_codecs.c +++ b/mariadb/mariadb_codecs.c @@ -891,7 +891,7 @@ mariadb_get_column_info(PyObject *obj, MrdbParamInfo *paraminfo) return 1; } -static PyObject *ListOrTuple_GetItem(PyObject *obj, Py_ssize_t index) +PyObject *ListOrTuple_GetItem(PyObject *obj, Py_ssize_t index) { if (CHECK_TYPE(obj, &PyList_Type)) { diff --git a/mariadb/mariadb_cursor.c b/mariadb/mariadb_cursor.c index 4241aea..6397cd7 100644 --- a/mariadb/mariadb_cursor.c +++ b/mariadb/mariadb_cursor.c @@ -19,6 +19,7 @@ #include #include +#include static void MrdbCursor_dealloc(MrdbCursor *self); @@ -39,6 +40,9 @@ MrdbCursor_InitResultSet(MrdbCursor *self); static PyObject * MrdbCursor_execute_text(MrdbCursor *self, PyObject *args); +static PyObject * +MrdbCursor_check_text_types(MrdbCursor *self); + static PyObject * MrdbCursor_fetchrows(MrdbCursor *self, PyObject *args); @@ -138,6 +142,9 @@ static PyMethodDef MrdbCursor_Methods[] = METH_NOARGS, cursor_next__doc__}, /* internal helper functions */ + {"_check_text_types", (PyCFunction) MrdbCursor_check_text_types, + METH_NOARGS, + NULL}, {"_seek", (PyCFunction)MrdbCursor_seek, METH_VARARGS, NULL}, @@ -1273,3 +1280,23 @@ MrdbCursor_fetchrows(MrdbCursor *self, PyObject *args) return List; } +static PyObject * +MrdbCursor_check_text_types(MrdbCursor *self) +{ + PyDateTime_IMPORT; + + if (!self || !self->data || !self->parseinfo.paramcount) + { + Py_RETURN_NONE; + } + + for (uint32_t i= 0; i < self->parseinfo.paramcount; i++) + { + PyObject *obj= ListOrTuple_GetItem(self->data, i); + if (PyBytes_Check(obj) || + PyByteArray_Check(obj) || + PyDate_Check(obj)) + Py_RETURN_TRUE; + } + Py_RETURN_NONE; +}