From 87684a1fdbffd5207cabc288f67be4ac289b65fb Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 5 May 2020 22:41:36 +0200 Subject: [PATCH] Fix for CONPY-62: When using binary protocl (which is forced when using a placeholder), the type NEW_DECIMAL was ignored and internally converted as string instead of Decimal. --- src/mariadb_codecs.c | 14 ++++++++++++-- src/mariadb_cursor.c | 1 - test/integration/test_cursor.py | 9 +++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/mariadb_codecs.c b/src/mariadb_codecs.c index c91030c..72fff0a 100644 --- a/src/mariadb_codecs.c +++ b/src/mariadb_codecs.c @@ -473,7 +473,6 @@ field_fetch_fromtext(MrdbCursor *self, char *data, unsigned int column) case MYSQL_TYPE_NEWDECIMAL: { PyObject *decimal; - decimal= PyObject_CallFunction(decimal_type, "s", (const char *)data); self->values[column]= decimal; break; @@ -692,13 +691,24 @@ field_fetch_callback(void *data, unsigned int column, unsigned char **row) *row+= length; break; } + case MYSQL_TYPE_NEWDECIMAL: + { + unsigned long length= mysql_net_field_length(row); + + if (length > 0) + { + self->values[column]= PyObject_CallFunction(decimal_type, "s", (const char *)*row); + } else { + self->values[column]= PyObject_CallFunction(decimal_type, "s", "0"); + } + break; + } case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_JSON: case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_SET: case MYSQL_TYPE_ENUM: { diff --git a/src/mariadb_cursor.c b/src/mariadb_cursor.c index afc863e..d6e526d 100644 --- a/src/mariadb_cursor.c +++ b/src/mariadb_cursor.c @@ -941,7 +941,6 @@ MrdbCursor_fetchone(MrdbCursor *self) "Cursor doesn't have a result set"); return NULL; } - if (MrdbCursor_fetchinternal(self)) { Py_INCREF(Py_None); diff --git a/test/integration/test_cursor.py b/test/integration/test_cursor.py index 3c75591..ca75348 100644 --- a/test/integration/test_cursor.py +++ b/test/integration/test_cursor.py @@ -918,5 +918,14 @@ def test_conpy61(self): del cursor + def test_conpy62(self): + con= create_connection() + cur = con.cursor() + con= create_connection() + query = "select round(.75 * (? / 3), 2) as val" + cur.execute(query,[5]) + row= cur.fetchone() + self.assertEqual(row[0], Decimal(1.25)) + if __name__ == '__main__': unittest.main()