Skip to content

Commit 9070459

Browse files
author
Daniel Kinzler
committed
don't attach _fetch_dict to cursors, causes memory leak (all cursors are retained forever)
git-svn-id: https://svn.toolserver.org/svnroot/daniel/duesenstuff/trunk/gpClient@584 9f2c43bc-b3c0-43f4-b155-41619b16f219
1 parent 8bfa563 commit 9070459

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

python/gp/mysql.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def next(self):
1717
# XXX: if we knew that the order of fields in the result set is the same
1818
# as the order given in self.table, we could just use result.fetchone()
1919

20-
raw = self.result.fetch_dict( )
20+
raw = _fetch_dict( self.result )
2121

2222
if not raw:
2323
raise StopIteration()
@@ -285,8 +285,17 @@ def getTableName (self):
285285
return self.table
286286

287287
def _fetch_dict( cursor ):
288+
try:
289+
row = cursor.fetch_dict( )
290+
return row
291+
except AttributeError:
292+
pass
293+
288294
r = cursor.fetchone()
289295
if r is None: return None
296+
297+
if hasattr(r, "has_key"):
298+
return r # it's a dict!
290299

291300
row = {}
292301

@@ -388,8 +397,11 @@ def mysql_query( self, sql, unbuffered = None, dict_rows = False, cursor = None
388397

389398
if not dict_rows:
390399
# HACK: glue a fetch_dict method to a cursor that natively returns sequences from fetchone()
391-
m = types.MethodType(_fetch_dict, cursor, cursor.__class__)
392-
setattr(cursor, "fetch_dict", m)
400+
# FIXME: if we do this, we for some reason retain a reference to the cursor forever!
401+
#
402+
#m = types.MethodType(_fetch_dict, cursor, cursor.__class__)
403+
#setattr(cursor, "fetch_dict", m)
404+
pass
393405
else:
394406
# make fetch_dict an alias for fetchone
395407
cursor.fetch_dict = cursor.fetchone # TESTME
@@ -712,7 +724,7 @@ def dump_result (self, res ):
712724

713725
print ""
714726
while True:
715-
row = res.fetch_dict()
727+
row = _fetch_dict(res)
716728
if not row: break
717729

718730
if keys is None :

python/gp/tests/mysql_test.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from test_base import *
22
from gp.client import *
33
from gp.mysql import *
4+
from gp.mysql import _fetch_dict
45

56
import unittest
67
import sys
@@ -102,7 +103,7 @@ def test_UnbufferedSelectInto(self):
102103
self.assertEquals( [ ( 3, 8 ), ( 7, 9 ), ( 11, 11 ) ], data )
103104

104105
def assertNextRowEquals(self, expected, res):
105-
row = res.fetch_dict()
106+
row = _fetch_dict(res)
106107
self.assertTrue( TestBase.dictEquals(expected, row), "expected row to be %s, got %s" % (expected, row) )
107108

108109
def test_TempSink(self):
@@ -117,7 +118,7 @@ def test_TempSink(self):
117118

118119
self.assertNextRowEquals({ 'a': 4, 'b': 5 }, res )
119120
self.assertNextRowEquals({ 'a': 6, 'b': 7 }, res )
120-
self.assertFalse( res.fetch_dict(), "expected next row to be false" )
121+
self.assertFalse( res.fetchone(), "expected next row to be false" )
121122

122123
res.close()
123124

@@ -228,7 +229,7 @@ def testSuccessorsToSinkObject(self):
228229
self.assertNextRowEquals({ 'n': 12L }, res )
229230
self.assertNextRowEquals({ 'n': 111L }, res )
230231
self.assertNextRowEquals({ 'n': 112L }, res )
231-
self.assertFalse( res.fetch_dict(), "expected next row to be False" )
232+
self.assertFalse( res.fetchone(), "expected next row to be False" )
232233

233234
res.close()
234235

@@ -247,7 +248,7 @@ def testSuccessorsToSinkObject(self):
247248
self.assertNextRowEquals({ 'n': 12 }, res )
248249
self.assertNextRowEquals({ 'n': 111 }, res )
249250
self.assertNextRowEquals({ 'n': 112 }, res )
250-
self.assertFalse( res.fetch_dict(), "expected next row to be False" )
251+
self.assertFalse( res.fetchone(), "expected next row to be False" )
251252

252253
res.close()
253254

@@ -272,7 +273,7 @@ def test_SuccessorsToSinkShorthand(self):
272273
self.assertNextRowEquals({ 'n': 12 }, res )
273274
self.assertNextRowEquals({ 'n': 111 }, res )
274275
self.assertNextRowEquals({ 'n': 112 }, res )
275-
self.assertFalse( res.fetch_dict(), "expected next row to be False" )
276+
self.assertFalse( res.fetchone(), "expected next row to be False" )
276277

277278
res.close()
278279
snk.drop()
@@ -289,7 +290,7 @@ def test_SuccessorsToSinkShorthand(self):
289290
self.assertNextRowEquals({ 'n': 12 }, res )
290291
self.assertNextRowEquals({ 'n': 111 }, res )
291292
self.assertNextRowEquals({ 'n': 112 }, res )
292-
self.assertFalse( res.fetch_dict(), "expected next row to be False" )
293+
self.assertFalse( res.fetchone(), "expected next row to be False" )
293294

294295
res.close()
295296
snk.drop()
@@ -306,7 +307,7 @@ def test_SuccessorsToSinkShorthand(self):
306307
self.assertNextRowEquals({ 'n': 12 }, res )
307308
self.assertNextRowEquals({ 'n': 111 }, res )
308309
self.assertNextRowEquals({ 'n': 112 }, res )
309-
self.assertFalse( res.fetch_dict(), "expected next row to be False" )
310+
self.assertFalse( res.fetchone(), "expected next row to be False" )
310311

311312
res.close()
312313
snk.drop()
@@ -325,7 +326,7 @@ def test_SuccessorsToSinkShorthand(self):
325326
self.assertNextRowEquals({ 'n': 12 }, res )
326327
self.assertNextRowEquals({ 'n': 111 }, res )
327328
self.assertNextRowEquals({ 'n': 112 }, res )
328-
self.assertFalse( res.fetch_dict(), "expected next row to be False" )
329+
self.assertFalse( res.fetchone(), "expected next row to be False" )
329330

330331
res.close()
331332

0 commit comments

Comments
 (0)