summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-03-10 16:18:52 -0800
committerMike Bayer <mike_mp@zzzcomputing.com>2012-03-10 16:18:52 -0800
commit5448f6129cd0487c3d06324385cc2ef0701b5815 (patch)
treecdc8bd5a7312e37dc8fb873c7211be49e54b202c
parentdb69a48231754c4279b2ceb5ce7317a50ed839d2 (diff)
downloadsqlalchemy-5448f6129cd0487c3d06324385cc2ef0701b5815.tar.gz
- [bug] Fixed memory leak in core which would
occur when C extensions were used with particular types of result fetches, in particular when orm query.count() were called. [ticket:2427]
-rw-r--r--CHANGES6
-rw-r--r--lib/sqlalchemy/cextension/resultproxy.c6
-rw-r--r--test/aaa_profiling/test_memusage.py16
3 files changed, 28 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index c98b80f56..cc5f66348 100644
--- a/CHANGES
+++ b/CHANGES
@@ -69,6 +69,12 @@ CHANGES
on the method object. [ticket:2352]
- sql
+ - [bug] Fixed memory leak in core which would
+ occur when C extensions were used with
+ particular types of result fetches,
+ in particular when orm query.count()
+ were called. [ticket:2427]
+
- [feature] Added support for SQL standard
common table expressions (CTE), allowing
SELECT objects as the CTE source (DML
diff --git a/lib/sqlalchemy/cextension/resultproxy.c b/lib/sqlalchemy/cextension/resultproxy.c
index 64b6855fa..325007c11 100644
--- a/lib/sqlalchemy/cextension/resultproxy.c
+++ b/lib/sqlalchemy/cextension/resultproxy.c
@@ -246,6 +246,7 @@ BaseRowProxy_subscript(BaseRowProxy *self, PyObject *key)
PyObject *exc_module, *exception;
char *cstr_key;
long index;
+ int key_fallback = 0;
if (PyInt_CheckExact(key)) {
index = PyInt_AS_LONG(key);
@@ -276,12 +277,17 @@ BaseRowProxy_subscript(BaseRowProxy *self, PyObject *key)
"O", key);
if (record == NULL)
return NULL;
+ key_fallback = 1;
}
indexobject = PyTuple_GetItem(record, 2);
if (indexobject == NULL)
return NULL;
+ if (key_fallback) {
+ Py_DECREF(record);
+ }
+
if (indexobject == Py_None) {
exc_module = PyImport_ImportModule("sqlalchemy.exc");
if (exc_module == NULL)
diff --git a/test/aaa_profiling/test_memusage.py b/test/aaa_profiling/test_memusage.py
index 579555c3f..cffe8b71f 100644
--- a/test/aaa_profiling/test_memusage.py
+++ b/test/aaa_profiling/test_memusage.py
@@ -496,6 +496,22 @@ class MemUsageTest(EnsureZeroed):
metadata.drop_all()
assert_no_mappers()
+ @testing.fails_if(lambda : testing.db.dialect.name == 'sqlite' \
+ and testing.db.dialect.dbapi.version > '2.5')
+ @testing.provide_metadata
+ def test_key_fallback_result(self):
+ e = testing.db
+ m = self.metadata
+ t = Table('t', m, Column('x', Integer), Column('y', Integer))
+ m.create_all(e)
+ e.execute(t.insert(), {"x":1, "y":1})
+ @profile_memory
+ def go():
+ r = e.execute(t.alias().select())
+ for row in r:
+ row[t.c.x]
+ go()
+
# fails on newer versions of pysqlite due to unusual memory behvior
# in pysqlite itself. background at:
# http://thread.gmane.org/gmane.comp.python.db.pysqlite.user/2290