@@ -1589,6 +1589,24 @@ class Generator(generator.Generator):
15891589 """
15901590 )
15911591
1592+ # Template for RANDSTR transpilation - placeholders get replaced with actual parameters
1593+ RANDSTR_TEMPLATE : exp .Expression = exp .maybe_parse (
1594+ f"""
1595+ SELECT LISTAGG(
1596+ SUBSTRING(
1597+ '{ RANDSTR_CHAR_POOL } ',
1598+ 1 + CAST(FLOOR(random_value * 62) AS INT),
1599+ 1
1600+ ),
1601+ ''
1602+ )
1603+ FROM (
1604+ SELECT (ABS(HASH(i + :seed)) % 1000) / 1000.0 AS random_value
1605+ FROM RANGE(:length) AS t(i)
1606+ )
1607+ """ ,
1608+ )
1609+
15921610 def bitmapbitposition_sql (self : DuckDB .Generator , expression : exp .BitmapBitPosition ) -> str :
15931611 """
15941612 Transpile Snowflake's BITMAP_BIT_POSITION to DuckDB CASE expression.
@@ -1615,6 +1633,7 @@ def bitmapbitposition_sql(self: DuckDB.Generator, expression: exp.BitmapBitPosit
16151633 def randstr_sql (self : DuckDB .Generator , expression : exp .Randstr ) -> str :
16161634 """
16171635 Transpile Snowflake's RANDSTR to DuckDB equivalent using deterministic hash-based random.
1636+ Uses a pre-parsed template with placeholders replaced by expression nodes.
16181637
16191638 RANDSTR(length, generator) generates a random string of specified length.
16201639 - With numeric seed: Use HASH(i + seed) for deterministic output (same seed = same result)
@@ -1635,27 +1654,8 @@ def randstr_sql(self: DuckDB.Generator, expression: exp.Randstr) -> str:
16351654 # No generator specified, use default seed (arbitrary but deterministic)
16361655 seed_value = exp .Literal .number (RANDSTR_SEED )
16371656
1638- length_sql = self .sql (length )
1639- seed_sql = self .sql (seed_value )
1640-
1641- query : exp .Select = exp .maybe_parse (
1642- f"""
1643- SELECT LISTAGG(
1644- SUBSTRING(
1645- '{ RANDSTR_CHAR_POOL } ',
1646- 1 + CAST(FLOOR(random_value * 62) AS INT),
1647- 1
1648- ),
1649- ''
1650- )
1651- FROM (
1652- SELECT (ABS(HASH(i + { seed_sql } )) % 1000) / 1000.0 AS random_value
1653- FROM RANGE({ length_sql } ) AS t(i)
1654- )
1655- """ ,
1656- dialect = "duckdb" ,
1657- )
1658- return f"({ self .sql (query )} )"
1657+ replacements = {"seed" : seed_value , "length" : length }
1658+ return f"({ self .sql (exp .replace_placeholders (self .RANDSTR_TEMPLATE , ** replacements ))} )"
16591659
16601660 def zipf_sql (self : DuckDB .Generator , expression : exp .Zipf ) -> str :
16611661 """
0 commit comments