Skip to content

Commit 2dd6006

Browse files
author
gerhard.haering
committed
Fixed rowcount for SELECT statements. They're -1 now (again), for better DB-API 2.0 compliance.
git-svn-id: http://svn.python.org/projects/python/trunk@63839 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 144ecad commit 2dd6006

3 files changed

Lines changed: 20 additions & 15 deletions

File tree

Lib/sqlite3/test/dbapi.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,15 @@ def CheckRowcountExecute(self):
297297
self.cu.execute("update test set name='bar'")
298298
self.failUnlessEqual(self.cu.rowcount, 2)
299299

300+
def CheckRowcountSelect(self):
301+
"""
302+
pysqlite does not know the rowcount of SELECT statements, because we
303+
don't fetch all rows after executing the select statement. The rowcount
304+
has thus to be -1.
305+
"""
306+
self.cu.execute("select 5 union select 6")
307+
self.failUnlessEqual(self.cu.rowcount, -1)
308+
300309
def CheckRowcountExecutemany(self):
301310
self.cu.execute("delete from test")
302311
self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])

Modules/_sqlite/cursor.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,7 @@ int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs
101101

102102
self->arraysize = 1;
103103

104-
self->rowcount = PyInt_FromLong(-1L);
105-
if (!self->rowcount) {
106-
return -1;
107-
}
104+
self->rowcount = -1L;
108105

109106
Py_INCREF(Py_None);
110107
self->row_factory = Py_None;
@@ -130,7 +127,6 @@ void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
130127
Py_XDECREF(self->row_cast_map);
131128
Py_XDECREF(self->description);
132129
Py_XDECREF(self->lastrowid);
133-
Py_XDECREF(self->rowcount);
134130
Py_XDECREF(self->row_factory);
135131
Py_XDECREF(self->next_row);
136132

@@ -427,12 +423,12 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
427423
int statement_type;
428424
PyObject* descriptor;
429425
PyObject* second_argument = NULL;
430-
long rowcount = 0;
431426
int allow_8bit_chars;
432427

433428
if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
434429
return NULL;
435430
}
431+
436432
/* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */
437433
allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) &&
438434
(self->connection->text_factory != (PyObject*)&PyUnicode_Type && pysqlite_OptimizedUnicode));
@@ -514,10 +510,11 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
514510
operation_cstr = PyBytes_AsString(operation_bytestr);
515511
}
516512

517-
/* reset description */
513+
/* reset description and rowcount */
518514
Py_DECREF(self->description);
519515
Py_INCREF(Py_None);
520516
self->description = Py_None;
517+
self->rowcount = -1L;
521518

522519
func_args = PyTuple_New(1);
523520
if (!func_args) {
@@ -693,7 +690,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
693690
case STATEMENT_DELETE:
694691
case STATEMENT_INSERT:
695692
case STATEMENT_REPLACE:
696-
rowcount += (long)sqlite3_changes(self->connection->db);
693+
if (self->rowcount == -1L) {
694+
self->rowcount = 0L;
695+
}
696+
self->rowcount += (long)sqlite3_changes(self->connection->db);
697697
}
698698

699699
Py_DECREF(self->lastrowid);
@@ -728,13 +728,9 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
728728
Py_XDECREF(parameters_list);
729729

730730
if (PyErr_Occurred()) {
731-
Py_DECREF(self->rowcount);
732-
self->rowcount = PyInt_FromLong(-1L);
731+
self->rowcount = -1L;
733732
return NULL;
734733
} else {
735-
Py_DECREF(self->rowcount);
736-
self->rowcount = PyInt_FromLong(rowcount);
737-
738734
Py_INCREF(self);
739735
return (PyObject*)self;
740736
}
@@ -1028,7 +1024,7 @@ static struct PyMemberDef cursor_members[] =
10281024
{"description", T_OBJECT, offsetof(pysqlite_Cursor, description), RO},
10291025
{"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0},
10301026
{"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), RO},
1031-
{"rowcount", T_OBJECT, offsetof(pysqlite_Cursor, rowcount), RO},
1027+
{"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), RO},
10321028
{"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0},
10331029
{NULL}
10341030
};

Modules/_sqlite/cursor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ typedef struct
3737
PyObject* row_cast_map;
3838
int arraysize;
3939
PyObject* lastrowid;
40-
PyObject* rowcount;
40+
long rowcount;
4141
PyObject* row_factory;
4242
pysqlite_Statement* statement;
4343

0 commit comments

Comments
 (0)