Skip to content
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
125 changes: 86 additions & 39 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ python = "^3.10"
sqlparse = ">=0.4.1,<0.6.0"

[tool.poetry.dev-dependencies]
black = "^25.11"
black = "^26.3"
coverage = {extras = ["toml"], version = "^7.13"}
pylint = "^3.3.9"
pytest = "^9.0.2"
Expand Down
1 change: 1 addition & 0 deletions sql_metadata/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""
This module provides SQL query parsing functions
"""

import logging
import re
from typing import Dict, List, Optional, Set, Tuple, Union
Expand Down
18 changes: 6 additions & 12 deletions test/test_create_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,25 @@ def test_is_create_table_query():


def test_create_table():
parser = Parser(
"""
parser = Parser("""
CREATE TABLE `new_table` (
`item_id` int(9) NOT NULL AUTO_INCREMENT,
`foo` varchar(16) NOT NULL DEFAULT '',
PRIMARY KEY (`item_id`,`foo`),
KEY `idx_foo` (`foo`)
) CHARACTER SET utf8;
"""
)
""")
assert parser.query_type == QueryType.CREATE
assert parser.tables == ["new_table"]
assert parser.columns == ["item_id", "foo"]


def test_simple_create_table_as_select():
parser = Parser(
"""
parser = Parser("""
CREATE table abc.foo
as SELECT pqr.foo1 , ab.foo2
FROM foo pqr, bar ab;
"""
)
""")
assert parser.query_type == QueryType.CREATE
assert parser.tables == ["abc.foo", "foo", "bar"]
assert parser.columns == ["foo.foo1", "bar.foo2"]
Expand Down Expand Up @@ -168,11 +164,9 @@ def test_create_if_not_exists_simple_name():

def test_create_temporary_table():
# https://dev.mysql.com/doc/refman/8.4/en/create-temporary-table.html
parser = Parser(
"""
parser = Parser("""
CREATE TEMPORARY TABLE new_tbl SELECT * FROM orig_tbl LIMIT 0;;
"""
)
""")
assert parser.query_type == QueryType.CREATE
assert parser.tables == ["new_tbl", "orig_tbl"]
assert parser.columns == ["*"]
15 changes: 4 additions & 11 deletions test/test_getting_columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,10 @@ def test_getting_columns():
"test",
]
assert Parser("SELECT /* a comment */ bar FROM test_table").columns == ["bar"]
assert (
Parser(
"""
assert Parser("""
WITH foo AS (SELECT test_table.* FROM test_table)
SELECT foo.bar FROM foo
"""
).columns
== ["test_table.*", "bar"]
)
""").columns == ["test_table.*", "bar"]


def test_columns_with_order_by():
Expand Down Expand Up @@ -273,11 +268,9 @@ def test_columns_with_comments():
"order_by": ["cl_sortkey"],
}

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

Expand Down
42 changes: 10 additions & 32 deletions test/test_getting_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,9 @@ def test_complex_query_tables():

# test whitespaces in keywords
# @see https://github.com/macbre/sql-metadata/issues/80
assert (
["tab", "tab2"]
== Parser(
"""SELECT a,b,c from tab
assert ["tab", "tab2"] == Parser("""SELECT a,b,c from tab
full outer \r\n\t join tab2 on (col1 = col2) group
\r\n \t by a, b, c """
).tables
)
\r\n \t by a, b, c """).tables


def test_joins():
Expand Down Expand Up @@ -291,16 +286,11 @@ def test_table_name_with_group_by():
== expected_tables
)

assert (
Parser(
"""
assert Parser("""
SELECT s.cust_id,count(s.cust_id) FROM SH.sales s
GROUP BY s.cust_id HAVING s.cust_id != '1660'
AND s.cust_id != '2'
""".strip()
).tables
== expected_tables
)
""".strip()).tables == expected_tables


def test_datasets():
Expand Down Expand Up @@ -344,31 +334,21 @@ def test_unions():


def test_with_brackets():
assert (
["database1.table1", "database2.table2"]
== Parser(
"""
assert ["database1.table1", "database2.table2"] == Parser("""
SELECT
"xxxxx"
FROM
(database1.table1 alias
LEFT JOIN database2.table2 ON ("tt"."ttt"."fff" = "xx"."xxx"))
"""
).tables
)
""").tables

assert (
["inner_table"]
== Parser(
"""
assert ["inner_table"] == Parser("""
SELECT
t.foo
FROM
(SELECT foo FROM inner_table
WHERE bar = '1') t
"""
).tables
)
""").tables


def test_db2_query():
Expand Down Expand Up @@ -725,16 +705,14 @@ def test_join_followed_by_tables():
parser = Parser(query)
assert parser.tables == ["web_sales", "web_returns", "date_dim", "web_site"]

parser = Parser(
"""
parser = Parser("""
SELECT *
FROM Sales
JOIN Customers
ON Sales.CustomerID = Customers.CustomerID,
(SELECT MAX(Revenue) FROM Sales),
Stores
"""
)
""")
assert parser.tables == ["Sales", "Customers", "Stores"]


Expand Down
36 changes: 12 additions & 24 deletions test/test_mssql_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,53 +39,45 @@ def test_sql_server_cte():
@see https://www.sqlservertutorial.net/sql-server-basics/sql-server-cte/
"""

