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