The helper that quotes non-ASCII identifiers wraps the input in "…" but never escapes embedded " characters, so an identifier like my"col renders as "my"col" — which most SQL parsers will read as identifier my followed by col" and fail.
The function is duplicated in two codegen paths:
|
private def doubleQuoteIfNecessary(s: String): String = |
|
if identifierPattern.matches(s) then |
|
s |
|
else |
|
s""""${s}"""" |
private def doubleQuoteIfNecessary(s: String): String =
if identifierPattern.matches(s) then
s
else
s""""${s}""""
|
private def doubleQuoteIfNecessary(s: String): String = |
|
if s.matches("^[_a-zA-Z][_a-zA-Z0-9]*$") then |
|
s |
|
else |
|
s""""${s}"""" |
private def doubleQuoteIfNecessary(s: String): String =
if s.matches("^[_a-zA-Z][_a-zA-Z0-9]*$") then
s
else
s""""${s}""""
The single-quote case is already handled correctly elsewhere (SqlGenerator.scala line 1710 uses replaceAll("'", "''")); only the double-quote path was missed.
private def doubleQuoteIfNecessary(s: String): String =
if s.matches("^[_a-zA-Z][_a-zA-Z0-9]*$") then
s
else
s""""${s.replace("\"", "\"\"")}""""
Happy to PR if you'd like — though the duplication between SqlGenerator and GenSQL looks like it could collapse into a shared helper.
The helper that quotes non-ASCII identifiers wraps the input in
"…"but never escapes embedded"characters, so an identifier likemy"colrenders as"my"col"— which most SQL parsers will read as identifiermyfollowed bycol"and fail.The function is duplicated in two codegen paths:
wvlet/wvlet-lang/src/main/scala/wvlet/lang/compiler/codegen/SqlGenerator.scala
Lines 35 to 39 in 4222c2f
wvlet/wvlet-lang/src/main/scala/wvlet/lang/compiler/codegen/GenSQL.scala
Lines 42 to 46 in 4222c2f
The single-quote case is already handled correctly elsewhere (
SqlGenerator.scalaline 1710 usesreplaceAll("'", "''")); only the double-quote path was missed.Happy to PR if you'd like — though the duplication between
SqlGeneratorandGenSQLlooks like it could collapse into a shared helper.