Edit on GitHub

sqlglot.generators.exasol

  1from __future__ import annotations
  2
  3import typing as t
  4
  5from sqlglot import exp, generator
  6from sqlglot.dialects.dialect import (
  7    DATE_ADD_OR_SUB,
  8    Dialect,
  9    groupconcat_sql,
 10    mod_func_sql,
 11    no_last_day_sql,
 12    rename_func,
 13    strposition_sql,
 14    timestrtotime_sql,
 15    timestamptrunc_sql,
 16)
 17from sqlglot.errors import UnsupportedError
 18from sqlglot.generator import unsupported_args
 19from sqlglot.optimizer.scope import build_scope, find_in_scope
 20from sqlglot.parsers.exasol import DATE_UNITS
 21
 22
 23def _sha2_sql(self: ExasolGenerator, expression: exp.SHA2) -> str:
 24    length = expression.text("length")
 25    func_name = "HASH_SHA256" if length == "256" else "HASH_SHA512"
 26    return self.func(func_name, expression.this)
 27
 28
 29def _date_diff_sql(self: ExasolGenerator, expression: exp.DateDiff | exp.TsOrDsDiff) -> str:
 30    unit = expression.text("unit").upper() or "DAY"
 31
 32    if unit not in DATE_UNITS:
 33        self.unsupported(f"'{unit}' is not supported in Exasol.")
 34        return self.function_fallback_sql(expression)
 35
 36    return self.func(f"{unit}S_BETWEEN", expression.this, expression.expression)
 37
 38
 39# https://docs.exasol.com/db/latest/sql/select.htm#:~:text=If%20you%20have,local.x%3E10
 40def _add_local_prefix_for_aliases(expression: exp.Expr, dialect: Dialect) -> exp.Expr:
 41    def _key(ident: exp.Identifier) -> str:
 42        return dialect.normalize_identifier(ident.copy()).this
 43
 44    if isinstance(expression, exp.Select):
 45        aliases: dict[str, exp.Identifier] = {
 46            _key(alias): alias
 47            for sel in expression.selects
 48            if isinstance(sel, exp.Alias) and (alias := sel.args.get("alias"))
 49        }
 50
 51        table = expression.find(exp.Table)
 52        table_ident = table.this if table else None
 53
 54        if (
 55            table_ident
 56            and table_ident.name.upper() == "LOCAL"
 57            and not bool(table_ident.args.get("quoted"))
 58        ):
 59            table_ident.replace(exp.to_identifier(table_ident.name.upper(), quoted=True))
 60
 61        def prefix_local(node: exp.Expr, visible_aliases: dict[str, exp.Identifier]) -> exp.Expr:
 62            if isinstance(node, exp.Column) and not node.table:
 63                alias = visible_aliases.get(_key(node.this))
 64                if alias is not None:
 65                    return exp.Column(
 66                        this=alias,
 67                        table=exp.to_identifier("LOCAL", quoted=False),
 68                    )
 69            return node
 70
 71        for key in ("where", "group", "having"):
 72            if arg := expression.args.get(key):
 73                expression.set(key, arg.transform(lambda node: prefix_local(node, aliases)))
 74
 75        seen_aliases: dict[str, exp.Identifier] = {}
 76        new_selects: list[exp.Expr] = []
 77        for sel in expression.selects:
 78            if isinstance(sel, exp.Alias):
 79                inner = sel.this.transform(lambda node: prefix_local(node, seen_aliases))
 80                sel.set("this", inner)
 81
 82                if alias_node := sel.args.get("alias"):
 83                    seen_aliases[_key(alias_node)] = alias_node
 84                new_selects.append(sel)
 85            else:
 86                new_selects.append(sel.transform(lambda node: prefix_local(node, seen_aliases)))
 87        expression.set("expressions", new_selects)
 88
 89    return expression
 90
 91
 92def _trunc_sql(
 93    self: ExasolGenerator, kind: str, expression: exp.DateTrunc | exp.TimestampTrunc
 94) -> str:
 95    unit_expr = expression.args.get("unit")
 96    unit = (
 97        self.weekstart_name(unit_expr)
 98        if isinstance(unit_expr, exp.WeekStart)
 99        else expression.text("unit")
100    )
101    node = expression.this.this if isinstance(expression.this, exp.Cast) else expression.this
102    expr_sql = self.sql(node)
103    if isinstance(node, exp.Literal) and node.is_string:
104        text = node.this.replace("T", " ") if kind == "TIMESTAMP" else node.this
105        expr_sql = f"{kind} {self.sql(exp.Literal.string(text))}"
106    return f"DATE_TRUNC({self.sql(exp.Literal.string(unit))}, {expr_sql})"
107
108
109def _date_trunc_sql(self: ExasolGenerator, expression: exp.DateTrunc) -> str:
110    return _trunc_sql(self, "DATE", expression)
111
112
113def _timestamp_trunc_sql(
114    self: ExasolGenerator, expression: exp.DateTrunc | exp.TimestampTrunc
115) -> str:
116    return _trunc_sql(self, "TIMESTAMP", expression)
117
118
119def is_case_insensitive(node: exp.Expr) -> bool:
120    return isinstance(node, exp.Collate) and node.text("expression").upper() == "UTF8_LCASE"
121
122
123def _substring_index_sql(self: ExasolGenerator, expression: exp.SubstringIndex) -> str:
124    this = expression.this
125    delimiter = expression.args["delimiter"]
126    count_node = expression.args["count"]
127    count_sql = self.sql(expression, "count")
128    num = count_node.to_py() if count_node.is_number else 0
129
130    haystack_sql = self.sql(this)
131    if num == 0:
132        return self.func("SUBSTR", haystack_sql, "1", "0")
133
134    from_right = num < 0
135    direction = "-1" if from_right else "1"
136    occur = self.func("ABS", count_sql) if from_right else count_sql
137
138    delimiter_sql = self.sql(delimiter)
139
140    position = self.func(
141        "INSTR",
142        self.func("LOWER", haystack_sql) if is_case_insensitive(this) else haystack_sql,
143        self.func("LOWER", delimiter_sql) if is_case_insensitive(delimiter) else delimiter_sql,
144        direction,
145        occur,
146    )
147    nullable_pos = self.func("NULLIF", position, "0")
148
149    if from_right:
150        start = self.func(
151            "NVL", f"{nullable_pos} + {self.func('LENGTH', delimiter_sql)}", direction
152        )
153        return self.func("SUBSTR", haystack_sql, start)
154
155    length = self.func("NVL", f"{nullable_pos} - 1", self.func("LENGTH", haystack_sql))
156    return self.func("SUBSTR", haystack_sql, direction, length)
157
158
159# https://docs.exasol.com/db/latest/sql/select.htm#:~:text=The%20select_list%20defines%20the%20columns%20of%20the%20result%20table.%20If%20*%20is%20used%2C%20all%20columns%20are%20listed.%20You%20can%20use%20an%20expression%20like%20t.*%20to%20list%20all%20columns%20of%20the%20table%20t%2C%20the%20view%20t%2C%20or%20the%20object%20with%20the%20table%20alias%20t.
160def _qualify_unscoped_star(expression: exp.Expr) -> exp.Expr:
161    """
162    Exasol doesn't support a bare * alongside other select items, so we rewrite it
163    Rewrite: SELECT *, <other> FROM <Table>
164    Into: SELECT T.*, <other> FROM <Table> AS T
165    """
166
167    if not isinstance(expression, exp.Select):
168        return expression
169
170    select_expressions = expression.expressions or []
171
172    def is_bare_star(expr: exp.Expr) -> bool:
173        return isinstance(expr, exp.Star) and expr.this is None
174
175    has_other_expression = False
176    bare_star_expr: exp.Expr | None = None
177    for expr in select_expressions:
178        has_bare_star = is_bare_star(expr)
179        if has_bare_star and bare_star_expr is None:
180            bare_star_expr = expr
181        elif not has_bare_star:
182            has_other_expression = True
183        if bare_star_expr and has_other_expression:
184            break
185
186    if not (bare_star_expr and has_other_expression):
187        return expression
188
189    scope = build_scope(expression)
190
191    if not scope or not scope.selected_sources:
192        return expression
193
194    table_identifiers: list[exp.Identifier] = []
195
196    for source_name, (source_expr, _) in scope.selected_sources.items():
197        ident = (
198            source_expr.this.copy()
199            if isinstance(source_expr, exp.Table) and isinstance(source_expr.this, exp.Identifier)
200            else exp.to_identifier(source_name)
201        )
202        table_identifiers.append(ident)
203
204    qualified_star_columns = [
205        exp.Column(this=bare_star_expr.copy(), table=ident) for ident in table_identifiers
206    ]
207
208    new_select_expressions: list[exp.Expr] = []
209
210    for select_expr in select_expressions:
211        new_select_expressions.extend(qualified_star_columns) if is_bare_star(
212            select_expr
213        ) else new_select_expressions.append(select_expr)
214
215    expression.set("expressions", new_select_expressions)
216    return expression
217
218
219def _add_date_sql(self: ExasolGenerator, expression: DATE_ADD_OR_SUB) -> str:
220    interval = expression.expression if isinstance(expression.expression, exp.Interval) else None
221
222    unit = (
223        (interval.text("unit") or "DAY").upper()
224        if interval is not None
225        else (expression.text("unit") or "DAY").upper()
226    )
227
228    if unit not in DATE_UNITS:
229        self.unsupported(f"'{unit}' is not supported in Exasol.")
230        return self.function_fallback_sql(expression)
231
232    offset_expr: exp.Expr = expression.expression
233    if interval is not None:
234        offset_expr = interval.this
235
236    if isinstance(expression, exp.DateSub):
237        offset_expr = exp.Neg(this=offset_expr)
238
239    return self.func(f"ADD_{unit}S", expression.this, offset_expr)
240
241
242def _group_by_all(expression: exp.Expr) -> exp.Expr:
243    if not isinstance(expression, exp.Select):
244        return expression
245
246    group = expression.args.get("group")
247    if not group or not group.args.get("all"):
248        return expression
249
250    if expression.is_star:
251        if any(find_in_scope(proj, exp.AggFunc) for proj in expression.expressions):
252            raise UnsupportedError(
253                "GROUP BY ALL with star projection and aggregates is not supported by Exasol"
254            )
255        expression.set("distinct", exp.Distinct())
256        expression.set("group", None)
257        return expression
258
259    group_positions = [
260        exp.Literal.number(i)
261        for i, proj in enumerate(expression.expressions, start=1)
262        if not find_in_scope(proj, exp.AggFunc)
263    ]
264
265    if not group_positions:
266        expression.set("group", None)
267        return expression
268
269    group.set("expressions", group_positions)
270    group.set("all", None)
271
272    return expression
273
274
275class ExasolGenerator(generator.Generator):
276    SELECT_KINDS: tuple[str, ...] = ()
277    TRY_SUPPORTED = False
278    SUPPORTS_UESCAPE = False
279    SUPPORTS_DECODE_CASE = False
280
281    AFTER_HAVING_MODIFIER_TRANSFORMS = generator.AFTER_HAVING_MODIFIER_TRANSFORMS
282
283    # https://docs.exasol.com/db/latest/sql_references/data_types/datatypedetails.htm#StringDataType
284    STRING_TYPE_MAPPING: t.ClassVar = {
285        exp.DType.BLOB: "VARCHAR",
286        exp.DType.LONGBLOB: "VARCHAR",
287        exp.DType.LONGTEXT: "VARCHAR",
288        exp.DType.MEDIUMBLOB: "VARCHAR",
289        exp.DType.MEDIUMTEXT: "VARCHAR",
290        exp.DType.TINYBLOB: "VARCHAR",
291        exp.DType.TINYTEXT: "VARCHAR",
292        # https://docs.exasol.com/db/latest/sql_references/data_types/datatypealiases.htm
293        exp.DType.TEXT: "LONG VARCHAR",
294        exp.DType.VARBINARY: "VARCHAR",
295    }
296
297    # https://docs.exasol.com/db/latest/sql_references/data_types/datatypealiases.htm
298    TYPE_MAPPING = {
299        **generator.Generator.TYPE_MAPPING,
300        **STRING_TYPE_MAPPING,
301        exp.DType.TINYINT: "SMALLINT",
302        exp.DType.MEDIUMINT: "INT",
303        exp.DType.DECIMAL32: "DECIMAL",
304        exp.DType.DECIMAL64: "DECIMAL",
305        exp.DType.DECIMAL128: "DECIMAL",
306        exp.DType.DECIMAL256: "DECIMAL",
307        exp.DType.DATETIME: "TIMESTAMP",
308        exp.DType.TIMESTAMPTZ: "TIMESTAMP",
309        exp.DType.TIMESTAMPLTZ: "TIMESTAMP",
310        exp.DType.TIMESTAMPNTZ: "TIMESTAMP",
311    }
312
313    def select_sql(self, expression: exp.Select) -> str:
314        processed = _qualify_unscoped_star(expression)
315        processed = _add_local_prefix_for_aliases(processed, self.dialect)
316        processed = _group_by_all(processed)
317        return super().select_sql(t.cast(exp.Select, processed))
318
319    def datatype_sql(self, expression: exp.DataType) -> str:
320        # Exasol supports a fixed default precision of 3 for TIMESTAMP WITH LOCAL TIME ZONE
321        # and does not allow specifying a different custom precision
322        if expression.is_type(exp.DType.TIMESTAMPLTZ):
323            return "TIMESTAMP WITH LOCAL TIME ZONE"
324
325        return super().datatype_sql(expression)
326
327    TRANSFORMS = {
328        **generator.Generator.TRANSFORMS,
329        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/every.htm
330        exp.All: rename_func("EVERY"),
331        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_and.htm
332        exp.BitwiseAnd: rename_func("BIT_AND"),
333        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_or.htm
334        exp.BitwiseOr: rename_func("BIT_OR"),
335        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_not.htm
336        exp.BitwiseNot: rename_func("BIT_NOT"),
337        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_lshift.htm
338        exp.BitwiseLeftShift: rename_func("BIT_LSHIFT"),
339        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_rshift.htm
340        exp.BitwiseRightShift: rename_func("BIT_RSHIFT"),
341        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_xor.htm
342        exp.BitwiseXor: rename_func("BIT_XOR"),
343        exp.CurrentSchema: lambda *_: "CURRENT_SCHEMA",
344        exp.DateDiff: _date_diff_sql,
345        exp.DateAdd: _add_date_sql,
346        exp.TsOrDsAdd: _add_date_sql,
347        exp.DateSub: _add_date_sql,
348        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/div.htm#DIV
349        exp.IntDiv: rename_func("DIV"),
350        exp.TsOrDsDiff: _date_diff_sql,
351        exp.DateTrunc: _date_trunc_sql,
352        exp.DayOfWeek: lambda self, e: f"CAST(TO_CHAR({self.sql(e, 'this')}, 'D') AS INTEGER)",
353        exp.DatetimeTrunc: timestamptrunc_sql(),
354        exp.GroupConcat: lambda self, e: groupconcat_sql(self, e, on_overflow=True),
355        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/edit_distance.htm#EDIT_DISTANCE
356        exp.Levenshtein: unsupported_args("ins_cost", "del_cost", "sub_cost", "max_dist")(
357            rename_func("EDIT_DISTANCE")
358        ),
359        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/mod.htm
360        exp.Mod: mod_func_sql,
361        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/from_posix_time.htm
362        exp.UnixToTime: lambda self, e: self.func("FROM_POSIX_TIME", e.this),
363        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/rank.htm
364        exp.Rank: unsupported_args("expressions")(lambda *_: "RANK()"),
365        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/dense_rank.htm
366        exp.DenseRank: unsupported_args("expressions")(lambda *_: "DENSE_RANK()"),
367        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/regexp_substr.htm
368        exp.RegexpExtract: unsupported_args("parameters", "group")(rename_func("REGEXP_SUBSTR")),
369        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/regexp_replace.htm
370        exp.RegexpReplace: unsupported_args("modifiers")(rename_func("REGEXP_REPLACE")),
371        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/var_pop.htm
372        exp.VariancePop: rename_func("VAR_POP"),
373        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/approximate_count_distinct.htm
374        exp.ApproxDistinct: unsupported_args("accuracy")(rename_func("APPROXIMATE_COUNT_DISTINCT")),
375        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_char%20(datetime).htm
376        exp.TimeToStr: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)),
377        exp.ToChar: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)),
378        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_date.htm
379        exp.TsOrDsToDate: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)),
380        exp.TimeStrToTime: timestrtotime_sql,
381        exp.TimestampTrunc: _timestamp_trunc_sql,
382        exp.StrToTime: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)),
383        exp.CurrentUser: lambda *_: "CURRENT_USER",
384        exp.AtTimeZone: lambda self, e: self.func(
385            "CONVERT_TZ",
386            e.this,
387            "'UTC'",
388            e.args.get("zone"),
389        ),
390        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/instr.htm
391        exp.StrPosition: lambda self, e: strposition_sql(
392            self, e, func_name="INSTR", supports_position=True, supports_occurrence=True
393        ),
394        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha%5B1%5D.htm#HASH_SHA%5B1%5D
395        exp.SHA: rename_func("HASH_SHA"),
396        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha256.htm
397        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha512.htm
398        exp.SHA2: _sha2_sql,
399        exp.MD5: rename_func("HASH_MD5"),
400        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hashtype_md5.htm
401        exp.MD5Digest: rename_func("HASHTYPE_MD5"),
402        # https://docs.exasol.com/db/latest/sql/create_view.htm
403        exp.CommentColumnConstraint: lambda self, e: f"COMMENT IS {self.sql(e, 'this')}",
404        exp.SubstringIndex: _substring_index_sql,
405        exp.WeekOfYear: rename_func("WEEK"),
406        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_date.htm
407        exp.Date: rename_func("TO_DATE"),
408        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_timestamp.htm
409        exp.Timestamp: rename_func("TO_TIMESTAMP"),
410        exp.Quarter: lambda self, e: f"CEIL(MONTH(TO_DATE({self.sql(e, 'this')}))/3)",
411        exp.LastDay: no_last_day_sql,
412    }
413
414    # https://docs.exasol.com/db/7.1/sql_references/system_tables/metadata/exa_sql_keywords.htm
415    RESERVED_KEYWORDS = {
416        "absolute",
417        "action",
418        "add",
419        "after",
420        "all",
421        "allocate",
422        "alter",
423        "and",
424        "any",
425        "append",
426        "are",
427        "array",
428        "as",
429        "asc",
430        "asensitive",
431        "assertion",
432        "at",
433        "attribute",
434        "authid",
435        "authorization",
436        "before",
437        "begin",
438        "between",
439        "bigint",
440        "binary",
441        "bit",
442        "blob",
443        "blocked",
444        "bool",
445        "boolean",
446        "both",
447        "by",
448        "byte",
449        "call",
450        "called",
451        "cardinality",
452        "cascade",
453        "cascaded",
454        "case",
455        "casespecific",
456        "cast",
457        "catalog",
458        "chain",
459        "char",
460        "character",
461        "character_set_catalog",
462        "character_set_name",
463        "character_set_schema",
464        "characteristics",
465        "check",
466        "checked",
467        "clob",
468        "close",
469        "coalesce",
470        "collate",
471        "collation",
472        "collation_catalog",
473        "collation_name",
474        "collation_schema",
475        "column",
476        "commit",
477        "condition",
478        "connect_by_iscycle",
479        "connect_by_isleaf",
480        "connect_by_root",
481        "connection",
482        "constant",
483        "constraint",
484        "constraint_state_default",
485        "constraints",
486        "constructor",
487        "contains",
488        "continue",
489        "control",
490        "convert",
491        "corresponding",
492        "create",
493        "cs",
494        "csv",
495        "cube",
496        "current",
497        "current_cluster",
498        "current_cluster_uid",
499        "current_date",
500        "current_path",
501        "current_role",
502        "current_schema",
503        "current_session",
504        "current_statement",
505        "current_time",
506        "current_timestamp",
507        "current_user",
508        "cursor",
509        "cycle",
510        "data",
511        "datalink",
512        "datetime_interval_code",
513        "datetime_interval_precision",
514        "day",
515        "dbtimezone",
516        "deallocate",
517        "dec",
518        "decimal",
519        "declare",
520        "default",
521        "default_like_escape_character",
522        "deferrable",
523        "deferred",
524        "defined",
525        "definer",
526        "delete",
527        "deref",
528        "derived",
529        "desc",
530        "describe",
531        "descriptor",
532        "deterministic",
533        "disable",
534        "disabled",
535        "disconnect",
536        "dispatch",
537        "distinct",
538        "dlurlcomplete",
539        "dlurlpath",
540        "dlurlpathonly",
541        "dlurlscheme",
542        "dlurlserver",
543        "dlvalue",
544        "do",
545        "domain",
546        "double",
547        "drop",
548        "dynamic",
549        "dynamic_function",
550        "dynamic_function_code",
551        "each",
552        "else",
553        "elseif",
554        "elsif",
555        "emits",
556        "enable",
557        "enabled",
558        "end",
559        "end-exec",
560        "endif",
561        "enforce",
562        "equals",
563        "errors",
564        "escape",
565        "except",
566        "exception",
567        "exec",
568        "execute",
569        "exists",
570        "exit",
571        "export",
572        "external",
573        "extract",
574        "false",
575        "fbv",
576        "fetch",
577        "file",
578        "final",
579        "first",
580        "float",
581        "following",
582        "for",
583        "forall",
584        "force",
585        "format",
586        "found",
587        "free",
588        "from",
589        "fs",
590        "full",
591        "function",
592        "general",
593        "generated",
594        "geometry",
595        "get",
596        "global",
597        "go",
598        "goto",
599        "grant",
600        "granted",
601        "group",
602        "group_concat",
603        "grouping",
604        "groups",
605        "hashtype",
606        "hashtype_format",
607        "having",
608        "high",
609        "hold",
610        "hour",
611        "identity",
612        "if",
613        "ifnull",
614        "immediate",
615        "impersonate",
616        "implementation",
617        "import",
618        "in",
619        "index",
620        "indicator",
621        "inner",
622        "inout",
623        "input",
624        "insensitive",
625        "insert",
626        "instance",
627        "instantiable",
628        "int",
629        "integer",
630        "integrity",
631        "intersect",
632        "interval",
633        "into",
634        "inverse",
635        "invoker",
636        "is",
637        "iterate",
638        "join",
639        "key_member",
640        "key_type",
641        "large",
642        "last",
643        "lateral",
644        "ldap",
645        "leading",
646        "leave",
647        "left",
648        "level",
649        "like",
650        "limit",
651        "listagg",
652        "localtime",
653        "localtimestamp",
654        "locator",
655        "log",
656        "longvarchar",
657        "loop",
658        "low",
659        "map",
660        "match",
661        "matched",
662        "merge",
663        "method",
664        "minus",
665        "minute",
666        "mod",
667        "modifies",
668        "modify",
669        "module",
670        "month",
671        "names",
672        "national",
673        "natural",
674        "nchar",
675        "nclob",
676        "new",
677        "next",
678        "nls_date_format",
679        "nls_date_language",
680        "nls_first_day_of_week",
681        "nls_numeric_characters",
682        "nls_timestamp_format",
683        "no",
684        "nocycle",
685        "nologging",
686        "none",
687        "not",
688        "null",
689        "nullif",
690        "number",
691        "numeric",
692        "nvarchar",
693        "nvarchar2",
694        "object",
695        "of",
696        "off",
697        "old",
698        "on",
699        "only",
700        "open",
701        "option",
702        "options",
703        "or",
704        "order",
705        "ordering",
706        "ordinality",
707        "others",
708        "out",
709        "outer",
710        "output",
711        "over",
712        "overlaps",
713        "overlay",
714        "overriding",
715        "pad",
716        "parallel_enable",
717        "parameter",
718        "parameter_specific_catalog",
719        "parameter_specific_name",
720        "parameter_specific_schema",
721        "parquet",
722        "partial",
723        "path",
724        "permission",
725        "placing",
726        "plus",
727        "preceding",
728        "preferring",
729        "prepare",
730        "preserve",
731        "prior",
732        "privileges",
733        "procedure",
734        "profile",
735        "qualify",
736        "random",
737        "range",
738        "read",
739        "reads",
740        "real",
741        "recovery",
742        "recursive",
743        "ref",
744        "references",
745        "referencing",
746        "refresh",
747        "regexp_like",
748        "relative",
749        "release",
750        "rename",
751        "repeat",
752        "replace",
753        "restore",
754        "restrict",
755        "result",
756        "return",
757        "returned_length",
758        "returned_octet_length",
759        "returns",
760        "revoke",
761        "right",
762        "rollback",
763        "rollup",
764        "routine",
765        "row",
766        "rows",
767        "rowtype",
768        "savepoint",
769        "schema",
770        "scope",
771        "scope_user",
772        "script",
773        "scroll",
774        "search",
775        "second",
776        "section",
777        "security",
778        "select",
779        "selective",
780        "self",
781        "sensitive",
782        "separator",
783        "sequence",
784        "session",
785        "session_user",
786        "sessiontimezone",
787        "set",
788        "sets",
789        "shortint",
790        "similar",
791        "smallint",
792        "some",
793        "source",
794        "space",
795        "specific",
796        "specifictype",
797        "sql",
798        "sql_bigint",
799        "sql_bit",
800        "sql_char",
801        "sql_date",
802        "sql_decimal",
803        "sql_double",
804        "sql_float",
805        "sql_integer",
806        "sql_longvarchar",
807        "sql_numeric",
808        "sql_preprocessor_script",
809        "sql_real",
810        "sql_smallint",
811        "sql_timestamp",
812        "sql_tinyint",
813        "sql_type_date",
814        "sql_type_timestamp",
815        "sql_varchar",
816        "sqlexception",
817        "sqlstate",
818        "sqlwarning",
819        "start",
820        "state",
821        "statement",
822        "static",
823        "structure",
824        "style",
825        "substring",
826        "subtype",
827        "sysdate",
828        "system",
829        "system_user",
830        "systimestamp",
831        "table",
832        "temporary",
833        "text",
834        "then",
835        "time",
836        "timestamp",
837        "timezone_hour",
838        "timezone_minute",
839        "tinyint",
840        "to",
841        "trailing",
842        "transaction",
843        "transform",
844        "transforms",
845        "translation",
846        "treat",
847        "trigger",
848        "trim",
849        "true",
850        "truncate",
851        "under",
852        "union",
853        "unique",
854        "unknown",
855        "unlink",
856        "unnest",
857        "until",
858        "update",
859        "usage",
860        "user",
861        "using",
862        "value",
863        "values",
864        "varchar",
865        "varchar2",
866        "varray",
867        "verify",
868        "view",
869        "when",
870        "whenever",
871        "where",
872        "while",
873        "window",
874        "with",
875        "within",
876        "without",
877        "work",
878        "year",
879        "yes",
880        "zone",
881    }
882
883    def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
884        from_tz = expression.args.get("source_tz")
885        to_tz = expression.args.get("target_tz")
886        datetime = expression.args.get("timestamp")
887        options = expression.args.get("options")
888
889        return self.func("CONVERT_TZ", datetime, from_tz, to_tz, options)
890
891    def if_sql(self, expression: exp.If) -> str:
892        this = self.sql(expression, "this")
893        true = self.sql(expression, "true")
894        false = self.sql(expression, "false")
895        return f"IF {this} THEN {true} ELSE {false} ENDIF"
896
897    # https://docs.exasol.com/db/latest/sql/open_schema.htm
898    def use_sql(self, expression: exp.Use) -> str:
899        kind = expression.args.get("kind")
900        if kind and self.sql(kind).upper() != "SCHEMA":
901            self.unsupported(f"'USE {self.sql(kind)}' is not supported in Exasol")
902            return super().use_sql(expression)
903        this = self.sql(expression, "this")
904        return f"OPEN SCHEMA {this}"
905
906    # https://docs.exasol.com/db/latest/sql_references/metadata/metadata_system_tables.htm
907    def show_sql(self, expression: exp.Show) -> str:
908        if expression.name == "TABLES":
909            db_name = expression.text("db")
910            schema_filter: exp.Expression = (
911                exp.Literal.string(db_name.upper()) if db_name else exp.CurrentSchema()
912            )
913            select = (
914                exp.select(exp.column("TABLE_NAME"))
915                .from_(exp.table_("EXA_ALL_TABLES", db="SYS"))
916                .where(exp.column("TABLE_SCHEMA").eq(schema_filter))
917            )
918            return self.sql(select)
919
920        if expression.name == "DATABASES":
921            select = exp.select(exp.column("SCHEMA_NAME")).from_(
922                exp.table_("EXA_SCHEMAS", db="SYS")
923            )
924            return self.sql(select)
925
926        return super().show_sql(expression)
927
928    def collate_sql(self, expression: exp.Collate) -> str:
929        return self.sql(expression.this)
930
931    def jsonextract_sql(self, expression: exp.JSONExtract) -> str:
932        sql = self.func(
933            "JSON_EXTRACT", expression.this, expression.expression, *expression.expressions
934        )
935
936        emits = self.sql(expression, "emits")
937        if emits:
938            sql = f"{sql} EMITS {emits}"
939
940        return sql
941
942    @unsupported_args("flag")
943    def regexplike_sql(self, expression: exp.RegexpLike) -> str:
944        if not expression.args.get("full_match"):
945            pattern = expression.expression
946            if pattern.is_string:
947                expression.set("expression", exp.Literal.string(f".*{pattern.name}.*"))
948            else:
949                expression.set(
950                    "expression",
951                    exp.Paren(
952                        this=exp.Concat(
953                            expressions=[
954                                exp.Literal.string(".*"),
955                                pattern,
956                                exp.Literal.string(".*"),
957                            ]
958                        )
959                    ),
960                )
961        return self.binary(expression, "REGEXP_LIKE")
def is_case_insensitive(node: sqlglot.expressions.core.Expr) -> bool:
120def is_case_insensitive(node: exp.Expr) -> bool:
121    return isinstance(node, exp.Collate) and node.text("expression").upper() == "UTF8_LCASE"
class ExasolGenerator(sqlglot.generator.Generator):
276class ExasolGenerator(generator.Generator):
277    SELECT_KINDS: tuple[str, ...] = ()
278    TRY_SUPPORTED = False
279    SUPPORTS_UESCAPE = False
280    SUPPORTS_DECODE_CASE = False
281
282    AFTER_HAVING_MODIFIER_TRANSFORMS = generator.AFTER_HAVING_MODIFIER_TRANSFORMS
283
284    # https://docs.exasol.com/db/latest/sql_references/data_types/datatypedetails.htm#StringDataType
285    STRING_TYPE_MAPPING: t.ClassVar = {
286        exp.DType.BLOB: "VARCHAR",
287        exp.DType.LONGBLOB: "VARCHAR",
288        exp.DType.LONGTEXT: "VARCHAR",
289        exp.DType.MEDIUMBLOB: "VARCHAR",
290        exp.DType.MEDIUMTEXT: "VARCHAR",
291        exp.DType.TINYBLOB: "VARCHAR",
292        exp.DType.TINYTEXT: "VARCHAR",
293        # https://docs.exasol.com/db/latest/sql_references/data_types/datatypealiases.htm
294        exp.DType.TEXT: "LONG VARCHAR",
295        exp.DType.VARBINARY: "VARCHAR",
296    }
297
298    # https://docs.exasol.com/db/latest/sql_references/data_types/datatypealiases.htm
299    TYPE_MAPPING = {
300        **generator.Generator.TYPE_MAPPING,
301        **STRING_TYPE_MAPPING,
302        exp.DType.TINYINT: "SMALLINT",
303        exp.DType.MEDIUMINT: "INT",
304        exp.DType.DECIMAL32: "DECIMAL",
305        exp.DType.DECIMAL64: "DECIMAL",
306        exp.DType.DECIMAL128: "DECIMAL",
307        exp.DType.DECIMAL256: "DECIMAL",
308        exp.DType.DATETIME: "TIMESTAMP",
309        exp.DType.TIMESTAMPTZ: "TIMESTAMP",
310        exp.DType.TIMESTAMPLTZ: "TIMESTAMP",
311        exp.DType.TIMESTAMPNTZ: "TIMESTAMP",
312    }
313
314    def select_sql(self, expression: exp.Select) -> str:
315        processed = _qualify_unscoped_star(expression)
316        processed = _add_local_prefix_for_aliases(processed, self.dialect)
317        processed = _group_by_all(processed)
318        return super().select_sql(t.cast(exp.Select, processed))
319
320    def datatype_sql(self, expression: exp.DataType) -> str:
321        # Exasol supports a fixed default precision of 3 for TIMESTAMP WITH LOCAL TIME ZONE
322        # and does not allow specifying a different custom precision
323        if expression.is_type(exp.DType.TIMESTAMPLTZ):
324            return "TIMESTAMP WITH LOCAL TIME ZONE"
325
326        return super().datatype_sql(expression)
327
328    TRANSFORMS = {
329        **generator.Generator.TRANSFORMS,
330        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/every.htm
331        exp.All: rename_func("EVERY"),
332        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_and.htm
333        exp.BitwiseAnd: rename_func("BIT_AND"),
334        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_or.htm
335        exp.BitwiseOr: rename_func("BIT_OR"),
336        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_not.htm
337        exp.BitwiseNot: rename_func("BIT_NOT"),
338        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_lshift.htm
339        exp.BitwiseLeftShift: rename_func("BIT_LSHIFT"),
340        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_rshift.htm
341        exp.BitwiseRightShift: rename_func("BIT_RSHIFT"),
342        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_xor.htm
343        exp.BitwiseXor: rename_func("BIT_XOR"),
344        exp.CurrentSchema: lambda *_: "CURRENT_SCHEMA",
345        exp.DateDiff: _date_diff_sql,
346        exp.DateAdd: _add_date_sql,
347        exp.TsOrDsAdd: _add_date_sql,
348        exp.DateSub: _add_date_sql,
349        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/div.htm#DIV
350        exp.IntDiv: rename_func("DIV"),
351        exp.TsOrDsDiff: _date_diff_sql,
352        exp.DateTrunc: _date_trunc_sql,
353        exp.DayOfWeek: lambda self, e: f"CAST(TO_CHAR({self.sql(e, 'this')}, 'D') AS INTEGER)",
354        exp.DatetimeTrunc: timestamptrunc_sql(),
355        exp.GroupConcat: lambda self, e: groupconcat_sql(self, e, on_overflow=True),
356        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/edit_distance.htm#EDIT_DISTANCE
357        exp.Levenshtein: unsupported_args("ins_cost", "del_cost", "sub_cost", "max_dist")(
358            rename_func("EDIT_DISTANCE")
359        ),
360        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/mod.htm
361        exp.Mod: mod_func_sql,
362        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/from_posix_time.htm
363        exp.UnixToTime: lambda self, e: self.func("FROM_POSIX_TIME", e.this),
364        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/rank.htm
365        exp.Rank: unsupported_args("expressions")(lambda *_: "RANK()"),
366        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/dense_rank.htm
367        exp.DenseRank: unsupported_args("expressions")(lambda *_: "DENSE_RANK()"),
368        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/regexp_substr.htm
369        exp.RegexpExtract: unsupported_args("parameters", "group")(rename_func("REGEXP_SUBSTR")),
370        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/regexp_replace.htm
371        exp.RegexpReplace: unsupported_args("modifiers")(rename_func("REGEXP_REPLACE")),
372        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/var_pop.htm
373        exp.VariancePop: rename_func("VAR_POP"),
374        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/approximate_count_distinct.htm
375        exp.ApproxDistinct: unsupported_args("accuracy")(rename_func("APPROXIMATE_COUNT_DISTINCT")),
376        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_char%20(datetime).htm
377        exp.TimeToStr: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)),
378        exp.ToChar: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)),
379        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_date.htm
380        exp.TsOrDsToDate: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)),
381        exp.TimeStrToTime: timestrtotime_sql,
382        exp.TimestampTrunc: _timestamp_trunc_sql,
383        exp.StrToTime: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)),
384        exp.CurrentUser: lambda *_: "CURRENT_USER",
385        exp.AtTimeZone: lambda self, e: self.func(
386            "CONVERT_TZ",
387            e.this,
388            "'UTC'",
389            e.args.get("zone"),
390        ),
391        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/instr.htm
392        exp.StrPosition: lambda self, e: strposition_sql(
393            self, e, func_name="INSTR", supports_position=True, supports_occurrence=True
394        ),
395        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha%5B1%5D.htm#HASH_SHA%5B1%5D
396        exp.SHA: rename_func("HASH_SHA"),
397        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha256.htm
398        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha512.htm
399        exp.SHA2: _sha2_sql,
400        exp.MD5: rename_func("HASH_MD5"),
401        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hashtype_md5.htm
402        exp.MD5Digest: rename_func("HASHTYPE_MD5"),
403        # https://docs.exasol.com/db/latest/sql/create_view.htm
404        exp.CommentColumnConstraint: lambda self, e: f"COMMENT IS {self.sql(e, 'this')}",
405        exp.SubstringIndex: _substring_index_sql,
406        exp.WeekOfYear: rename_func("WEEK"),
407        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_date.htm
408        exp.Date: rename_func("TO_DATE"),
409        # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_timestamp.htm
410        exp.Timestamp: rename_func("TO_TIMESTAMP"),
411        exp.Quarter: lambda self, e: f"CEIL(MONTH(TO_DATE({self.sql(e, 'this')}))/3)",
412        exp.LastDay: no_last_day_sql,
413    }
414
415    # https://docs.exasol.com/db/7.1/sql_references/system_tables/metadata/exa_sql_keywords.htm
416    RESERVED_KEYWORDS = {
417        "absolute",
418        "action",
419        "add",
420        "after",
421        "all",
422        "allocate",
423        "alter",
424        "and",
425        "any",
426        "append",
427        "are",
428        "array",
429        "as",
430        "asc",
431        "asensitive",
432        "assertion",
433        "at",
434        "attribute",
435        "authid",
436        "authorization",
437        "before",
438        "begin",
439        "between",
440        "bigint",
441        "binary",
442        "bit",
443        "blob",
444        "blocked",
445        "bool",
446        "boolean",
447        "both",
448        "by",
449        "byte",
450        "call",
451        "called",
452        "cardinality",
453        "cascade",
454        "cascaded",
455        "case",
456        "casespecific",
457        "cast",
458        "catalog",
459        "chain",
460        "char",
461        "character",
462        "character_set_catalog",
463        "character_set_name",
464        "character_set_schema",
465        "characteristics",
466        "check",
467        "checked",
468        "clob",
469        "close",
470        "coalesce",
471        "collate",
472        "collation",
473        "collation_catalog",
474        "collation_name",
475        "collation_schema",
476        "column",
477        "commit",
478        "condition",
479        "connect_by_iscycle",
480        "connect_by_isleaf",
481        "connect_by_root",
482        "connection",
483        "constant",
484        "constraint",
485        "constraint_state_default",
486        "constraints",
487        "constructor",
488        "contains",
489        "continue",
490        "control",
491        "convert",
492        "corresponding",
493        "create",
494        "cs",
495        "csv",
496        "cube",
497        "current",
498        "current_cluster",
499        "current_cluster_uid",
500        "current_date",
501        "current_path",
502        "current_role",
503        "current_schema",
504        "current_session",
505        "current_statement",
506        "current_time",
507        "current_timestamp",
508        "current_user",
509        "cursor",
510        "cycle",
511        "data",
512        "datalink",
513        "datetime_interval_code",
514        "datetime_interval_precision",
515        "day",
516        "dbtimezone",
517        "deallocate",
518        "dec",
519        "decimal",
520        "declare",
521        "default",
522        "default_like_escape_character",
523        "deferrable",
524        "deferred",
525        "defined",
526        "definer",
527        "delete",
528        "deref",
529        "derived",
530        "desc",
531        "describe",
532        "descriptor",
533        "deterministic",
534        "disable",
535        "disabled",
536        "disconnect",
537        "dispatch",
538        "distinct",
539        "dlurlcomplete",
540        "dlurlpath",
541        "dlurlpathonly",
542        "dlurlscheme",
543        "dlurlserver",
544        "dlvalue",
545        "do",
546        "domain",
547        "double",
548        "drop",
549        "dynamic",
550        "dynamic_function",
551        "dynamic_function_code",
552        "each",
553        "else",
554        "elseif",
555        "elsif",
556        "emits",
557        "enable",
558        "enabled",
559        "end",
560        "end-exec",
561        "endif",
562        "enforce",
563        "equals",
564        "errors",
565        "escape",
566        "except",
567        "exception",
568        "exec",
569        "execute",
570        "exists",
571        "exit",
572        "export",
573        "external",
574        "extract",
575        "false",
576        "fbv",
577        "fetch",
578        "file",
579        "final",
580        "first",
581        "float",
582        "following",
583        "for",
584        "forall",
585        "force",
586        "format",
587        "found",
588        "free",
589        "from",
590        "fs",
591        "full",
592        "function",
593        "general",
594        "generated",
595        "geometry",
596        "get",
597        "global",
598        "go",
599        "goto",
600        "grant",
601        "granted",
602        "group",
603        "group_concat",
604        "grouping",
605        "groups",
606        "hashtype",
607        "hashtype_format",
608        "having",
609        "high",
610        "hold",
611        "hour",
612        "identity",
613        "if",
614        "ifnull",
615        "immediate",
616        "impersonate",
617        "implementation",
618        "import",
619        "in",
620        "index",
621        "indicator",
622        "inner",
623        "inout",
624        "input",
625        "insensitive",
626        "insert",
627        "instance",
628        "instantiable",
629        "int",
630        "integer",
631        "integrity",
632        "intersect",
633        "interval",
634        "into",
635        "inverse",
636        "invoker",
637        "is",
638        "iterate",
639        "join",
640        "key_member",
641        "key_type",
642        "large",
643        "last",
644        "lateral",
645        "ldap",
646        "leading",
647        "leave",
648        "left",
649        "level",
650        "like",
651        "limit",
652        "listagg",
653        "localtime",
654        "localtimestamp",
655        "locator",
656        "log",
657        "longvarchar",
658        "loop",
659        "low",
660        "map",
661        "match",
662        "matched",
663        "merge",
664        "method",
665        "minus",
666        "minute",
667        "mod",
668        "modifies",
669        "modify",
670        "module",
671        "month",
672        "names",
673        "national",
674        "natural",
675        "nchar",
676        "nclob",
677        "new",
678        "next",
679        "nls_date_format",
680        "nls_date_language",
681        "nls_first_day_of_week",
682        "nls_numeric_characters",
683        "nls_timestamp_format",
684        "no",
685        "nocycle",
686        "nologging",
687        "none",
688        "not",
689        "null",
690        "nullif",
691        "number",
692        "numeric",
693        "nvarchar",
694        "nvarchar2",
695        "object",
696        "of",
697        "off",
698        "old",
699        "on",
700        "only",
701        "open",
702        "option",
703        "options",
704        "or",
705        "order",
706        "ordering",
707        "ordinality",
708        "others",
709        "out",
710        "outer",
711        "output",
712        "over",
713        "overlaps",
714        "overlay",
715        "overriding",
716        "pad",
717        "parallel_enable",
718        "parameter",
719        "parameter_specific_catalog",
720        "parameter_specific_name",
721        "parameter_specific_schema",
722        "parquet",
723        "partial",
724        "path",
725        "permission",
726        "placing",
727        "plus",
728        "preceding",
729        "preferring",
730        "prepare",
731        "preserve",
732        "prior",
733        "privileges",
734        "procedure",
735        "profile",
736        "qualify",
737        "random",
738        "range",
739        "read",
740        "reads",
741        "real",
742        "recovery",
743        "recursive",
744        "ref",
745        "references",
746        "referencing",
747        "refresh",
748        "regexp_like",
749        "relative",
750        "release",
751        "rename",
752        "repeat",
753        "replace",
754        "restore",
755        "restrict",
756        "result",
757        "return",
758        "returned_length",
759        "returned_octet_length",
760        "returns",
761        "revoke",
762        "right",
763        "rollback",
764        "rollup",
765        "routine",
766        "row",
767        "rows",
768        "rowtype",
769        "savepoint",
770        "schema",
771        "scope",
772        "scope_user",
773        "script",
774        "scroll",
775        "search",
776        "second",
777        "section",
778        "security",
779        "select",
780        "selective",
781        "self",
782        "sensitive",
783        "separator",
784        "sequence",
785        "session",
786        "session_user",
787        "sessiontimezone",
788        "set",
789        "sets",
790        "shortint",
791        "similar",
792        "smallint",
793        "some",
794        "source",
795        "space",
796        "specific",
797        "specifictype",
798        "sql",
799        "sql_bigint",
800        "sql_bit",
801        "sql_char",
802        "sql_date",
803        "sql_decimal",
804        "sql_double",
805        "sql_float",
806        "sql_integer",
807        "sql_longvarchar",
808        "sql_numeric",
809        "sql_preprocessor_script",
810        "sql_real",
811        "sql_smallint",
812        "sql_timestamp",
813        "sql_tinyint",
814        "sql_type_date",
815        "sql_type_timestamp",
816        "sql_varchar",
817        "sqlexception",
818        "sqlstate",
819        "sqlwarning",
820        "start",
821        "state",
822        "statement",
823        "static",
824        "structure",
825        "style",
826        "substring",
827        "subtype",
828        "sysdate",
829        "system",
830        "system_user",
831        "systimestamp",
832        "table",
833        "temporary",
834        "text",
835        "then",
836        "time",
837        "timestamp",
838        "timezone_hour",
839        "timezone_minute",
840        "tinyint",
841        "to",
842        "trailing",
843        "transaction",
844        "transform",
845        "transforms",
846        "translation",
847        "treat",
848        "trigger",
849        "trim",
850        "true",
851        "truncate",
852        "under",
853        "union",
854        "unique",
855        "unknown",
856        "unlink",
857        "unnest",
858        "until",
859        "update",
860        "usage",
861        "user",
862        "using",
863        "value",
864        "values",
865        "varchar",
866        "varchar2",
867        "varray",
868        "verify",
869        "view",
870        "when",
871        "whenever",
872        "where",
873        "while",
874        "window",
875        "with",
876        "within",
877        "without",
878        "work",
879        "year",
880        "yes",
881        "zone",
882    }
883
884    def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
885        from_tz = expression.args.get("source_tz")
886        to_tz = expression.args.get("target_tz")
887        datetime = expression.args.get("timestamp")
888        options = expression.args.get("options")
889
890        return self.func("CONVERT_TZ", datetime, from_tz, to_tz, options)
891
892    def if_sql(self, expression: exp.If) -> str:
893        this = self.sql(expression, "this")
894        true = self.sql(expression, "true")
895        false = self.sql(expression, "false")
896        return f"IF {this} THEN {true} ELSE {false} ENDIF"
897
898    # https://docs.exasol.com/db/latest/sql/open_schema.htm
899    def use_sql(self, expression: exp.Use) -> str:
900        kind = expression.args.get("kind")
901        if kind and self.sql(kind).upper() != "SCHEMA":
902            self.unsupported(f"'USE {self.sql(kind)}' is not supported in Exasol")
903            return super().use_sql(expression)
904        this = self.sql(expression, "this")
905        return f"OPEN SCHEMA {this}"
906
907    # https://docs.exasol.com/db/latest/sql_references/metadata/metadata_system_tables.htm
908    def show_sql(self, expression: exp.Show) -> str:
909        if expression.name == "TABLES":
910            db_name = expression.text("db")
911            schema_filter: exp.Expression = (
912                exp.Literal.string(db_name.upper()) if db_name else exp.CurrentSchema()
913            )
914            select = (
915                exp.select(exp.column("TABLE_NAME"))
916                .from_(exp.table_("EXA_ALL_TABLES", db="SYS"))
917                .where(exp.column("TABLE_SCHEMA").eq(schema_filter))
918            )
919            return self.sql(select)
920
921        if expression.name == "DATABASES":
922            select = exp.select(exp.column("SCHEMA_NAME")).from_(
923                exp.table_("EXA_SCHEMAS", db="SYS")
924            )
925            return self.sql(select)
926
927        return super().show_sql(expression)
928
929    def collate_sql(self, expression: exp.Collate) -> str:
930        return self.sql(expression.this)
931
932    def jsonextract_sql(self, expression: exp.JSONExtract) -> str:
933        sql = self.func(
934            "JSON_EXTRACT", expression.this, expression.expression, *expression.expressions
935        )
936
937        emits = self.sql(expression, "emits")
938        if emits:
939            sql = f"{sql} EMITS {emits}"
940
941        return sql
942
943    @unsupported_args("flag")
944    def regexplike_sql(self, expression: exp.RegexpLike) -> str:
945        if not expression.args.get("full_match"):
946            pattern = expression.expression
947            if pattern.is_string:
948                expression.set("expression", exp.Literal.string(f".*{pattern.name}.*"))
949            else:
950                expression.set(
951                    "expression",
952                    exp.Paren(
953                        this=exp.Concat(
954                            expressions=[
955                                exp.Literal.string(".*"),
956                                pattern,
957                                exp.Literal.string(".*"),
958                            ]
959                        )
960                    ),
961                )
962        return self.binary(expression, "REGEXP_LIKE")

