Mike Bayer avatar Mike Bayer committed f9f8414

- slightly better support for bind params as column clauses, either
via bindparam() or via literal(), i.e. select([literal('foo')])
- removed "table" argument from column(). this does not add the column
to the table anyway so was misleading.
- Select _exportable_columns() only exports Selectable instances
- Select uses _exportable_columns() when searching for engines
instead of _raw_columns for similar reasons (non selectables have no engine)
- _BindParamClause no longer has a _make_proxy(). its not a ColumnElement.
- _Label detects underlying column element and will generate its own
column()._make_proxy() if the element is not a ColumnElement. this
allows a Label to be declared for nearly anything and it can export
itself as a column on a containing Selectable.

Comments (0)

Files changed (3)

      with conflicting names, specify "unique=True" - this option is
      still used internally for all the auto-genererated (value-based) 
      bind parameters.    
+    - slightly better support for bind params as column clauses, either
+    via bindparam() or via literal(), i.e. select([literal('foo')])
     - exists() becomes useable as a standalone selectable, not just in a 
     WHERE clause, i.e. exists([columns], criterion).select()


     return _Label(name, obj)
-def column(text, table=None, type=None, **kwargs):
+def column(text, type=None):
     """Return a textual column clause, relative to a table.
     This is also the primitive version of a ``schema.Column`` which is
     a subclass.
-    return _ColumnClause(text, table, type, **kwargs)
+    return _ColumnClause(text, type=type)
 def literal_column(text, table=None, type=None, **kwargs):
     """Return a textual column clause with the `literal` flag set.
         return isinstance(other, _BindParamClause) and other.type.__class__ == self.type.__class__
-    def _make_proxy(self, selectable, name = None):
-        return self
     def __repr__(self):
         return "_BindParamClause(%s, %s, type=%s)" % (repr(self.key), repr(self.value), repr(self.type))
         return self.obj._get_from_objects()
     def _make_proxy(self, selectable, name = None):
-        return self.obj._make_proxy(selectable, name=self.name)
+        if isinstance(self.obj, Selectable):
+            return self.obj._make_proxy(selectable, name=self.name)
+        else:
+            return column(self.name)._make_proxy(selectable=selectable)
 legal_characters = util.Set(string.ascii_letters + string.digits + '_')
         # propigate the "is_literal" flag only if we are keeping our name,
         # otherwise its considered to be a label
         is_literal = self.is_literal and (name is None or name == self.name)
-        c = _ColumnClause(name or self.name, selectable, _is_oid=self._is_oid, type=self.type, is_literal=is_literal)
+        c = _ColumnClause(name or self.name, selectable=selectable, _is_oid=self._is_oid, type=self.type, is_literal=is_literal)
         c.orig_set = self.orig_set
         if not self._is_oid:
             selectable.columns[c.name] = c
             return label(name, self)
     def _exportable_columns(self):
-        return self._raw_columns
+        return [c for c in self._raw_columns if isinstance(c, Selectable)]
     def _proxy_column(self, column):
         if self.use_labels:
             return column._make_proxy(self, name=column._label)
                 return e
         # look through the columns (largely synomous with looking
         # through the FROMs except in the case of _CalculatedClause/_Function)
-        for cc in self._raw_columns:
+        for cc in self._exportable_columns():
             for c in cc.columns:
                 if getattr(c, 'table', None) is self:


         c = s.compile(parameters = {'test' : 7})
         self.assert_(c.get_params() == {'test' : 7})
+    def testbindascol(self):
+        t = table('foo', column('id'))
+        s = select([t, literal('lala').label('hoho')])
+        self.runtest(s, "SELECT foo.id, :literal AS hoho FROM foo")
+        assert [str(c) for c in s.c] == ["id", "hoho"]
     def testin(self):
         self.runtest(select([table1], table1.c.myid.in_(1, 2, 3)),
         "SELECT mytable.myid, mytable.name, mytable.description FROM mytable WHERE mytable.myid IN (:mytable_myid, :mytable_my_1, :mytable_my_2)")
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.