]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed bug where the truncation of long labels in SQL could produce
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 28 Apr 2015 20:02:59 +0000 (16:02 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 28 Apr 2015 20:02:59 +0000 (16:02 -0400)
a label that overlapped another label that is not truncated; this
because the length threshhold for truncation was greater than
the portion of the label that remains after truncation.  These
two values have now been made the same; label_length - 6.
The effect here is that shorter column labels will be "truncated"
where they would not have been truncated before.
fixes #3396

doc/build/changelog/changelog_10.rst
lib/sqlalchemy/sql/compiler.py
test/sql/test_labels.py

index 5b0ddf64fe2594b871fc68a16ff288ac592977a5..5c39566b9050365425990bd72357a6f6924491d0 100644 (file)
 .. changelog::
     :version: 1.0.3
 
+    .. change::
+        :tags: bug, sql
+        :tickets: 3396
+
+        Fixed bug where the truncation of long labels in SQL could produce
+        a label that overlapped another label that is not truncated; this
+        because the length threshhold for truncation was greater than
+        the portion of the label that remains after truncation.  These
+        two values have now been made the same; label_length - 6.
+        The effect here is that shorter column labels will be "truncated"
+        where they would not have been truncated before.
+
     .. change::
         :tags: bug, orm
         :tickets: 3392
index 91b677a0efc4850f8db1ca692bf630eecb7628c0..c9c7fd2a15821afec73a8b31aa875616e517af55 100644 (file)
@@ -1133,7 +1133,7 @@ class SQLCompiler(Compiled):
 
         anonname = name.apply_map(self.anon_map)
 
-        if len(anonname) > self.label_length:
+        if len(anonname) > self.label_length - 6:
             counter = self.truncated_names.get(ident_class, 1)
             truncname = anonname[0:max(self.label_length - 6, 0)] + \
                 "_" + hex(counter)[2:]
index 1792a42d8fe78086a0ad7244ab1bae8e71f137d2..7f548eb491af6cd0a20beb548add7806c2748d51 100644 (file)
@@ -138,8 +138,9 @@ class MaxIdentTest(fixtures.TestBase, AssertsCompiledSQL):
             issuperset(['this_is_the_data_column',
                         s.c.this_is_the_data_column])
         assert \
-            set(compiled._create_result_map()['this_is_the_primarykey_column'][1]).\
+            set(compiled._create_result_map()['this_is_the_primarykey__1'][1]).\
             issuperset(['this_is_the_primarykey_column',
+                        'this_is_the_primarykey__1',
                         s.c.this_is_the_primarykey_column])
 
     def test_result_map_anon_alias(self):
@@ -150,29 +151,28 @@ class MaxIdentTest(fixtures.TestBase, AssertsCompiledSQL):
         s = select([q]).apply_labels()
 
         self.assert_compile(
-            s, 'SELECT '
-            'anon_1.this_is_the_primarykey_column '
-            'AS anon_1_this_is_the_prim_1, '
-            'anon_1.this_is_the_data_column '
-            'AS anon_1_this_is_the_data_2 '
-            'FROM ('
-            'SELECT '
-            'some_large_named_table.'
-            'this_is_the_primarykey_column '
-            'AS this_is_the_primarykey_column, '
-            'some_large_named_table.this_is_the_data_column '
-            'AS this_is_the_data_column '
-            'FROM '
-            'some_large_named_table '
-            'WHERE '
-            'some_large_named_table.this_is_the_primarykey_column '
-            '= :this_is_the_primarykey__1'
-            ') '
-            'AS anon_1', dialect=dialect)
+            s,
+            "SELECT "
+            "anon_1.this_is_the_primarykey__2 AS anon_1_this_is_the_prim_1, "
+            "anon_1.this_is_the_data_column AS anon_1_this_is_the_data_3 "
+            "FROM ("
+            "SELECT "
+            "some_large_named_table."
+            "this_is_the_primarykey_column AS this_is_the_primarykey__2, "
+            "some_large_named_table."
+            "this_is_the_data_column AS this_is_the_data_column "
+            "FROM "
+            "some_large_named_table "
+            "WHERE "
+            "some_large_named_table.this_is_the_primarykey_column "
+            "= :this_is_the_primarykey__1"
+            ") "
+            "AS anon_1", dialect=dialect)
+
         compiled = s.compile(dialect=dialect)
-        assert set(compiled._create_result_map()['anon_1_this_is_the_data_2'][1]).\
+        assert set(compiled._create_result_map()['anon_1_this_is_the_data_3'][1]).\
             issuperset([
-                'anon_1_this_is_the_data_2',
+                'anon_1_this_is_the_data_3',
                 q.corresponding_column(
                     table1.c.this_is_the_data_column)
             ])
@@ -542,3 +542,26 @@ class LabelLengthTest(fixtures.TestBase, AssertsCompiledSQL):
         compiled = s.compile(dialect=dialect)
         assert set(compiled._create_result_map()['_1'][1]).issuperset([
             'asdf_abcde', a1.c.abcde, '_1'])
+
+    def test_label_overlap_unlabeled(self):
+        """test that an anon col can't overlap with a fixed name, #3396"""
+
+        table1 = table(
+            "tablename", column('columnname_one'), column('columnn_1'))
+
+        stmt = select([table1]).apply_labels()
+
+        dialect = default.DefaultDialect(label_length=23)
+        self.assert_compile(
+            stmt,
+            "SELECT tablename.columnname_one AS tablename_columnn_1, "
+            "tablename.columnn_1 AS tablename_columnn_2 FROM tablename",
+            dialect=dialect
+        )
+        compiled = stmt.compile(dialect=dialect)
+        eq_(
+            set(compiled._create_result_map()),
+            set(['tablename_columnn_1', 'tablename_columnn_2'])
+        )
+
+