]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- anonymous alias names now truncate down to the max length
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 10 Feb 2009 01:20:45 +0000 (01:20 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 10 Feb 2009 01:20:45 +0000 (01:20 +0000)
allowed by the dialect.  More significant on DBs like
Oracle with very small character limits. [ticket:1309]

CHANGES
lib/sqlalchemy/sql/compiler.py
test/sql/labels.py

diff --git a/CHANGES b/CHANGES
index ef8d2b3d41878d933d8fd4425a7333f93b962708..95dfab4d57cab8b63dd982ad676916f3b8134d52 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -25,6 +25,10 @@ CHANGES
     - Fixed missing _label attribute on Function object, others
       when used in a select() with use_labels (such as when used
       in an ORM column_property()).  [ticket:1302]
+
+    - anonymous alias names now truncate down to the max length
+      allowed by the dialect.  More significant on DBs like
+      Oracle with very small character limits. [ticket:1309]
       
     - the __selectable__() interface has been replaced entirely
       by __clause_element__().
index f34bd49060cbce6d59b48116b2e111a873235b26..3a982f23c43e32c296040bfcff17f468c7d939ba 100644 (file)
@@ -278,8 +278,9 @@ class DefaultCompiler(engine.Compiled):
             else:
                 schema_prefix = ''
             tablename = column.table.name
-            if isinstance(tablename, sql._generated_label):
-                tablename = tablename % self.anon_map
+            tablename = isinstance(tablename, sql._generated_label) and \
+                            self._truncated_identifier("alias", tablename) or tablename
+            
             return schema_prefix + self.preparer.quote(tablename, column.table.quote) + "." + name
 
     def escape_literal_column(self, text):
@@ -454,8 +455,11 @@ class DefaultCompiler(engine.Compiled):
 
     def visit_alias(self, alias, asfrom=False, **kwargs):
         if asfrom:
+            alias_name = isinstance(alias.name, sql._generated_label) and \
+                            self._truncated_identifier("alias", alias.name) or alias.name
+            
             return self.process(alias.original, asfrom=True, **kwargs) + " AS " + \
-                    self.preparer.format_alias(alias, alias.name % self.anon_map)
+                    self.preparer.format_alias(alias, alias_name)
         else:
             return self.process(alias.original, **kwargs)
 
index 5a620be8c89abe0e94e883723372559a8509b5eb..94ee20342e6ac7cb5d39c98c06a3337920c773ba 100644 (file)
@@ -4,9 +4,6 @@ from sqlalchemy import exc as exceptions
 from testlib import *
 from sqlalchemy.engine import default
 
-# TODO: either create a mock dialect with named paramstyle and a short identifier length,
-# or find a way to just use sqlite dialect and make those changes
-
 IDENT_LENGTH = 29
 
 class LabelTypeTest(TestBase):
@@ -20,13 +17,18 @@ class LabelTypeTest(TestBase):
 
 class LongLabelsTest(TestBase, AssertsCompiledSQL):
     def setUpAll(self):
-        global metadata, table1, maxlen
+        global metadata, table1, table2, maxlen
         metadata = MetaData(testing.db)
         table1 = Table("some_large_named_table", metadata,
             Column("this_is_the_primarykey_column", Integer, Sequence("this_is_some_large_seq"), primary_key=True),
             Column("this_is_the_data_column", String(30))
             )
 
+        table2 = Table("table_with_exactly_29_characs", metadata,
+            Column("this_is_the_primarykey_column", Integer, Sequence("some_seq"), primary_key=True),
+            Column("this_is_the_data_column", String(30))
+            )
+
         metadata.create_all()
 
         maxlen = testing.db.dialect.max_identifier_length
@@ -87,6 +89,37 @@ class LongLabelsTest(TestBase, AssertsCompiledSQL):
             (3, "data3"),
         ], repr(result)
 
+    def test_table_alias_names(self):
+        self.assert_compile(
+            table2.alias().select(),
+            "SELECT table_with_exactly_29_c_1.this_is_the_primarykey_column, table_with_exactly_29_c_1.this_is_the_data_column FROM table_with_exactly_29_characs AS table_with_exactly_29_c_1"
+        )
+
+        ta = table2.alias()
+        dialect = default.DefaultDialect()
+        dialect.max_identifier_length = IDENT_LENGTH
+        self.assert_compile(
+            select([table1, ta]).select_from(table1.join(ta, table1.c.this_is_the_data_column==ta.c.this_is_the_data_column)).\
+                        where(ta.c.this_is_the_data_column=='data3'),
+                        
+            "SELECT some_large_named_table.this_is_the_primarykey_column, some_large_named_table.this_is_the_data_column, "
+            "table_with_exactly_29_c_1.this_is_the_primarykey_column, table_with_exactly_29_c_1.this_is_the_data_column FROM "
+            "some_large_named_table JOIN table_with_exactly_29_characs AS table_with_exactly_29_c_1 ON "
+            "some_large_named_table.this_is_the_data_column = table_with_exactly_29_c_1.this_is_the_data_column "
+            "WHERE table_with_exactly_29_c_1.this_is_the_data_column = :this_is_the_data_column_1",
+            dialect=dialect
+        )
+        
+        table2.insert().execute(
+            {"this_is_the_primarykey_column":1, "this_is_the_data_column":"data1"},
+            {"this_is_the_primarykey_column":2, "this_is_the_data_column":"data2"},
+            {"this_is_the_primarykey_column":3, "this_is_the_data_column":"data3"},
+            {"this_is_the_primarykey_column":4, "this_is_the_data_column":"data4"},
+        )
+        
+        r = table2.alias().select().execute()
+        assert r.fetchall() == [(x, "data%d" % x) for x in range(1, 5)]
+        
     def test_colbinds(self):
         table1.insert().execute(**{"this_is_the_primarykey_column":1, "this_is_the_data_column":"data1"})
         table1.insert().execute(**{"this_is_the_primarykey_column":2, "this_is_the_data_column":"data2"})
@@ -153,9 +186,9 @@ class LongLabelsTest(TestBase, AssertsCompiledSQL):
             "FROM some_large_named_table WHERE some_large_named_table.this_is_the_primarykey_column = :this_1) AS anon_1", dialect=compile_dialect)
 
         compile_dialect = default.DefaultDialect(label_length=4)
-        self.assert_compile(x, "SELECT anon_1.this_is_the_primarykey_column AS _1, anon_1.this_is_the_data_column AS _2 FROM "
+        self.assert_compile(x, "SELECT _1.this_is_the_primarykey_column AS _1, _1.this_is_the_data_column AS _2 FROM "
             "(SELECT some_large_named_table.this_is_the_primarykey_column AS _3, some_large_named_table.this_is_the_data_column AS _4 "
-            "FROM some_large_named_table WHERE some_large_named_table.this_is_the_primarykey_column = :_1) AS anon_1", dialect=compile_dialect)
+            "FROM some_large_named_table WHERE some_large_named_table.this_is_the_primarykey_column = :_1) AS _1", dialect=compile_dialect)
         
         
 if __name__ == '__main__':