]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
(no commit message)
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 4 Nov 2005 00:37:26 +0000 (00:37 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 4 Nov 2005 00:37:26 +0000 (00:37 +0000)
lib/sqlalchemy/ansisql.py
lib/sqlalchemy/mapper.py
lib/sqlalchemy/sql.py
test/select.py

index f5ec9c11d731401cab6dfded0071a58b99d2eac0..31b401595bf0551646551dd566066b9df010efb3 100644 (file)
@@ -118,7 +118,7 @@ class ANSICompiler(sql.Compiled):
             self.strings[compound] = "(" + string.join([self.get_str(c) for c in compound.clauses], sep) + ")"
         else:
             self.strings[compound] = string.join([self.get_str(c) for c in compound.clauses], sep)
-
+        
     def visit_clauselist(self, list):
         self.strings[list] = string.join([self.get_str(c) for c in list.clauses], ', ')
         
@@ -172,7 +172,7 @@ class ANSICompiler(sql.Compiled):
         whereclause = select.whereclause
         
         froms = []
-        for f in select.froms.values():
+        for f in select.froms:
 
             # special thingy used by oracle to redefine a join
             w = self.get_whereclause(f)
index 5c082a95fd0c31a7899118ad0424e8ee5b0ae076..756ea49046626fdefc22c1691e124b8e4b47ec73 100644 (file)
@@ -966,7 +966,7 @@ class LazyLoader(PropertyLoader):
                 if self.secondary is not None:
                     order_by = [self.secondary.rowid_column]
                 else:
-                    order_by = [self.target.rowid_column]
+                    order_by = []
                 result = self.mapper.select(self.lazywhere, order_by=order_by,**params)
                 if self.uselist:
                     return result
index bae42022e8dd135869ba9c227c36902b026c3d5c..1d3f74e1ab42c6abf3b54a0284a39d6457b5db81 100644 (file)
@@ -23,7 +23,7 @@ import sqlalchemy.util as util
 import sqlalchemy.types as types
 import string
 
-__ALL__ = ['textclause', 'select', 'join', 'and_', 'or_', 'union', 'desc', 'asc', 'outerjoin', 'alias', 'subquery', 'bindparam', 'sequence']
+__ALL__ = ['textclause', 'select', 'join', 'and_', 'or_', 'union', 'unionall', 'desc', 'asc', 'outerjoin', 'alias', 'subquery', 'bindparam', 'sequence']
 
 def desc(column):
     """returns a descending ORDER BY clause element, e.g.:
@@ -125,6 +125,9 @@ def exists(*args, **params):
 def union(*selects, **params):
     return _compound_select('UNION', *selects, **params)
 
+def union_all(*selects, **params):
+    return _compound_select('UNION ALL', *selects, **params)
+
 def alias(*args, **params):
     return Alias(*args, **params)
 
@@ -178,6 +181,7 @@ class ClauseVisitor(schema.SchemaVisitor):
     def visit_select(self, select):pass
     def visit_join(self, join):pass
     def visit_null(self, null):pass
+    def visit_clauselist(self, list):pass
     
 class Compiled(ClauseVisitor):
     """represents a compiled SQL expression.  the __str__ method of the Compiled object
@@ -523,6 +527,9 @@ class Selectable(FromClause):
     def outerjoin(self, right, *args, **kwargs):
         return Join(self, right, isouter = True, *args, **kwargs)
 
+    def alias(self, name):
+        return Alias(self, name)
+        
     def group_parenthesized(self):
         """indicates if this Selectable requires parenthesis when grouped into a compound statement"""
         return True
@@ -679,6 +686,9 @@ class TableImpl(Selectable):
     
     def outerjoin(self, right, *args, **kwargs):
         return Join(self.table, right, isouter = True, *args, **kwargs)
+
+    def alias(self, name):
+        return Alias(self.table, name)
             
     def select(self, whereclauses = None, **params):
         return select([self.table], whereclauses, **params)
@@ -709,7 +719,7 @@ class Select(Selectable):
     the ability to execute itself and return a result set."""
     def __init__(self, columns, whereclause = None, from_obj = [], group_by = None, order_by = None, use_labels = False, engine = None):
         self.columns = util.OrderedProperties()
-        self.froms = util.OrderedDict()
+        self._froms = util.OrderedDict()
         self.use_labels = use_labels
         self.id = "Select(%d)" % id(self)
         self.name = None
@@ -724,6 +734,7 @@ class Select(Selectable):
         self._text = None
         self._raw_columns = []
         self._clauses = []
+        self._correlated = None
         
         for c in columns:
             self.append_column(c)
@@ -740,17 +751,26 @@ class Select(Selectable):
         if order_by:
             self.order_by(*order_by)
 
+    class CorrelatedVisitor(ClauseVisitor):
+        def __init__(self, select):
+            self.select = select
+        def visit_select(self, select):
+            if select is self.select:
+                return
+            select.issubquery = True
+            select._correlated = self.select._froms
+
     def append_column(self, column):
         if _is_literal(column):
             column = ColumnClause(str(column), self)
 
         self._raw_columns.append(column)
 
-        column._process_from_dict(self.froms, False)
+        column._process_from_dict(self._froms, False)
         for f in column._get_from_objects():
             if self.rowid_column is None and hasattr(f, 'rowid_column'):
                 self.rowid_column = f.rowid_column._make_proxy(self)
-
+        
         for co in column.columns:
             if self.use_labels:
                 co._make_proxy(self, name = co.label)
@@ -761,14 +781,9 @@ class Select(Selectable):
         if type(whereclause) == str:
             whereclause = TextClause(whereclause)
 
-        class CorrelatedVisitor(ClauseVisitor):
-            def visit_select(s, select):
-                for f in self.froms.keys():
-                    select.clear_from(f)
-                    select.issubquery = True
-
-        whereclause.accept_visitor(CorrelatedVisitor())
-        whereclause._process_from_dict(self.froms, False)
+        visitor = Select.CorrelatedVisitor(self)
+        whereclause.accept_visitor(visitor)
+        whereclause._process_from_dict(self._froms, False)
         
         if self.whereclause is not None:
             self.whereclause = and_(self.whereclause, whereclause)
@@ -782,7 +797,7 @@ class Select(Selectable):
         if type(fromclause) == str:
             fromclause = FromClause(from_name = fromclause)
 
-        fromclause._process_from_dict(self.froms, True)
+        fromclause._process_from_dict(self._froms, True)
         
     def append_clause(self, keyword, clause):
         if type(clause) == str:
@@ -796,10 +811,18 @@ class Select(Selectable):
         if engine is None:
             raise "no engine supplied, and no engine could be located within the clauses!"
 
+        # TODO: this has issues
+        #visitor = Select.CorrelatedVisitor(self)
+        #self.accept_visitor(visitor)
+
         return engine.compile(self, bindparams)
 
+    def _get_froms(self):
+        return [f for f in self._froms.values() if self._correlated is None or not self._correlated.has_key(f.id)]
+    froms = property(lambda s: s._get_froms())
+    
     def accept_visitor(self, visitor):
-        for f in self.froms.values():
+        for f in self.froms:
             f.accept_visitor(visitor)
         if self.whereclause is not None:
             self.whereclause.accept_visitor(visitor)
@@ -825,7 +848,7 @@ class Select(Selectable):
         if self._engine:
             return self._engine
         
-        for f in self.froms.values():
+        for f in self.froms:
             e = f.engine
             if e is not None:
                 return e
index 3c626eaf9d66e680c71cacc2bf34f722a72589ea..86b9861d6505f365d21b6a57f02bb1583ec3b99a 100644 (file)
@@ -156,7 +156,7 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") s
         # create a select for a join of two tables.  use_labels means the column names will have
         # labels tablename_columnname, which become the column keys accessible off the Selectable object.
         # also, only use one column from the second table and all columns from the first table.
-        q = select([table, table2.c.id], table.c.id == table2.c.id, use_labels = False)
+        q = select([table, table2.c.id], table.c.id == table2.c.id, use_labels = True)
         
         # make an alias of the "selectable".  column names stay the same (i.e. the labels), table name "changes" to "t2view".
         a = alias(q, 't2view')