Generator converts a given syntax tree to the corresponding SQL string.

Arguments:
  • pretty: Whether to format the produced SQL string. Default: False.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote except for specials cases. 'safe': Only quote identifiers that are case insensitive.
  • normalize: Whether to normalize identifiers to lowercase. Default: False.
  • pad: The pad size in a formatted string. For example, this affects the indentation of a projection in a query, relative to its nesting level. Default: 2.
  • indent: The indentation size in a formatted string. For example, this affects the indentation of subqueries and filters under a WHERE clause. Default: 2.
  • normalize_functions: How to normalize function names. Possible values are: "upper" or True (default): Convert names to uppercase. "lower": Convert names to lowercase. False: Disables function name normalization.
  • unsupported_level: Determines the generator's behavior when it encounters unsupported expressions. Default ErrorLevel.WARN.
  • max_unsupported: Maximum number of unsupported messages to include in a raised UnsupportedError. This is only relevant if unsupported_level is ErrorLevel.RAISE. Default: 3
  • leading_comma: Whether the comma is leading or trailing in select expressions. This is only relevant when generating in pretty mode. Default: False
  • max_text_width: The max number of characters in a segment before creating new lines in pretty mode. The default is on the smaller end because the length only represents a segment and not the true line length. Default: 80
  • comments: Whether to preserve comments in the output SQL code. Default: True
