fix(mssql): support top syntax for limiting queries (#18746)

* SQL-TOP Fix For Database Engines

MSSQL is not supporting LIMIT syntax in SQLs. For limiting the rows, MSSQL having a different keyword TOP. Added fixes for handling the TOP and LIMIT clauses based on the database engines.

* Teradata code for top clause handling removed from teradata.py

Teradata code for top clause handling removed from teradata.py file, since we added generic section in base engine for the same.

* Changes to handle CTE along with TOP in complex SQLs

Added changes to handle TOP command in CTEs, for DB Engines which are not supporting inline CTEs.

* Test cases for TOP unit testing in MSSQL

Added multiple unit test cases for MSSQL top command handling and also along with CTEs

* Corrected the select_keywords name key in basengine

Corrected the select_keywords name key in basengine

* Changes based on as per review.

made the required corrections based on code review to keep good code readability and code cleanliness.

* Review changes to correct lint and typo issues

Made the changes according to the review comments.

* fix linting errors

* fix teradata tests

* add coverage

* lint

* Code cleanliness

Moved the top/limit flag check from sql_lab to core.

* Changed for code cleanliness

Changes for keeping code cleanliness

* Corrected lint issue

Corrected lint issue.

* Code cleanliness

Code cleanliness

Co-authored-by: Ville Brofeldt <ville.v.brofeldt@gmail.com>
This commit is contained in:
Sujith Kumar S
2022-02-21 13:28:39 +05:30
committed by GitHub
parent a29153778e
commit 7e51b200b4
8 changed files with 196 additions and 302 deletions

View File

@@ -231,6 +231,37 @@ def test_cte_query_parsing(
assert actual == expected
@pytest.mark.parametrize(
"original,expected,top",
[
("SEL TOP 1000 * FROM My_table", "SEL TOP 100 * FROM My_table", 100),
("SEL TOP 1000 * FROM My_table;", "SEL TOP 100 * FROM My_table", 100),
("SEL TOP 1000 * FROM My_table;", "SEL TOP 1000 * FROM My_table", 10000),
("SEL TOP 1000 * FROM My_table;", "SEL TOP 1000 * FROM My_table", 1000),
(
"""with abc as (select * from test union select * from test1)
select TOP 100 * from currency""",
"""WITH abc as (select * from test union select * from test1)
select TOP 100 * from currency""",
1000,
),
("SELECT 1 as cnt", "SELECT TOP 10 1 as cnt", 10),
(
"select TOP 1000 * from abc where id=1",
"select TOP 10 * from abc where id=1",
10,
),
],
)
def test_top_query_parsing(
app_context: AppContext, original: TypeEngine, expected: str, top: int
) -> None:
from superset.db_engine_specs.mssql import MssqlEngineSpec
actual = MssqlEngineSpec.apply_top_to_sql(original, top)
assert actual == expected
def test_extract_errors(app_context: AppContext) -> None:
"""
Test that custom error messages are extracted correctly.