parser = Parser(
"""
parser = Parser("""
WITH x AS (
SELECT * FROM n
)
SELECT
*
FROM x
JOIN y ON x.a = y.a
"""
)
""")
assert parser.tables == ["n", "y"]
assert parser.with_names == ["x"]
assert parser.with_queries == {"x": "SELECT * FROM n"}
assert parser.columns == ["*", "a", "y.a"]

parser = Parser(
"""
parser = Parser("""
WITH x AS (
SELECT * FROM n
)
SELECT
*
FROM x
JOIN y ON x.a = y.a
"""
)
""")
assert parser.tables == ["n", "y"]

parser = Parser(
"""
parser = Parser("""
WITH foo AS (
SELECT * FROM n
)
UPDATE z from foo set z.q = foo.y
"""
)
""")
assert parser.tables == ["n", "z"]

parser = Parser(
"""
parser = Parser("""
WITH foo AS (
SELECT * FROM tab
)
DELETE FROM z JOIN foo ON z.a = foo.a
"""
)
""")
assert parser.tables == ["tab", "z"]


Expand Down Expand Up @@ -133,8 +125,7 @@ def test_sql_server_cte_sales_by_year():

def test_partition_over_with_rank_and_one_order():
"""Test for #204"""
parser = Parser(
"""
parser = Parser("""
select t.RANKED, t.RANKED_two, t.test from (
SELECT
RANK() OVER (PARTITION BY col_one ORDER BY col_two) RANKED,
Expand All @@ -144,8 +135,7 @@ def test_partition_over_with_rank_and_one_order():
where t.RANKED = 1
and t.RANKED_two = 2
order by test
"""
)
""")
assert parser.tables == ["nice_table"]
assert parser.columns_aliases_names == ["RANKED", "RANKED_two", "test"]
assert parser.columns_aliases == {
Expand All @@ -163,8 +153,7 @@ def test_partition_over_with_rank_and_one_order():

def test_partition_over_with_row_number_and_many_orders():
"""Test for #204"""
parser = Parser(
"""
parser = Parser("""
select t.row_no, t.row_no_two, t.test from (
SELECT
ROW_NUMBER() OVER (
Expand All @@ -178,8 +167,7 @@ def test_partition_over_with_row_number_and_many_orders():
where t.row_no = 1
and t.row_no_two = 2
order by t.row_no
"""
)
""")
assert parser.tables == ["nice_table"]
assert parser.columns_aliases_names == ["row_no", "row_no_two", "test"]
assert parser.columns_aliases == {
Expand Down
6 changes: 2 additions & 4 deletions test/test_multiple_subqueries.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,14 +410,12 @@ def test_resolving_columns_in_sub_queries_functions():


def test_readme_query():
parser = Parser(
"""
parser = Parser("""
SELECT COUNT(1) FROM
(SELECT std.task_id FROM some_task_detail std WHERE std.STATUS = 1) a
JOIN (SELECT st.task_id FROM some_task st WHERE task_type_id = 80) b
ON a.task_id = b.task_id;
"""
)
""")
assert parser.subqueries == {
"a": "SELECT std.task_id FROM some_task_detail std WHERE std.STATUS = 1",
"b": "SELECT st.task_id FROM some_task st WHERE task_type_id = 80",
Expand Down
18 changes: 6 additions & 12 deletions test/test_with_statements.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@


def test_with_statements():
parser = Parser(
"""
parser = Parser("""
WITH
database1.tableFromWith AS (SELECT aa.* FROM table3 as aa
left join table4 on aa.col1=table4.col2),
Expand All @@ -16,17 +15,15 @@ def test_with_statements():
FROM
database1.tableFromWith alias
LEFT JOIN database2.table2 ON ("tt"."ttt"."fff" = "xx"."xxx")
"""
)
""")
assert parser.tables == ["table3", "table4", "database2.table2"]
assert parser.with_names == ["database1.tableFromWith", "test"]
assert parser.with_queries == {
"database1.tableFromWith": "SELECT aa.* FROM table3 as aa left join table4 on "
"aa.col1 = table4.col2",
"test": "SELECT * from table3",
}
parser = Parser(
"""
parser = Parser("""
WITH
database1.tableFromWith AS (SELECT * FROM table3),
database1.tableFromWith2 AS (SELECT * FROM table4),
Expand All @@ -37,8 +34,7 @@ def test_with_statements():
FROM
database1.tableFromWith alias
LEFT JOIN database2.table2 ON ("tt"."ttt"."fff" = "xx"."xxx")
"""
)
""")

assert parser.with_names == [
"database1.tableFromWith",
Expand All @@ -54,15 +50,13 @@ def test_with_statements():
}
assert parser.tables == ["table3", "table4", "table5", "table6", "database2.table2"]

parser = Parser(
"""
parser = Parser("""
WITH
cte1 AS (SELECT a, b FROM table1),
cte2 AS (SELECT c, d FROM table2)
SELECT cte1.b, d FROM cte1 JOIN cte2
WHERE cte1.a = cte2.c;
"""
)
""")

assert parser.with_names == ["cte1", "cte2"]
assert parser.with_queries == {
Expand Down