Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #377 #390 #394 #440

Merged
merged 8 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion sql_metadata/generalizator.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def without_comments(self) -> str:
:rtype: str
"""
sql = sqlparse.format(self._raw_query, strip_comments=True)
sql = re.sub(r"\s{2,}", " ", sql)
sql = sql.replace("\n", " ")
sql = re.sub(r"[ \t]+", " ", sql)
return sql

@property
Expand Down
12 changes: 8 additions & 4 deletions sql_metadata/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,12 +533,16 @@ def subqueries(self) -> Dict:
):
current_subquery.append(inner_token)
inner_token = inner_token.next_token

query_name = None
if inner_token.next_token.value in self.subqueries_names:
query_name = inner_token.next_token.value
else:
elif inner_token.next_token.is_as_keyword:
query_name = inner_token.next_token.next_token.value

subquery_text = "".join([x.stringified_token for x in current_subquery])
subqueries[query_name] = subquery_text
if query_name is not None:
subqueries[query_name] = subquery_text

token = token.next_token

Expand Down Expand Up @@ -622,7 +626,7 @@ def without_comments(self) -> str:
"""
Removes comments from SQL query
"""
return Generalizator(self.query).without_comments
return Generalizator(self._raw_query).without_comments

@property
def generalize(self) -> str:
Expand Down Expand Up @@ -865,7 +869,7 @@ def _determine_opening_parenthesis_type(self, token: SQLToken):
# we are in columns and in a column subquery definition
token.is_column_definition_start = True
elif (
token.previous_token.is_as_keyword
token.previous_token_not_comment.is_as_keyword
and token.last_keyword_normalized != "WINDOW"
):
# window clause also contains AS keyword, but it is not a query
Expand Down
9 changes: 9 additions & 0 deletions sql_metadata/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,15 @@ def next_token_not_comment(self):
return self.next_token.next_token_not_comment
return self.next_token

@property
def previous_token_not_comment(self):
"""
Property returning previous non-comment token
"""
if self.previous_token and self.previous_token.is_comment:
return self.previous_token.previous_token_not_comment
return self.previous_token

def is_constraint_definition_inside_create_table_clause(
self, query_type: str
) -> bool:
Expand Down
8 changes: 8 additions & 0 deletions test/test_comments.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,11 @@ def test_next_token_not_comment_on_non_comments():
select_tok.next_token.next_token
== select_tok.next_token_not_comment.next_token_not_comment
)


def test_without_comments_for_multiline_query():
query = """SELECT * -- comment
FROM table
WHERE table.id = '123'"""
parser = Parser(query)
assert parser.without_comments == """SELECT * FROM table WHERE table.id = '123'"""
42 changes: 42 additions & 0 deletions test/test_getting_columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,14 @@ def test_columns_with_comments():
"order_by": ["cl_sortkey"],
}

parser = Parser(
"""WITH aa AS --sdfsdfsdf
(SELECT C1, C2 FROM T1)
SELECT C1, C2 FROM aa"""
)
assert parser.columns == ["C1", "C2"]
assert parser.columns_dict == {"select": ["C1", "C2"]}


def test_columns_with_keyword_aliases():
parser = Parser(
Expand Down Expand Up @@ -477,3 +485,37 @@ def test_having_columns():
"group_by": ["Country"],
"having": ["CustomerID"],
}


def test_nested_queries():
query = """
SELECT max(dt) FROM
(
SELECT max(dt) as dt FROM t
UNION ALL
SELECT max(dt) as dt FROM t2
)
"""
parser = Parser(query)
assert parser.columns == ["dt"]
assert parser.columns_dict == {"select": ["dt"]}

query = """
SELECT max(dt) FROM
(
SELECT max(dt) as dt FROM t
)
"""
parser = Parser(query)
assert parser.columns == ["dt"]
assert parser.columns_dict == {"select": ["dt"]}

query = """
SELECT max(dt) FROM
(
SELECT dt FROM t
)
"""
parser = Parser(query)
assert parser.columns == ["dt"]
assert parser.columns_dict == {"select": ["dt"]}