]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [bug] Fixed cextension bug whereby the
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 22 Aug 2012 22:49:16 +0000 (18:49 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 22 Aug 2012 22:49:16 +0000 (18:49 -0400)
"ambiguous column error" would fail to
function properly if the given index were
a Column object and not a string.
Note there are still some column-targeting
issues here which are fixed in 0.8.
[ticket:2553]

CHANGES
lib/sqlalchemy/cextension/resultproxy.c
test/sql/test_query.py

diff --git a/CHANGES b/CHANGES
index cffdf2ac8f9b05279b6aebb1ee632a9f53245eec..87ef0446e54558eddb7288cc9552078db7fe5cc3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -87,6 +87,14 @@ CHANGES
     the absense of which was preventing the new
     GAE dialect from being loaded.  [ticket:2529]
 
+  - [bug] Fixed cextension bug whereby the
+    "ambiguous column error" would fail to
+    function properly if the given index were
+    a Column object and not a string.
+    Note there are still some column-targeting
+    issues here which are fixed in 0.8.
+    [ticket:2553]
+
   - [bug] Fixed the repr() of Enum to include
     the "name" and "native_enum" flags.  Helps
     Alembic autogenerate.
index 518209e54ea9933ed5b0f4540fa73896f75b33da..ca9d28e63ab222b3f284cda1f6f61a2508f869f0 100644 (file)
@@ -13,8 +13,8 @@ typedef int Py_ssize_t;
 #define PY_SSIZE_T_MAX INT_MAX
 #define PY_SSIZE_T_MIN INT_MIN
 typedef Py_ssize_t (*lenfunc)(PyObject *);
-#define PyInt_FromSsize_t(x) PyInt_FromLong(x) 
-typedef intargfunc ssizeargfunc; 
+#define PyInt_FromSsize_t(x) PyInt_FromLong(x)
+typedef intargfunc ssizeargfunc;
 #endif
 
 
@@ -243,12 +243,12 @@ BaseRowProxy_subscript(BaseRowProxy *self, PyObject *key)
     PyObject *processors, *values;
     PyObject *processor, *value, *processed_value;
     PyObject *row, *record, *result, *indexobject;
-    PyObject *exc_module, *exception;
+    PyObject *exc_module, *exception, *cstr_obj;
     char *cstr_key;
     long index;
     int key_fallback = 0;
     int tuple_check = 0;
-    
+
     if (PyInt_CheckExact(key)) {
         index = PyInt_AS_LONG(key);
     } else if (PyLong_CheckExact(key)) {
@@ -300,9 +300,16 @@ BaseRowProxy_subscript(BaseRowProxy *self, PyObject *key)
             if (exception == NULL)
                 return NULL;
 
-            cstr_key = PyString_AsString(key);
-            if (cstr_key == NULL)
+            // wow.  this seems quite excessive.
+            cstr_obj = PyObject_Str(key);
+            if (cstr_obj == NULL)
+                return NULL;
+            cstr_key = PyString_AsString(cstr_obj);
+            if (cstr_key == NULL) {
+                Py_DECREF(cstr_obj);
                 return NULL;
+            }
+            Py_DECREF(cstr_obj);
 
             PyErr_Format(exception,
                     "Ambiguous column name '%.200s' in result set! "
@@ -328,7 +335,7 @@ BaseRowProxy_subscript(BaseRowProxy *self, PyObject *key)
         value = PySequence_GetItem(row, index);
         tuple_check = 0;
     }
-        
+
     if (value == NULL)
         return NULL;
 
@@ -368,7 +375,7 @@ BaseRowProxy_getattro(BaseRowProxy *self, PyObject *name)
     tmp = BaseRowProxy_subscript(self, name);
     if (tmp == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) {
         PyErr_Format(
-                PyExc_AttributeError, 
+                PyExc_AttributeError,
                 "Could not locate column in row for column '%.200s'",
                 PyString_AsString(name)
             );
index aba7288d26d624f985f28b66cc5adeeae2bed4cf..f46ffd8123e18825d3be39e22c484e31f3d8dd89 100644 (file)
@@ -954,6 +954,34 @@ class QueryTest(fixtures.TestBase):
             lambda: r['user_id']
         )
 
+    def test_ambiguous_column_by_col(self):
+        users.insert().execute(user_id=1, user_name='john')
+        ua = users.alias()
+        u2 = users.alias()
+        result = select([users.c.user_id, ua.c.user_id]).execute()
+        row = result.first()
+
+        assert_raises_message(
+            exc.InvalidRequestError,
+            "Ambiguous column name",
+            lambda: row[users.c.user_id]
+        )
+
+        # this is a bug, should be ambiguous.
+        # Fixed in 0.8
+        eq_(row[ua.c.user_id], 1)
+
+        # this is also a less severe bug - u2.c.user_id
+        # is not in the row at all so is not actually
+        # ambiguous.  Still is like this in 0.8
+        # and is due to overly liberal "this is a derived column"
+        # rules.
+        assert_raises_message(
+            exc.InvalidRequestError,
+            "Ambiguous column name",
+            lambda: row[u2.c.user_id]
+        )
+
     @testing.requires.subqueries
     def test_column_label_targeting(self):
         users.insert().execute(user_id=7, user_name='ed')