Skip to content

Commit

Permalink
Added escape_name function to escape individual SQL names and `esca…
Browse files Browse the repository at this point in the history
…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
nfx authored Nov 8, 2024
1 parent aae9ea1 commit 776e1cf
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/databricks/labs/lsql/escapes.py
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)
34 changes: 34 additions & 0 deletions tests/unit/test_escapes.py
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`"

0 comments on commit 776e1cf

Please sign in to comment.