From: Mike Bayer Date: Sun, 9 Dec 2012 00:25:04 +0000 (-0500) Subject: Fixed bug whereby using a label_length on dialect that was smaller X-Git-Tag: rel_0_8_0b2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33bafcb132ed959f072f98fa488b05e5628f097b;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Fixed bug whereby using a label_length on dialect that was smaller than the size of actual column identifiers would fail to render the columns correctly in a SELECT statement. [ticket:2610] --- diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index 3ef8bb6324..012a052c83 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -6,6 +6,14 @@ .. changelog:: :version: 0.8.0b2 + .. change:: + :tags: sql, bug + :tickets: 2610 + + Fixed bug whereby using a label_length on dialect that was smaller + than the size of actual column identifiers would fail to render + the columns correctly in a SELECT statement. + .. change:: :tags: sql, feature :tickets: 2623 diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 2fb542a430..4f3655a1da 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -1114,7 +1114,8 @@ class Column(SchemaItem, expression.ColumnClause): c.dispatch._update(self.dispatch) return c - def _make_proxy(self, selectable, name=None, key=None): + def _make_proxy(self, selectable, name=None, key=None, + name_is_truncatable=False, **kw): """Create a *proxy* for this column. This is a copy of this ``Column`` referenced by a different parent @@ -1130,7 +1131,8 @@ class Column(SchemaItem, expression.ColumnClause): "been assigned.") try: c = self._constructor( - expression._as_truncated(name or self.name), + expression._as_truncated(name or self.name) if \ + name_is_truncatable else (name or self.name), self.type, key=key if key else name if name else self.key, primary_key=self.primary_key, diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 7065495181..ee6f134b4d 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -2320,7 +2320,7 @@ class ColumnElement(ClauseElement, ColumnOperators): return hasattr(other, 'name') and hasattr(self, 'name') and \ other.name == self.name - def _make_proxy(self, selectable, name=None, **kw): + def _make_proxy(self, selectable, name=None, name_is_truncatable=False, **kw): """Create a new :class:`.ColumnElement` representing this :class:`.ColumnElement` as it appears in the select list of a descending selectable. @@ -2331,7 +2331,7 @@ class ColumnElement(ClauseElement, ColumnOperators): key = str(self) else: key = name - co = ColumnClause(_as_truncated(name), + co = ColumnClause(_as_truncated(name) if name_is_truncatable else name, selectable, type_=getattr(self, 'type', None)) @@ -4490,12 +4490,15 @@ class ColumnClause(Immutable, ColumnElement): _compared_to_type=self.type, unique=True) - def _make_proxy(self, selectable, name=None, attach=True, **kw): + def _make_proxy(self, selectable, name=None, attach=True, + name_is_truncatable=False, **kw): # propagate 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 = self._constructor( - _as_truncated(name if name else self.name), + _as_truncated(name or self.name) if \ + name_is_truncatable else \ + (name or self.name), selectable=selectable, type_=self.type, is_literal=is_literal @@ -5727,7 +5730,8 @@ class Select(HasPrefixes, SelectBase): if hasattr(c, '_make_proxy'): c._make_proxy(self, name=c._label if self.use_labels else None, - key=c._key_label if self.use_labels else None) + key=c._key_label if self.use_labels else None, + name_is_truncatable=True) def _refresh_for_new_column(self, column): for fromclause in self._froms: @@ -5738,7 +5742,8 @@ class Select(HasPrefixes, SelectBase): if our_label not in self.c: return col._make_proxy(self, name=col._label if self.use_labels else None, - key=col._key_label if self.use_labels else None) + key=col._key_label if self.use_labels else None, + name_is_truncatable=True) return None return None diff --git a/test/sql/test_labels.py b/test/sql/test_labels.py index 05671619ef..d7cb8db4a3 100644 --- a/test/sql/test_labels.py +++ b/test/sql/test_labels.py @@ -491,3 +491,46 @@ class LabelLengthTest(fixtures.TestBase, AssertsCompiledSQL): dialect=compile_dialect) + def test_colnames_longer_than_labels_lowercase(self): + t1 = table('a', column('abcde')) + self._test_colnames_longer_than_labels(t1) + + def test_colnames_longer_than_labels_uppercase(self): + m = MetaData() + t1 = Table('a', m, Column('abcde', Integer)) + self._test_colnames_longer_than_labels(t1) + + def _test_colnames_longer_than_labels(self, t1): + dialect = default.DefaultDialect(label_length=4) + a1 = t1.alias(name='asdf') + + # 'abcde' is longer than 4, but rendered as itself + # needs to have all characters + s = select([a1]) + self.assert_compile( + select([a1]), + "SELECT asdf.abcde FROM a AS asdf", + dialect=dialect + ) + compiled = s.compile(dialect=dialect) + assert set(compiled.result_map['abcde'][1]).issuperset([ + 'abcde', + a1.c.abcde, + 'abcde' + ]) + + # column still there, but short label + s = select([a1]).apply_labels() + self.assert_compile( + s, + "SELECT asdf.abcde AS _1 FROM a AS asdf", + dialect=dialect + ) + compiled = s.compile(dialect=dialect) + assert set(compiled.result_map['_1'][1]).issuperset([ + 'asdf_abcde', + a1.c.abcde, + '_1' + ]) + +