summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Albrecht <a.albrecht@Mac-PU08.prounix.local>2019-10-09 11:14:27 +0200
committerAndreas Albrecht <a.albrecht@Mac-PU08.prounix.local>2019-10-09 11:14:27 +0200
commite8ae45d9f0e4238add9e24af2b8cfbc1665aab77 (patch)
tree451cba08a3ac2f9e7c8e56abc3133acb33a13538
parent91cfc1bfcd86640538fa98b6ceaae64d0d4c9328 (diff)
downloadsqlparse-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--CHANGELOG2
-rw-r--r--sqlparse/sql.py42
-rw-r--r--tests/test_grouping.py7
-rw-r--r--tests/test_parse.py4
4 files changed, 35 insertions, 20 deletions
diff --git a/CHANGELOG b/CHANGELOG
index b2df0af..713bad9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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():