SELECT_KINDS: tuple[str, ...] = ()
TRY_SUPPORTED = False
SUPPORTS_UESCAPE = False
SUPPORTS_DECODE_CASE = False
AFTER_HAVING_MODIFIER_TRANSFORMS = {'windows': <function <lambda>>, 'qualify': <function <lambda>>}
STRING_TYPE_MAPPING: ClassVar = {<DType.BLOB: 'BLOB'>: 'VARCHAR', <DType.LONGBLOB: 'LONGBLOB'>: 'VARCHAR', <DType.LONGTEXT: 'LONGTEXT'>: 'VARCHAR', <DType.MEDIUMBLOB: 'MEDIUMBLOB'>: 'VARCHAR', <DType.MEDIUMTEXT: 'MEDIUMTEXT'>: 'VARCHAR', <DType.TINYBLOB: 'TINYBLOB'>: 'VARCHAR', <DType.TINYTEXT: 'TINYTEXT'>: 'VARCHAR', <DType.TEXT: 'TEXT'>: 'LONG VARCHAR', <DType.VARBINARY: 'VARBINARY'>: 'VARCHAR'}
TYPE_MAPPING = {<DType.DATETIME2: 'DATETIME2'>: 'TIMESTAMP', <DType.NCHAR: 'NCHAR'>: 'CHAR', <DType.NVARCHAR: 'NVARCHAR'>: 'VARCHAR', <DType.MEDIUMTEXT: 'MEDIUMTEXT'>: 'VARCHAR', <DType.LONGTEXT: 'LONGTEXT'>: 'VARCHAR', <DType.TINYTEXT: 'TINYTEXT'>: 'VARCHAR', <DType.BLOB: 'BLOB'>: 'VARCHAR', <DType.MEDIUMBLOB: 'MEDIUMBLOB'>: 'VARCHAR', <DType.LONGBLOB: 'LONGBLOB'>: 'VARCHAR', <DType.TINYBLOB: 'TINYBLOB'>: 'VARCHAR', <DType.INET: 'INET'>: 'INET', <DType.ROWVERSION: 'ROWVERSION'>: 'VARBINARY', <DType.SMALLDATETIME: 'SMALLDATETIME'>: 'TIMESTAMP', <DType.TEXT: 'TEXT'>: 'LONG VARCHAR', <DType.VARBINARY: 'VARBINARY'>: 'VARCHAR', <DType.TINYINT: 'TINYINT'>: 'SMALLINT', <DType.MEDIUMINT: 'MEDIUMINT'>: 'INT', <DType.DECIMAL32: 'DECIMAL32'>: 'DECIMAL', <DType.DECIMAL64: 'DECIMAL64'>: 'DECIMAL', <DType.DECIMAL128: 'DECIMAL128'>: 'DECIMAL', <DType.DECIMAL256: 'DECIMAL256'>: 'DECIMAL', <DType.DATETIME: 'DATETIME'>: 'TIMESTAMP', <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP', <DType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>: 'TIMESTAMP'}
def select_sql(self, expression: sqlglot.expressions.query.Select) -> str:
314    def select_sql(self, expression: exp.Select) -> str:
315        processed = _qualify_unscoped_star(expression)
316        processed = _add_local_prefix_for_aliases(processed, self.dialect)
317        processed = _group_by_all(processed)
318        return super().select_sql(t.cast(exp.Select, processed))
def datatype_sql(self, expression: sqlglot.expressions.datatypes.DataType) -> str:
320    def datatype_sql(self, expression: exp.DataType) -> str:
321        # Exasol supports a fixed default precision of 3 for TIMESTAMP WITH LOCAL TIME ZONE
322        # and does not allow specifying a different custom precision
323        if expression.is_type(exp.DType.TIMESTAMPLTZ):
324            return "TIMESTAMP WITH LOCAL TIME ZONE"
325
326        return super().datatype_sql(expression)
TRANSFORMS = {<class 'sqlglot.expressions.query.JSONPathFilter'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathKey'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathRecursive'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathRoot'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathScript'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathSelector'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathSlice'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathSubscript'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathUnion'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathWildcard'>: <function <lambda>>, <class 'sqlglot.expressions.core.Adjacent'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.AllowedValuesProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.AnalyzeColumns'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.AnalyzeWith'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.array.ArrayContainedBy'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.array.ArrayContainsAll'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.array.ArrayOverlaps'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.AssumeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.AutoRefreshProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.BackupProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.BinaryColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.CaseSpecificColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CalledOnNullInputProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.math.Ceil'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.CharacterSetColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CharacterSetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.ClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.CollateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.CommentColumnConstraint'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.functions.ConnectByRoot'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.string.ConvertToCharset'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CopyGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CopyTagsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CredentialsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.functions.CurrentCatalog'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.functions.SessionUser'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.DateFormatColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.DefaultColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ApiProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ApplicationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CatalogProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ComputeProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.DatabaseProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.DynamicProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.EmptyProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.EncodeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.EndStatement'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.EnviromentProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.HandlerProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ParameterStyleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.EphemeralColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.ExcludeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Except'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ExternalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.math.Floor'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Get'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.GlobalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.HeapProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.HybridProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.IcebergProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.IgnoreGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.InheritsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.InlineLengthColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.InputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Intersect'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.datatypes.IntervalSpan'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.functions.Int64'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBContainsAnyTopKeys'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBContainsAllTopKeys'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBContainsTopKey'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBDeleteAtPath'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBPathExists'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONObject'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONObjectAgg'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.LanguageProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.LocationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.LogProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.MaskingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.MaterializedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.functions.NetFunc'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.NetworkProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.NonClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.NoPrimaryIndexProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.NotForReplicationColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.OnCommitProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.OnProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.OnUpdateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.Operator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.OutputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.ExtendsLeft'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.ExtendsRight'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.PathColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.PartitionedByBucket'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.PartitionByTruncate'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.PivotAny'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.array.PositionalColumn'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.ProjectionPolicyColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.InvisibleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.ZeroFillColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Put'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.RemoteWithConnectionModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ReturnsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.RowAccessProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.SafeFunc'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SampleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SecureProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SecurityIntegrationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SetConfigProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SettingsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SharingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SqlReadWriteProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SqlSecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.StabilityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Stream'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.StreamingTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.StrictProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ddl.SwapTable'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.TableColumn'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.Tags'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.TitleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.array.ToMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ToTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.TransformModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.TransientProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.VirtualProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ddl.TriggerExecute'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Union'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.UnloggedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.UsingTemplateProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.UsingData'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.temporal.UtcDate'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.temporal.UtcTime'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.temporal.UtcTimestamp'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Variadic'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.array.VarMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ViewAttributeProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.WithProcedureOptions'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.WithSchemaBindingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.WithOperator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.WithoutRowidProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ForceProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.All'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.core.BitwiseAnd'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.core.BitwiseOr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.core.BitwiseNot'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.core.BitwiseLeftShift'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.core.BitwiseRightShift'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.core.BitwiseXor'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.functions.CurrentSchema'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.DateDiff'>: <function _date_diff_sql>, <class 'sqlglot.expressions.temporal.DateAdd'>: <function _add_date_sql>, <class 'sqlglot.expressions.temporal.TsOrDsAdd'>: <function _add_date_sql>, <class 'sqlglot.expressions.temporal.DateSub'>: <function _add_date_sql>, <class 'sqlglot.expressions.core.IntDiv'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.TsOrDsDiff'>: <function _date_diff_sql>, <class 'sqlglot.expressions.temporal.DateTrunc'>: <function _date_trunc_sql>, <class 'sqlglot.expressions.temporal.DayOfWeek'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.DatetimeTrunc'>: <function timestamptrunc_sql.<locals>._timestamptrunc_sql>, <class 'sqlglot.expressions.aggregate.GroupConcat'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.string.Levenshtein'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.core.Mod'>: <function mod_func_sql>, <class 'sqlglot.expressions.temporal.UnixToTime'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.aggregate.Rank'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.aggregate.DenseRank'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.string.RegexpExtract'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.string.RegexpReplace'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.aggregate.VariancePop'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.core.ApproxDistinct'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.TimeToStr'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.string.ToChar'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.TsOrDsToDate'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.TimeStrToTime'>: <function timestrtotime_sql>, <class 'sqlglot.expressions.temporal.TimestampTrunc'>: <function _timestamp_trunc_sql>, <class 'sqlglot.expressions.temporal.StrToTime'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.functions.CurrentUser'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.core.AtTimeZone'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.string.StrPosition'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.string.SHA'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.string.SHA2'>: <function _sha2_sql>, <class 'sqlglot.expressions.string.MD5'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.string.MD5Digest'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.string.SubstringIndex'>: <function _substring_index_sql>, <class 'sqlglot.expressions.temporal.WeekOfYear'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.Date'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.Timestamp'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.Quarter'>: <function ExasolGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.LastDay'>: <function no_last_day_sql>}
RESERVED_KEYWORDS = {'close', 'hold', 'if', 'after', 'inner', 'limit', 'get', 'nullif', 'sql_timestamp', 'sql', 'domain', 'ldap', 'using', 'table', 'referencing', 'cube', 'authorization', 'nls_timestamp_format', 'low', 'bit', 'except', 'assertion', 'cardinality', 'natural', 'sql_numeric', 'cs', 'system_user', 'sql_bigint', 'grouping', 'nvarchar2', 'byte', 'dispatch', 'row', 'errors', 'integrity', 'view', 'parquet', 'sqlexception', 'authid', 'constraint', 'with', 'old', 'cast', 'statement', 'specifictype', 'current_cluster', 'prior', 'constant', 'or', 'before', 'random', 'contains', 'references', 'privileges', 'modifies', 'for', 'constructor', 'and', 'start', 'coalesce', 'search', 'subtype', 'sql_bit', 'false', 'locator', 'tinyint', 'dynamic', 'parameter', 'overlay', 'equals', 'new', 'pad', 'timestamp', 'enforce', 'read', 'rows', 'dlurlcomplete', 'invoker', 'sql_double', 'instance', 'savepoint', 'dlvalue', 'called', 'some', 'exists', 'end', 'full', 'outer', 'sensitive', 'mod', 'deallocate', 'having', 'deferred', 'number', 'constraints', 'definer', 'current_time', 'create', 'dbtimezone', 'next', 'fetch', 'chain', 'overlaps', 'placing', 'overriding', 'sql_type_date', 'varray', 'zone', 'first', 'geometry', 'any', 'right', 'dynamic_function', 'group', 'trim', 'recursive', 'desc', 'sqlwarning', 'call', 'blob', 'large', 'then', 'numeric', 'current_statement', 'unlink', 'hashtype_format', 'deref', 'groups', 'restore', 'source', 'parallel_enable', 'transform', 'high', 'defined', 'sql_tinyint', 'state', 'at', 'each', 'without', 'constraint_state_default', 'path', 'nclob', 'following', 'reads', 'sessiontimezone', 'convert', 'ref', 'treat', 'systimestamp', 'restrict', 'dlurlpathonly', 'csv', 'identity', 'module', 'impersonate', 'enabled', 'qualify', 'connect_by_isleaf', 'dlurlserver', 'sql_preprocessor_script', 'character_set_catalog', 'elseif', 'as', 'sql_smallint', 'until', 'fs', 'column', 'sets', 'collation_name', 'sql_decimal', 'bool', 'intersect', 'parameter_specific_schema', 'commit', 'force', 'join', 'asensitive', 'left', 'return', 'static', 'nologging', 'returned_length', 'clob', 'current', 'current_role', 'else', 'connect_by_iscycle', 'text', 'timezone_minute', 'descriptor', 'unknown', 'collation_schema', 'enable', 'in', 'cursor', 'national', 'nchar', 'nls_numeric_characters', 'partial', 'union', 'disconnect', 'like', 'distinct', 'shortint', 'out', 'drop', 'range', 'character_set_name', 'collation_catalog', 'current_user', 'extract', 'lateral', 'permission', 'preserve', 'nocycle', 'declare', 'update', 'plus', 'only', 'nls_first_day_of_week', 'substring', 'minus', 'binary', 'do', 'current_date', 'returns', 'object', 'cycle', 'case', 'go', 'security', 'whenever', 'generated', 'goto', 'int', 'preceding', 'similar', 'nls_date_language', 'immediate', 'transaction', 'trailing', 'user', 'absolute', 'current_timestamp', 'default', 'boolean', 'emits', 'exception', 'format', 'values', 'regexp_like', 'function', 'window', 'parameter_specific_name', 'integer', 'match', 'rollback', 'while', 'dlurlscheme', 'found', 'iterate', 'yes', 'rollup', 'level', 'procedure', 'sysdate', 'sql_integer', 'separator', 'char', 'rename', 'over', 'select', 'datetime_interval_precision', 'attribute', 'sequence', 'refresh', 'implementation', 'inverse', 'connection', 'dynamic_function_code', 'sql_type_timestamp', 'structure', 'cascade', 'characteristics', 'fbv', 'collation', 'parameter_specific_catalog', 'names', 'transforms', 'replace', 'are', 'leading', 'instantiable', 'selective', 'control', 'sql_real', 'external', 'both', 'second', 'year', 'bigint', 'system', 'true', 'matched', 'sql_float', 'trigger', 'escape', 'scroll', 'dlurlpath', 'section', 'timezone_hour', 'space', 'general', 'last', 'sql_date', 'granted', 'session_user', 'when', 'condition', 'scope_user', 'export', 'day', 'catalog', 'alter', 'of', 'to', 'no', 'check', 'hour', 'usage', 'key_member', 'nvarchar', 'character', 'input', 'output', 'corresponding', 'current_path', 'longvarchar', 'set', 'prepare', 'import', 'deferrable', 'collate', 'routine', 'smallint', 'interval', 'modify', 'result', 'open', 'merge', 'add', 'current_cluster_uid', 'scope', 'casespecific', 'group_concat', 'forall', 'none', 'begin', 'checked', 'data', 'is', 'blocked', 'delete', 'month', 'self', 'listagg', 'final', 'execute', 'sql_longvarchar', 'exec', 'localtime', 'nls_date_format', 'datalink', 'asc', 'truncate', 'time', 'current_session', 'value', 'decimal', 'sql_varchar', 'derived', 'ordinality', 'global', 'method', 'null', 'minute', 'release', 'specific', 'ordering', 'translation', 'grant', 'disabled', 'rowtype', 'off', 'by', 'connect_by_root', 'log', 'within', 'script', 'action', 'between', 'loop', 'under', 'dec', 'order', 'others', 'temporary', 'from', 'current_schema', 'on', 'insensitive', 'end-exec', 'insert', 'relative', 'localtimestamp', 'unnest', 'datetime_interval_code', 'leave', 'preferring', 'index', 'varchar', 'ifnull', 'indicator', 'style', 'repeat', 'allocate', 'map', 'into', 'exit', 'deterministic', 'where', 'recovery', 'array', 'file', 'inout', 'sqlstate', 'returned_octet_length', 'cascaded', 'continue', 'revoke', 'session', 'varchar2', 'profile', 'verify', 'sql_char', 'work', 'real', 'double', 'options', 'disable', 'float', 'character_set_schema', 'all', 'elsif', 'not', 'append', 'hashtype', 'default_like_escape_character', 'key_type', 'endif', 'unique', 'schema', 'option', 'describe', 'free'}
def converttimezone_sql(self, expression: sqlglot.expressions.temporal.ConvertTimezone) -> str:
884    def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
885        from_tz = expression.args.get("source_tz")
886        to_tz = expression.args.get("target_tz")
887        datetime = expression.args.get("timestamp")
888        options = expression.args.get("options")
889
890        return self.func("CONVERT_TZ", datetime, from_tz, to_tz, options)
def if_sql(self, expression: sqlglot.expressions.functions.If) -> str:
892    def if_sql(self, expression: exp.If) -> str:
893        this = self.sql(expression, "this")
894        true = self.sql(expression, "true")
895        false = self.sql(expression, "false")
896        return f"IF {this} THEN {true} ELSE {false} ENDIF"
def use_sql(self, expression: sqlglot.expressions.ddl.Use) -> str:
899    def use_sql(self, expression: exp.Use) -> str:
900        kind = expression.args.get("kind")
901        if kind and self.sql(kind).upper() != "SCHEMA":
902            self.unsupported(f"'USE {self.sql(kind)}' is not supported in Exasol")
903            return super().use_sql(expression)
904        this = self.sql(expression, "this")
905        return f"OPEN SCHEMA {this}"
def show_sql(self, expression: sqlglot.expressions.ddl.Show) -> str:
908    def show_sql(self, expression: exp.Show) -> str:
909        if expression.name == "TABLES":
910            db_name = expression.text("db")
911            schema_filter: exp.Expression = (
912                exp.Literal.string(db_name.upper()) if db_name else exp.CurrentSchema()
913            )
914            select = (
915                exp.select(exp.column("TABLE_NAME"))
916                .from_(exp.table_("EXA_ALL_TABLES", db="SYS"))
917                .where(exp.column("TABLE_SCHEMA").eq(schema_filter))
918            )
919            return self.sql(select)
920
921        if expression.name == "DATABASES":
922            select = exp.select(exp.column("SCHEMA_NAME")).from_(
923                exp.table_("EXA_SCHEMAS", db="SYS")
924            )
925            return self.sql(select)
926
927        return super().show_sql(expression)
def collate_sql(self, expression: sqlglot.expressions.functions.Collate) -> str:
929    def collate_sql(self, expression: exp.Collate) -> str:
930        return self.sql(expression.this)
def jsonextract_sql(self, expression: sqlglot.expressions.json.JSONExtract) -> str:
932    def jsonextract_sql(self, expression: exp.JSONExtract) -> str:
933        sql = self.func(
934            "JSON_EXTRACT", expression.this, expression.expression, *expression.expressions
935        )
936
937        emits = self.sql(expression, "emits")
938        if emits:
939            sql = f"{sql} EMITS {emits}"
940
941        return sql
@unsupported_args('flag')
def regexplike_sql(self, expression: sqlglot.expressions.core.RegexpLike) -> str:
943    @unsupported_args("flag")
944    def regexplike_sql(self, expression: exp.RegexpLike) -> str:
945        if not expression.args.get("full_match"):
946            pattern = expression.expression
947            if pattern.is_string:
948                expression.set("expression", exp.Literal.string(f".*{pattern.name}.*"))
949            else:
950                expression.set(
951                    "expression",
952                    exp.Paren(
953                        this=exp.Concat(
954                            expressions=[
955                                exp.Literal.string(".*"),
956                                pattern,
957                                exp.Literal.string(".*"),
958                            ]
959                        )
960                    ),
961                )
962        return self.binary(expression, "REGEXP_LIKE")
Inherited Members
sqlglot.generator.Generator
Generator
NULL_ORDERING_SUPPORTED
WINDOW_FUNCS_WITH_NULL_ORDERING
IGNORE_NULLS_IN_FUNC
IGNORE_NULLS_BEFORE_ORDER
LOCKING_READS_SUPPORTED
EXCEPT_INTERSECT_SUPPORT_ALL_CLAUSE
WRAP_DERIVED_VALUES
CREATE_FUNCTION_RETURN_AS
MATCHED_BY_SOURCE
SUPPORTS_MERGE_WHERE
MERGE_ALL_BY_NAME
SINGLE_STRING_INTERVAL
INTERVAL_ALLOWS_PLURAL_FORM
AUTO_REFRESH_BARE_INTERVALS
LIMIT_FETCH
LIMIT_ONLY_LITERALS
RENAME_TABLE_WITH_DB
GROUPINGS_SEP
SUPPORTS_GROUPING_SETS_AS_SUFFIX
INDEX_ON
INOUT_SEPARATOR
JOIN_HINTS
DIRECTED_JOINS
SUPPORTS_NEAREST_JOIN
TABLE_HINTS
QUERY_HINTS
QUERY_HINT_SEP
IS_BOOL_ALLOWED
CAST_TO_INT_ROUNDS
SAFE_INT_DIVISION
DUPLICATE_KEY_UPDATE_WITH_SET
LIMIT_IS_TOP
RETURNING_END
EXTRACT_ALLOWS_QUOTES
TZ_TO_WITH_TIME_ZONE
NVL2_SUPPORTED
VALUES_AS_TABLE
ALTER_TABLE_INCLUDE_COLUMN_KEYWORD
ALTER_TABLE_ADD_COLUMNS_WRAPPED
UNNEST_WITH_ORDINALITY
SEMI_ANTI_JOIN_WITH_SIDE
COMPUTED_COLUMN_WITH_TYPE
SUPPORTS_TABLE_COPY
TABLESAMPLE_REQUIRES_PARENS
TABLESAMPLE_SIZE_IS_ROWS
TABLESAMPLE_KEYWORDS
TABLESAMPLE_WITH_METHOD
TABLESAMPLE_SEED_KEYWORD
HISTORICAL_DATA_POST_ALIAS
COLLATE_IS_FUNC
DATA_TYPE_SPECIFIERS_ALLOWED
ENSURE_BOOLS
CTE_RECURSIVE_KEYWORD_REQUIRED
SUPPORTS_SINGLE_ARG_CONCAT
LAST_DAY_SUPPORTS_DATE_PART
SUPPORTS_TABLE_ALIAS_COLUMNS
SUPPORTS_NAMED_CTE_COLUMNS
UNPIVOT_ALIASES_ARE_IDENTIFIERS
PIVOT_ALIAS_WITH_AS
JSON_KEY_VALUE_PAIR_SEP
INSERT_OVERWRITE
SUPPORTS_SELECT_INTO
SUPPORTS_UNLOGGED_TABLES
SUPPORTS_CREATE_TABLE_LIKE
SUPPORTS_MODIFY_COLUMN
SUPPORTS_CHANGE_COLUMN
SUPPORTS_ALTER_COLUMN_NULLABILITY
SUPPORTS_ALTER_COLUMN_IF_EXISTS
LIKE_PROPERTY_INSIDE_SCHEMA
MULTI_ARG_DISTINCT
JSON_TYPE_REQUIRED_FOR_EXTRACTION
JSON_PATH_BRACKETED_KEY_SUPPORTED
JSON_PATH_SINGLE_QUOTE_ESCAPE
JSON_PATH_KEY_QUOTED_FORCES_BRACKETS
SUPPORTED_JSON_PATH_PARTS
CAN_IMPLEMENT_ARRAY_ANY
SUPPORTS_TO_NUMBER
SUPPORTS_WINDOW_EXCLUDE
SET_OP_MODIFIERS
SET_OP_LIMITS
SET_OP_PARENTHESIZED_OPERANDS
COPY_PARAMS_ARE_WRAPPED
COPY_PARAMS_EQ_REQUIRED
COPY_HAS_INTO_KEYWORD
UNICODE_SUBSTITUTE
STAR_EXCEPT
HEX_FUNC
BYTE_STRING_FUNCTION
WITH_PROPERTIES_PREFIX
QUOTE_JSON_PATH
PAD_FILL_PATTERN_IS_REQUIRED
SUPPORTS_EXPLODING_PROJECTIONS
ARRAY_CONCAT_IS_VAR_LEN
SUPPORTS_CONVERT_TIMEZONE
SUPPORTS_MEDIAN
SUPPORTS_UNIX_SECONDS
ALTER_SET_WRAPPED
NORMALIZE_EXTRACT_DATE_PARTS
PARSE_JSON_NAME
ARRAY_SIZE_NAME
ALTER_SET_TYPE
ARRAY_SIZE_DIM_REQUIRED
SUPPORTS_BETWEEN_FLAGS
SUPPORTS_LIKE_QUANTIFIERS
MATCH_AGAINST_TABLE_PREFIX
SET_ASSIGNMENT_REQUIRES_VARIABLE_KEYWORD
DECLARE_DEFAULT_ASSIGNMENT
UPDATE_STATEMENT_SUPPORTS_FROM
STAR_EXCLUDE_REQUIRES_DERIVED_TABLE
SUPPORTS_DROP_ALTER_ICEBERG_PROPERTY
UNSUPPORTED_TYPES
TYPE_PARAM_SETTINGS
TIME_PART_SINGULARS
TOKEN_MAPPING
STRUCT_DELIMITER
PARAMETER_TOKEN
NAMED_PLACEHOLDER_TOKEN
EXPRESSION_PRECEDES_PROPERTIES_CREATABLES
PROPERTIES_LOCATION
WITH_SEPARATED_COMMENTS
EXCLUDE_COMMENTS
UNWRAPPED_INTERVAL_VALUES
PARAMETERIZABLE_TEXT_TYPES
EXPRESSIONS_WITHOUT_NESTED_CTES
RESPECT_IGNORE_NULLS_UNSUPPORTED_EXPRESSIONS
MOD_OPERATOR
MOD_PAREN_PARENT_TYPES
ALTER_PARTITION_OPTIONS
SAFE_JSON_PATH_KEY_RE
SENTINEL_LINE_BREAK
pretty
identify
normalize
pad
unsupported_level
max_unsupported
leading_comma
max_text_width
comments
dialect
normalize_functions
unsupported_messages
generate
preprocess
unsupported
sep
seg
sanitize_comment
maybe_comment
wrap
no_identify
normalize_func
indent
sql
uncache_sql
cache_sql
characterset_sql
column_parts
column_sql
pseudocolumn_sql
columnposition_sql
columndef_sql
columnconstraint_sql
computedcolumnconstraint_sql
autoincrementcolumnconstraint_sql
compresscolumnconstraint_sql
generatedasidentitycolumnconstraint_sql
generatedasrowcolumnconstraint_sql
periodforsystemtimeconstraint_sql
notnullcolumnconstraint_sql
primarykeycolumnconstraint_sql
uniquecolumnconstraint_sql
inoutcolumnconstraint_sql
createable_sql
create_sql
sequenceproperties_sql
triggerproperties_sql
triggerreferencing_sql
triggerevent_sql
clone_sql
describe_sql
heredoc_sql
prepend_ctes
with_sql
cte_sql
tablealias_sql
bitstring_sql
hexstring_sql
bytestring_sql
unicodestring_sql
rawstring_sql
datatypeparam_sql
datatype_param_bound_limiter
directory_sql
delete_sql
drop_sql
set_operation
set_operations
fetch_sql
limitoptions_sql
filter_sql
per_sql
hint_sql
indexparameters_sql
index_sql
dynamicidentifier_sql
identifier_sql
hex_sql
lowerhex_sql
inputoutputformat_sql
national_sql
partition_sql
properties_sql
root_properties
properties
with_properties
locate_properties
property_name
property_sql
uuidproperty_sql
likeproperty_sql
fallbackproperty_sql
journalproperty_sql
freespaceproperty_sql
checksumproperty_sql
mergeblockratioproperty_sql
moduleproperty_sql
datablocksizeproperty_sql
blockcompressionproperty_sql
isolatedloadingproperty_sql
partitionboundspec_sql
partitionedofproperty_sql
lockingproperty_sql
lockingstatement_sql
withdataproperty_sql
withsystemversioningproperty_sql
insert_sql
introducer_sql
kill_sql
pseudotype_sql
objectidentifier_sql
onconflict_sql
returning_sql
rowformatdelimitedproperty_sql
withtablehint_sql
indextablehint_sql
historicaldata_sql
table_parts
table_sql
tablefromrows_sql
tablesample_sql
pivot_sql
version_sql
tuple_sql
update_sql
values_sql
var_sql
into_sql
from_sql
groupingsets_sql
rollup_sql
rollupindex_sql
rollupproperty_sql
cube_sql
group_sql
having_sql
connectto_sql
disconnect_sql
connect_sql
prior_sql
join_sql
nearest_sql
lambda_sql
lateral_op
lateral_sql
limit_sql
offset_sql
setitem_sql
set_sql
queryband_sql
pragma_sql
lock_sql
literal_sql
escape_str
loaddata_sql
null_sql
boolean_sql
booland_sql
boolor_sql
order_sql
withfill_sql
cluster_sql
clusterproperty_sql
distribute_sql
sort_sql
ordered_sql
matchrecognizemeasure_sql
matchrecognize_sql
query_modifiers
options_modifier
forclause_sql
queryoption_sql
offset_limit_modifiers
after_limit_modifiers
schema_sql
schema_columns_sql
star_sql
parameter_sql
sessionparameter_sql
placeholder_sql
subquery_sql
qualify_sql
unnest_sql
prewhere_sql
where_sql
window_sql
partition_by_sql
partitionbyexcluding_sql
windowspec_sql
withingroup_sql
between_sql
bracket_offset_expressions
bracket_sql
all_sql
any_sql
exists_sql
case_sql
constraint_sql
nextvaluefor_sql
extract_sql
trim_sql
convert_concat_args
concat_sql
concatws_sql
check_sql
foreignkey_sql
primarykey_sql
timeserieskey_sql
matchagainst_sql
jsonkeyvalue_sql
jsonpath_sql
json_path_part
formatjson_sql
formatphrase_sql
teradatatitle_sql
jsonarray_sql
jsonarrayagg_sql
jsoncolumndef_sql
jsonschema_sql
jsontable_sql
openjsoncolumndef_sql
openjson_sql
in_sql
in_unnest_op
interval_sql
return_sql
reference_sql
anonymous_sql
paren_sql
neg_sql
not_sql
alias_sql
pivotalias_sql
aliases_sql
atindex_sql
attimezone_sql
fromtimezone_sql
fromiso8601date_sql
fromiso8601timestamp_sql
fromiso8601timestampnanos_sql
add_sql
and_sql
or_sql
xor_sql
connector_sql
bitwiseand_sql
bitwiseleftshift_sql
bitwisenot_sql
bitwiseor_sql
bitwiserightshift_sql
bitwisexor_sql
cast_sql
strtotime_sql
strtodate_sql
parsedatetime_sql
currentdate_sql
command_sql
comment_sql
mergetreettlaction_sql
mergetreettl_sql
transaction_sql
commit_sql
rollback_sql
altercolumn_sql
modifycolumn_sql
alterindex_sql
alterdiststyle_sql
altersortkey_sql
alterrename_sql
renamecolumn_sql
alterset_sql
alter_sql
altersession_sql
add_column_sql
droppartition_sql
dropprimarykey_sql
addconstraint_sql
replacecolumns_sql
addpartition_sql
distinct_sql
ignorenulls_sql
respectnulls_sql
havingmax_sql
intdiv_sql
dpipe_sql
nullif_zero_divisor
div_sql
safedivide_sql
overlaps_sql
distance_sql
distancend_sql
dot_sql
eq_sql
propertyeq_sql
escape_sql
glob_sql
gt_sql
gte_sql
is_sql
like_sql
ilike_sql
match_sql
similarto_sql
lt_sql
lte_sql
mod_sql
mul_sql
neq_sql
nullsafeeq_sql
nullsafeneq_sql
sub_sql
trycast_sql
jsoncast_sql
try_sql
log_sql
binary
ceil_floor
function_fallback_sql
function_name
func
format_args
too_wide
format_time
expressions
op_expressions
naked_property
tag_sql
token_sql
userdefinedfunction_sql
macrooverloads_sql
macrooverload_sql
joinhint_sql
kwarg_sql
when_sql
whens_sql
merge_sql
tochar_sql
tonumber_sql
dictproperty_sql
dictrange_sql
dictsubproperty_sql
aggregatekeyproperty_sql
duplicatekeyproperty_sql
uniquekeyproperty_sql
distributedbyproperty_sql
oncluster_sql
clusteredbyproperty_sql
anyvalue_sql
querytransform_sql
indexconstraintoption_sql
checkcolumnconstraint_sql
indexcolumnconstraint_sql
nvl2_sql
nthvalue_sql
comprehension_sql
columnprefix_sql
opclass_sql
predict_sql
generateembedding_sql
generatetext_sql
generatetable_sql
generatebool_sql
generateint_sql
generatedouble_sql
mltranslate_sql
mlforecast_sql
aiforecast_sql
featuresattime_sql
vectorsearch_sql
forin_sql
refresh_sql
toarray_sql
tsordstotime_sql
tsordstotimestamp_sql
tsordstodatetime_sql
tsordstodate_sql
unixdate_sql
lastday_sql
dateadd_sql
arrayinsert_sql
arrayany_sql
struct_sql
partitionrange_sql
truncatetable_sql
convert_sql
copyparameter_sql
credentials_sql
copy_sql
semicolon_sql
datadeletionproperty_sql
maskingpolicycolumnconstraint_sql
gapfill_sql
scope_resolution
scoperesolution_sql
parsejson_sql
rand_sql
changes_sql
pad_sql
summarize_sql
explodinggenerateseries_sql
json_sql
jsonvalue_sql
skipjsoncolumn_sql
conditionalinsert_sql
multitableinserts_sql
oncondition_sql
jsonextractquote_sql
jsonexists_sql
min_sql
max_sql
arrayagg_sql
timeslice_sql
slice_sql
apply_sql
grant_sql
revoke_sql
grantprivilege_sql
grantprincipal_sql
columns_sql
overlay_sql
todouble_sql
string_sql
median_sql
overflowtruncatebehavior_sql
unixseconds_sql
arraysort_sql
arraysize_sql
attach_sql
detach_sql
attachoption_sql
watermarkcolumnconstraint_sql
encodeproperty_sql
includeproperty_sql
xmlelement_sql
xmlkeyvalueoption_sql
partitionbyrangeproperty_sql
partitionbyrangepropertydynamic_sql
unpivotcolumns_sql
analyzesample_sql
analyzestatistics_sql
analyzehistogram_sql
analyzedelete_sql
analyzelistchainedrows_sql
analyzevalidate_sql
analyze_sql
xmltable_sql
xmlnamespace_sql
export_sql
declare_sql
declareitem_sql
recursivewithsearch_sql
parameterizedagg_sql
anonymousaggfunc_sql
combinedaggfunc_sql
combinedparameterizedagg_sql
install_sql
liststage_sql
get_put_sql
translatecharacters_sql
decodecase_sql
semanticview_sql
getextract_sql
datefromunixdate_sql
space_sql
buildproperty_sql
refreshtriggerproperty_sql
modelattribute_sql
directorystage_sql
uuid_sql
initcap_sql
localtime_sql
localtimestamp_sql
weekstart_name
weekstart_sql
chr_sql
weightstring_sql
block_sql
functionspecification_sql
storedprocedure_sql
ifblock_sql
casestatement_sql
whileblock_sql
loopblock_sql
repeatblock_sql
leave_sql
iterate_sql
execute_sql
executesql_sql
altermodifysqlsecurity_sql
usingproperty_sql
renameindex_sql