summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/changelog_08.rst8
-rw-r--r--lib/sqlalchemy/schema.py6
-rw-r--r--lib/sqlalchemy/sql/expression.py17
-rw-r--r--test/sql/test_labels.py43
4 files changed, 66 insertions, 8 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst
index 3ef8bb632..012a052c8 100644
--- a/doc/build/changelog/changelog_08.rst
+++ b/doc/build/changelog/changelog_08.rst
@@ -7,6 +7,14 @@
: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 2fb542a43..4f3655a1d 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 706549518..ee6f134b4 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 05671619e..d7cb8db4a 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'
+ ])
+
+