Skip to content

Commit 3953b11

Browse files
committed
BUG21420633: Fix CExtension crashing while fetching large number of NULL values
CExtension was crashing with "Fatal Python error: deallocating None" when a large number of NULL values were fetched. With this patch we fix this issue by incrementing reference to None whenver a NULL value is fetched. A test case has been added for BUG#21420633.
1 parent 8815bb6 commit 3953b11

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/mysql_capi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,7 @@ MySQL_fetch_row(MySQL *self)
22372237
for (i= 0; i < num_fields; i++) {
22382238
if (row[i] == NULL)
22392239
{
2240+
Py_INCREF(Py_None);
22402241
PyTuple_SET_ITEM(result_row, i, Py_None);
22412242
continue;
22422243
}

tests/test_bugs.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3657,3 +3657,44 @@ def sleepy_select(cnx):
36573657
self.assertEqual(str(self.cnx.test_error),
36583658
"1317 (70100): Query execution was interrupted")
36593659
self.cnx.close()
3660+
3661+
class BugOra21420633(tests.MySQLConnectorTests):
3662+
"""BUG#21420633: CEXTENSION CRASHES WHILE FETCHING LOTS OF NULL VALUES
3663+
"""
3664+
def setUp(self):
3665+
config = tests.get_mysql_config()
3666+
cnx = connection.MySQLConnection(**config)
3667+
cur = cnx.cursor()
3668+
3669+
self.tbl = 'Bug21420633'
3670+
cur.execute("DROP TABLE IF EXISTS {0}".format(self.tbl))
3671+
3672+
create = ("CREATE TABLE {0} (id INT, dept VARCHAR(5)) "
3673+
"DEFAULT CHARSET latin1".format(self.tbl))
3674+
cur.execute(create)
3675+
cur.close()
3676+
cnx.close()
3677+
3678+
def tearDown(self):
3679+
config = tests.get_mysql_config()
3680+
cnx = connection.MySQLConnection(**config)
3681+
cur = cnx.cursor()
3682+
cur.execute("DROP TABLE IF EXISTS {0}".format(self.tbl))
3683+
cur.close()
3684+
cnx.close()
3685+
3686+
@foreach_cnx()
3687+
def test_null(self):
3688+
cur = self.cnx.cursor()
3689+
sql = "INSERT INTO {0} VALUES(%s, %s)".format(self.tbl)
3690+
3691+
data = [(i, None) for i in range(10000)]
3692+
3693+
cur.executemany(sql, data)
3694+
cur.close()
3695+
3696+
cur = self.cnx.cursor(named_tuple=True)
3697+
cur.execute("SELECT * FROM {0}".format(self.tbl))
3698+
3699+
res = cur.fetchall()
3700+
cur.close()

0 commit comments

Comments
 (0)