Uh oh!
There was an error while loading. Please reload this page.
Commit 2c1bc55
committed
Handle literal backtick in column name by doubling per SQL grammar
Databricks supports literal backticks in column names via the
BACKQUOTED_IDENTIFIER lexer rule ``(``|~`)*`` — a backtick inside a
quoted identifier is escaped by doubling it. Empirically verified
via raw SQL: `CREATE TABLE ... (`a``b` STRING)`, `INSERT INTO ...
VALUES (:`a``b`)` with dict key `a`b` (single) all work end-to-end.
Databricks docs example: `DESCRIBE SELECT 5 AS `a``b``.
The dialect had two bugs in this path:
1. DatabricksIdentifierPreparer inherited SQLAlchemy's default
escape_quote=`"` (double quote), not ``` ` ``` (backtick). So DDL
for a column named ``a`b`` rendered as ``a`b`` (3 backticks,
unparseable) instead of ``a``b`` (4 backticks). CREATE TABLE
failed with PARSE_SYNTAX_ERROR. Pre-existing bug — never worked
on main.
2. The bind template `:`%(name)s`` used straight string substitution
with no escape awareness. For a name containing a literal
backtick, the rendered marker had an unescaped inner backtick
and the parser failed to match.
Fix:
- Preparer passes escape_quote=``` ` ``` explicitly so SQLAlchemy
doubles backticks inside quoted identifiers. SQLAlchemy infers
escape_to_quote=```` `` ```` from escape_quote.
- Statement compiler overrides bindparam_string to double backticks
in the name before the template wraps it. escaped_from is NOT set
so the params dict key stays the single-backtick original — the
server collapses the doubled form back to a single backtick when
it parses the marker name. Skipped for post_compile and
pre-escaped paths, matching super's contract.
Adds unit test and extends the empirical audit with a round-trip
case (CREATE -> INSERT -> SELECT WHERE -> DROP) on a column named
`a`b`. Audit is now 41/41 end-to-end; unit tests 258.
Signed-off-by: Madhavendra Rathore <madhavendra.rathore@databricks.com>1 parent 9414d89 commit 2c1bc55
2 files changed
Lines changed: 44 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
15 | 20 | | |
16 | 21 | | |
17 | 22 | | |
| |||
127 | 132 | | |
128 | 133 | | |
129 | 134 | | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
130 | 152 | | |
131 | 153 | | |
132 | 154 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
211 | 211 | | |
212 | 212 | | |
213 | 213 | | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
214 | 235 | | |
215 | 236 | | |
216 | 237 | | |
| |||
0 commit comments