Skip to content

Commit fd278a0

Browse files
feat(duckdb): Added a helper method
1 parent f2f91a6 commit fd278a0

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

sqlglot/dialects/duckdb.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,35 +1209,35 @@ def objectinsert_sql(self, expression: exp.ObjectInsert) -> str:
12091209

12101210
return self.func("STRUCT_INSERT", this, kv_sql)
12111211

1212-
def startswith_sql(self, expression: exp.StartsWith) -> str:
1213-
this = expression.this
1214-
expr = expression.expression
1212+
def _prepare_startswith_arg(self, arg: exp.Expression) -> None:
1213+
"""Prepare argument for STARTS_WITH by converting to VARCHAR.
1214+
1215+
ByteString literals are converted to regular string literals to avoid
1216+
BLOB casting by the generator. Non-VARCHAR types are cast to VARCHAR.
1217+
"""
1218+
# Convert ByteString to String literal before generation
1219+
# ByteStrings get typed as UNKNOWN and would be wrapped in CAST(...AS BLOB) by generator
1220+
if isinstance(arg, exp.ByteString):
1221+
arg.replace(exp.Literal.string(arg.this))
1222+
# Cast non-VARCHAR types to VARCHAR
1223+
elif arg.type and not arg.is_type(exp.DataType.Type.VARCHAR, exp.DataType.Type.UNKNOWN):
1224+
arg.replace(exp.cast(arg, exp.DataType.Type.VARCHAR))
12151225

1216-
if not this.type:
1226+
def startswith_sql(self, expression: exp.StartsWith) -> str:
1227+
# Annotate types if needed for type-based casting
1228+
if not expression.this.type:
12171229
from sqlglot.optimizer.annotate_types import annotate_types
12181230

1219-
this = annotate_types(this, dialect=self.dialect)
1231+
annotate_types(expression.this, dialect=self.dialect)
12201232

1221-
if not expr.type:
1233+
if not expression.expression.type:
12221234
from sqlglot.optimizer.annotate_types import annotate_types
12231235

1224-
expr = annotate_types(expr, dialect=self.dialect)
1236+
annotate_types(expression.expression, dialect=self.dialect)
12251237

1226-
if isinstance(expression.this, exp.ByteString):
1227-
expression.this.replace(exp.Literal.string(expression.this.this))
1228-
elif this.type and not this.is_type(
1229-
exp.DataType.Type.VARCHAR, exp.DataType.Type.UNKNOWN
1230-
):
1231-
expression.this.replace(exp.cast(expression.this, exp.DataType.Type.VARCHAR))
1232-
1233-
if isinstance(expression.expression, exp.ByteString):
1234-
expression.expression.replace(exp.Literal.string(expression.expression.this))
1235-
elif expr.type and not expr.is_type(
1236-
exp.DataType.Type.VARCHAR, exp.DataType.Type.UNKNOWN
1237-
):
1238-
expression.expression.replace(
1239-
exp.cast(expression.expression, exp.DataType.Type.VARCHAR)
1240-
)
1238+
# Prepare both arguments for STARTS_WITH
1239+
self._prepare_startswith_arg(expression.this)
1240+
self._prepare_startswith_arg(expression.expression)
12411241

12421242
return self.func("STARTS_WITH", expression.this, expression.expression)
12431243

0 commit comments

Comments
 (0)