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