fix(sql): handle backtick-quoted identifiers with base dialect (#36545)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Evan Rusackas
2025-12-15 13:00:13 -08:00
committed by Beto Dealmeida
parent d97a2a0425
commit 82b0fa6d07
2 changed files with 113 additions and 3 deletions

View File

@@ -3805,7 +3805,7 @@ def test_apply_cls_where_clause_hash() -> None:
# The WHERE clause should have the column hashed
assert "MD5" in result
assert 'WHERE' in result
assert "WHERE" in result
assert "MD5(CAST" in result
@@ -4208,8 +4208,8 @@ def test_apply_cls_where_no_rules_unchanged() -> None:
# No transformation should occur - just column qualification
assert "WHERE" in result
assert 'MD5' not in result
assert 'FALSE' not in result
assert "MD5" not in result
assert "FALSE" not in result
def test_apply_cls_table_with_schema() -> None:
@@ -4690,3 +4690,96 @@ def test_merge_cls_rules_complex_scenario() -> None:
"credit_card": CLSAction.HIDE,
},
}
@pytest.mark.parametrize(
"sql, engine, expected_tables",
[
# Issue #31853: Backtick-quoted table names with "Other" database type
(
"SELECT * FROM database.`6`",
"base",
{Table(table="6", schema="database")},
),
(
"SELECT * FROM database.`6` LIMIT 100",
"base",
{Table(table="6", schema="database")},
),
# Backtick-quoted table name without schema
(
"SELECT * FROM `my_table`",
"base",
{Table(table="my_table")},
),
# Backtick-quoted schema and table
(
"SELECT * FROM `my_schema`.`my_table`",
"base",
{Table(table="my_table", schema="my_schema")},
),
# Complex query with multiple backtick-quoted identifiers
(
"SELECT `col1`, `col2` FROM `schema`.`table` WHERE `id` = 1",
"base",
{Table(table="table", schema="schema")},
),
# Unknown engine should also fall back
(
"SELECT * FROM `table_name`",
"unknown-engine",
{Table(table="table_name")},
),
# Multiple tables with backticks
(
"SELECT * FROM `t1` JOIN `t2` ON `t1`.id = `t2`.id",
"base",
{Table(table="t1"), Table(table="t2")},
),
# Backticks in subquery
(
"SELECT * FROM (SELECT * FROM `inner_table`) AS sub",
"base",
{Table(table="inner_table")},
),
],
)
def test_backtick_quoted_identifiers_base_dialect(
sql: str, engine: str, expected_tables: set[Table]
) -> None:
"""
Test that backtick-quoted identifiers work with base dialect.
This is a regression test for issue #31853 where SQL parsing fails
with "Other" database type when using backtick-quoted table names.
The fix adds a fallback to MySQL dialect when parsing fails with
base dialect and backticks are present in the SQL.
"""
script = SQLScript(sql, engine)
assert len(script.statements) == 1
assert script.statements[0].tables == expected_tables
def test_backtick_normal_sql_still_works() -> None:
"""
Test that normal SQL without backticks still works with base dialect.
This ensures the backtick fallback doesn't break normal parsing.
"""
sql = "SELECT col1, col2 FROM my_schema.my_table WHERE id = 1"
script = SQLScript(sql, "base")
assert len(script.statements) == 1
assert script.statements[0].tables == {Table(table="my_table", schema="my_schema")}
def test_backtick_invalid_sql_still_fails() -> None:
"""
Test that invalid SQL with backticks still raises an error.
The fallback should only succeed when the MySQL dialect can parse
the SQL successfully.
"""
# Invalid SQL that should fail even with MySQL dialect
sql = "SELECT * FROM `table` WHERE"
with pytest.raises(SupersetParseError):
SQLScript(sql, "base")