-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added
escape_name
function to escape individual SQL names and `esca…
…pe_full_name` function to escape dot-separated full names (#316) Ported from https://github.com/databrickslabs/ucx by @larsgeorge-db , @JCZuurmond , and @asnare .
- Loading branch information
Showing
2 changed files
with
53 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
def escape_name(name: str) -> str: | ||
"""Escapes the name to make it SQL safe.""" | ||
return f"`{name.strip('`').replace('`', '``')}`" | ||
|
||
|
||
def escape_full_name(full_name: str) -> str: | ||
""" | ||
Escapes the full name components to make them SQL safe. | ||
Args: | ||
full_name (str): The dot-separated name of a catalog object. | ||
Returns: | ||
str: The path with all parts escaped in backticks. | ||
""" | ||
if not full_name: | ||
return full_name | ||
parts = full_name.split(".", maxsplit=2) | ||
return ".".join(escape_name(part) for part in parts) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import pytest | ||
|
||
from databricks.labs.lsql.escapes import escape_full_name, escape_name | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"path,expected", | ||
[ | ||
("a", "`a`"), | ||
("a.b", "`a`.`b`"), | ||
("a.b.c", "`a`.`b`.`c`"), | ||
("`a`.b.c", "`a`.`b`.`c`"), | ||
("a.`b`.c", "`a`.`b`.`c`"), | ||
("a.b.`c`", "`a`.`b`.`c`"), | ||
("`a.b`.c", "`a`.`b`.`c`"), | ||
("a.`b.c`", "`a`.`b`.`c`"), | ||
("`a.b`.`c`", "`a`.`b`.`c`"), | ||
("`a`.`b.c`", "`a`.`b`.`c`"), | ||
("`a`.`b`.`c`", "`a`.`b`.`c`"), | ||
("a.b.c.d", "`a`.`b`.`c.d`"), | ||
("a-b.c.d", "`a-b`.`c`.`d`"), | ||
("a.b-c.d", "`a`.`b-c`.`d`"), | ||
("a.b.c-d", "`a`.`b`.`c-d`"), | ||
("a.b.c`d", "`a`.`b`.`c``d`"), | ||
("✨.🍰.✨", "`✨`.`🍰`.`✨`"), | ||
("", ""), | ||
], | ||
) | ||
def test_escaped_path(path: str, expected: str) -> None: | ||
assert escape_full_name(path) == expected | ||
|
||
|
||
def test_escaped_when_column_contains_period() -> None: | ||
assert escape_name("column.with.periods") == "`column.with.periods`" |