diff options
author | Andreas Albrecht <a.albrecht@Mac-PU08.prounix.local> | 2019-10-09 11:14:27 +0200 |
---|---|---|
committer | Andreas Albrecht <a.albrecht@Mac-PU08.prounix.local> | 2019-10-09 11:14:27 +0200 |
commit | e8ae45d9f0e4238add9e24af2b8cfbc1665aab77 (patch) | |
tree | 451cba08a3ac2f9e7c8e56abc3133acb33a13538 | |
parent | 91cfc1bfcd86640538fa98b6ceaae64d0d4c9328 (diff) | |
download | sqlparse-e8ae45d9f0e4238add9e24af2b8cfbc1665aab77.tar.gz |
Restrict detection of alias names (fixes #455).
This change adopts some parts of the pull request #509 by
john-bodley. Thanks!
-rw-r--r-- | CHANGELOG | 2 | ||||
-rw-r--r-- | sqlparse/sql.py | 42 | ||||
-rw-r--r-- | tests/test_grouping.py | 7 | ||||
-rw-r--r-- | tests/test_parse.py | 4 |
4 files changed, 35 insertions, 20 deletions
@@ -16,6 +16,8 @@ Bug Fixes * Remove support for parsing double slash comments introduced in 0.3.0 (issue456) as it had some side-effects with other dialects and doesn't seem to be widely used (issue476). +* Restrict detection of alias names to objects that acutally could + have an alias (issue455, adopted some parts of pr509 by john-bodley). Release 0.3.0 (Mar 11, 2019) diff --git a/sqlparse/sql.py b/sqlparse/sql.py index a752555..cff501c 100644 --- a/sqlparse/sql.py +++ b/sqlparse/sql.py @@ -16,6 +16,29 @@ from sqlparse.compat import string_types, text_type, unicode_compatible from sqlparse.utils import imt, remove_quotes +class NameAliasMixin: + """Implements get_real_name and get_alias.""" + + def get_real_name(self): + """Returns the real name (object name) of this identifier.""" + # a.b + dot_idx, _ = self.token_next_by(m=(T.Punctuation, '.')) + return self._get_first_name(dot_idx, real_name=True) + + def get_alias(self): + """Returns the alias for this identifier or ``None``.""" + + # "name AS alias" + kw_idx, kw = self.token_next_by(m=(T.Keyword, 'AS')) + if kw is not None: + return self._get_first_name(kw_idx + 1, keywords=True) + + # "name alias" or "complicated column expression alias" + _, ws = self.token_next_by(t=T.Whitespace) + if len(self.tokens) > 2 and ws is not None: + return self._get_first_name(reverse=True) + + @unicode_compatible class Token(object): """Base class for all other classes in this module. @@ -341,16 +364,7 @@ class TokenList(Token): def get_alias(self): """Returns the alias for this identifier or ``None``.""" - - # "name AS alias" - kw_idx, kw = self.token_next_by(m=(T.Keyword, 'AS')) - if kw is not None: - return self._get_first_name(kw_idx + 1, keywords=True) - - # "name alias" or "complicated column expression alias" - _, ws = self.token_next_by(t=T.Whitespace) - if len(self.tokens) > 2 and ws is not None: - return self._get_first_name(reverse=True) + return None def get_name(self): """Returns the name of this identifier. @@ -363,9 +377,7 @@ class TokenList(Token): def get_real_name(self): """Returns the real name (object name) of this identifier.""" - # a.b - dot_idx, _ = self.token_next_by(m=(T.Punctuation, '.')) - return self._get_first_name(dot_idx, real_name=True) + return None def get_parent_name(self): """Return name of the parent object if any. @@ -433,7 +445,7 @@ class Statement(TokenList): return 'UNKNOWN' -class Identifier(TokenList): +class Identifier(NameAliasMixin, TokenList): """Represents an identifier. Identifiers may have aliases or typecasts. @@ -599,7 +611,7 @@ class Case(TokenList): return ret -class Function(TokenList): +class Function(NameAliasMixin, TokenList): """A function or procedure call.""" def get_parameters(self): diff --git a/tests/test_grouping.py b/tests/test_grouping.py index 63a01f2..c2d8860 100644 --- a/tests/test_grouping.py +++ b/tests/test_grouping.py @@ -294,9 +294,10 @@ def test_grouping_subquery_no_parens(): assert isinstance(p.tokens[0], sql.Case) -def test_grouping_alias_returns_none(): - # see issue185 - p = sqlparse.parse('foo.bar')[0] +@pytest.mark.parametrize('s', ['foo.bar', 'x, y', 'x > y', 'x / y']) +def test_grouping_alias_returns_none(s): + # see issue185 and issue445 + p = sqlparse.parse(s)[0] assert len(p.tokens) == 1 assert p.tokens[0].get_alias() is None diff --git a/tests/test_parse.py b/tests/test_parse.py index f2a2bda..c28cb06 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -431,8 +431,8 @@ def test_get_real_name(): s = u"update a t set t.b=1" stmts = sqlparse.parse(s) assert len(stmts) == 1 - assert 'a' == stmts[0].get_real_name() - assert 't' == stmts[0].get_alias() + assert 'a' == stmts[0].tokens[2].get_real_name() + assert 't' == stmts[0].tokens[2].get_alias() def test_from_subquery(): |