@@ -1298,19 +1298,16 @@ _mysql_row_to_dict_old(
1298
1298
1299
1299
typedef PyObject * _PYFUNC (_mysql_ResultObject * , MYSQL_ROW );
1300
1300
1301
- int
1301
+ Py_ssize_t
1302
1302
_mysql__fetch_row (
1303
1303
_mysql_ResultObject * self ,
1304
- PyObject * * r ,
1305
- int skiprows ,
1306
- int maxrows ,
1304
+ PyObject * r , /* list object */
1305
+ Py_ssize_t maxrows ,
1307
1306
_PYFUNC * convert_row )
1308
1307
{
1309
- int i ;
1310
- MYSQL_ROW row ;
1311
-
1312
- for (i = skiprows ; i < (skiprows + maxrows ); i ++ ) {
1313
- PyObject * v ;
1308
+ Py_ssize_t i ;
1309
+ for (i = 0 ; i < maxrows ; i ++ ) {
1310
+ MYSQL_ROW row ;
1314
1311
if (!self -> use )
1315
1312
row = mysql_fetch_row (self -> result );
1316
1313
else {
@@ -1320,19 +1317,20 @@ _mysql__fetch_row(
1320
1317
}
1321
1318
if (!row && mysql_errno (& (((_mysql_ConnectionObject * )(self -> conn ))-> connection ))) {
1322
1319
_mysql_Exception ((_mysql_ConnectionObject * )self -> conn );
1323
- goto error ;
1320
+ return -1 ;
1324
1321
}
1325
1322
if (!row ) {
1326
- if (_PyTuple_Resize (r , i ) == -1 ) goto error ;
1327
1323
break ;
1328
1324
}
1329
- v = convert_row (self , row );
1330
- if (!v ) goto error ;
1331
- PyTuple_SET_ITEM (* r , i , v );
1325
+ PyObject * v = convert_row (self , row );
1326
+ if (!v ) return -1 ;
1327
+ if (PyList_Append (r , v )) {
1328
+ Py_DECREF (v );
1329
+ return -1 ;
1330
+ }
1331
+ Py_DECREF (v );
1332
1332
}
1333
- return i - skiprows ;
1334
- error :
1335
- return -1 ;
1333
+ return i ;
1336
1334
}
1337
1335
1338
1336
static char _mysql_ResultObject_fetch_row__doc__ [] =
@@ -1359,7 +1357,7 @@ _mysql_ResultObject_fetch_row(
1359
1357
_mysql_row_to_dict_old
1360
1358
};
1361
1359
_PYFUNC * convert_row ;
1362
- int maxrows = 1 , how = 0 , skiprows = 0 , rowsadded ;
1360
+ int maxrows = 1 , how = 0 ;
1363
1361
PyObject * r = NULL ;
1364
1362
1365
1363
if (!PyArg_ParseTupleAndKeywords (args , kwargs , "|ii:fetch_row" , kwlist ,
@@ -1371,40 +1369,24 @@ _mysql_ResultObject_fetch_row(
1371
1369
return NULL ;
1372
1370
}
1373
1371
convert_row = row_converters [how ];
1374
- if (maxrows ) {
1375
- if (!(r = PyTuple_New (maxrows ))) goto error ;
1376
-
1377
- // see: https://docs.python.org/3/library/gc.html#gc.get_referrers
1378
- // This function can get a reference to the tuple r, and if that
1379
- // code is preempted while holding a ref to r, the _PyTuple_Resize
1380
- // will raise a SystemError because the ref count is 2.
1381
- PyObject_GC_UnTrack (r );
1382
- rowsadded = _mysql__fetch_row (self , & r , skiprows , maxrows , convert_row );
1383
- if (rowsadded == -1 ) goto error ;
1384
- PyObject_GC_Track (r );
1385
- } else {
1372
+ if (!maxrows ) {
1386
1373
if (self -> use ) {
1387
- maxrows = 1000 ;
1388
- if (!(r = PyTuple_New (maxrows ))) goto error ;
1389
- while (1 ) {
1390
- rowsadded = _mysql__fetch_row (self , & r , skiprows ,
1391
- maxrows , convert_row );
1392
- if (rowsadded == -1 ) goto error ;
1393
- skiprows += rowsadded ;
1394
- if (rowsadded < maxrows ) break ;
1395
- if (_PyTuple_Resize (& r , skiprows + maxrows ) == -1 )
1396
- goto error ;
1397
- }
1374
+ maxrows = INT_MAX ;
1398
1375
} else {
1399
- /* XXX if overflow, maxrows<0? */
1400
- maxrows = (int ) mysql_num_rows (self -> result );
1401
- if (!(r = PyTuple_New (maxrows ))) goto error ;
1402
- rowsadded = _mysql__fetch_row (self , & r , 0 ,
1403
- maxrows , convert_row );
1404
- if (rowsadded == -1 ) goto error ;
1376
+ // todo: preallocate.
1377
+ maxrows = (Py_ssize_t ) mysql_num_rows (self -> result );
1405
1378
}
1406
1379
}
1407
- return r ;
1380
+ if (!(r = PyList_New (0 ))) goto error ;
1381
+ Py_ssize_t rowsadded = _mysql__fetch_row (self , r , maxrows , convert_row );
1382
+ if (rowsadded == -1 ) goto error ;
1383
+
1384
+ /* DB-API allows return rows as list.
1385
+ * But we need to return list because Django expecting tuple.
1386
+ */
1387
+ PyObject * t = PyList_AsTuple (r );
1388
+ Py_DECREF (r );
1389
+ return t ;
1408
1390
error :
1409
1391
Py_XDECREF (r );
1410
1392
return NULL ;
0 commit comments