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( 352 self, e, func_name="LISTAGG", within_group=True 353 ), 354 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/edit_distance.htm#EDIT_DISTANCE 355 exp.Levenshtein: unsupported_args("ins_cost", "del_cost", "sub_cost", "max_dist")( 356 rename_func("EDIT_DISTANCE") 357 ), 358 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/mod.htm 359 exp.Mod: rename_func("MOD"), 360 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/from_posix_time.htm 361 exp.UnixToTime: lambda self, e: self.func("FROM_POSIX_TIME", e.this), 362 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/rank.htm 363 exp.Rank: unsupported_args("expressions")(lambda *_: "RANK()"), 364 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/dense_rank.htm 365 exp.DenseRank: unsupported_args("expressions")(lambda *_: "DENSE_RANK()"), 366 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/regexp_substr.htm 367 exp.RegexpExtract: unsupported_args("parameters", "group")(rename_func("REGEXP_SUBSTR")), 368 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/regexp_replace.htm 369 exp.RegexpReplace: unsupported_args("modifiers")(rename_func("REGEXP_REPLACE")), 370 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/var_pop.htm 371 exp.VariancePop: rename_func("VAR_POP"), 372 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/approximate_count_distinct.htm 373 exp.ApproxDistinct: unsupported_args("accuracy")(rename_func("APPROXIMATE_COUNT_DISTINCT")), 374 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_char%20(datetime).htm 375 exp.TimeToStr: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)), 376 exp.ToChar: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)), 377 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_date.htm 378 exp.TsOrDsToDate: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)), 379 exp.TimeStrToTime: timestrtotime_sql, 380 exp.TimestampTrunc: _timestamp_trunc_sql, 381 exp.StrToTime: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)), 382 exp.CurrentUser: lambda *_: "CURRENT_USER", 383 exp.AtTimeZone: lambda self, e: self.func( 384 "CONVERT_TZ", 385 e.this, 386 "'UTC'", 387 e.args.get("zone"), 388 ), 389 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/instr.htm 390 exp.StrPosition: lambda self, e: strposition_sql( 391 self, e, func_name="INSTR", supports_position=True, supports_occurrence=True 392 ), 393 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha%5B1%5D.htm#HASH_SHA%5B1%5D 394 exp.SHA: rename_func("HASH_SHA"), 395 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha256.htm 396 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha512.htm 397 exp.SHA2: _sha2_sql, 398 exp.MD5: rename_func("HASH_MD5"), 399 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hashtype_md5.htm 400 exp.MD5Digest: rename_func("HASHTYPE_MD5"), 401 # https://docs.exasol.com/db/latest/sql/create_view.htm 402 exp.CommentColumnConstraint: lambda self, e: f"COMMENT IS {self.sql(e, 'this')}", 403 exp.SubstringIndex: _substring_index_sql, 404 exp.WeekOfYear: rename_func("WEEK"), 405 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_date.htm 406 exp.Date: rename_func("TO_DATE"), 407 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_timestamp.htm 408 exp.Timestamp: rename_func("TO_TIMESTAMP"), 409 exp.Quarter: lambda self, e: f"CEIL(MONTH(TO_DATE({self.sql(e, 'this')}))/3)", 410 exp.LastDay: no_last_day_sql, 411 } 412 413 # https://docs.exasol.com/db/7.1/sql_references/system_tables/metadata/exa_sql_keywords.htm 414 RESERVED_KEYWORDS = { 415 "absolute", 416 "action", 417 "add", 418 "after", 419 "all", 420 "allocate", 421 "alter", 422 "and", 423 "any", 424 "append", 425 "are", 426 "array", 427 "as", 428 "asc", 429 "asensitive", 430 "assertion", 431 "at", 432 "attribute", 433 "authid", 434 "authorization", 435 "before", 436 "begin", 437 "between", 438 "bigint", 439 "binary", 440 "bit", 441 "blob", 442 "blocked", 443 "bool", 444 "boolean", 445 "both", 446 "by", 447 "byte", 448 "call", 449 "called", 450 "cardinality", 451 "cascade", 452 "cascaded", 453 "case", 454 "casespecific", 455 "cast", 456 "catalog", 457 "chain", 458 "char", 459 "character", 460 "character_set_catalog", 461 "character_set_name", 462 "character_set_schema", 463 "characteristics", 464 "check", 465 "checked", 466 "clob", 467 "close", 468 "coalesce", 469 "collate", 470 "collation", 471 "collation_catalog", 472 "collation_name", 473 "collation_schema", 474 "column", 475 "commit", 476 "condition", 477 "connect_by_iscycle", 478 "connect_by_isleaf", 479 "connect_by_root", 480 "connection", 481 "constant", 482 "constraint", 483 "constraint_state_default", 484 "constraints", 485 "constructor", 486 "contains", 487 "continue", 488 "control", 489 "convert", 490 "corresponding", 491 "create", 492 "cs", 493 "csv", 494 "cube", 495 "current", 496 "current_cluster", 497 "current_cluster_uid", 498 "current_date", 499 "current_path", 500 "current_role", 501 "current_schema", 502 "current_session", 503 "current_statement", 504 "current_time", 505 "current_timestamp", 506 "current_user", 507 "cursor", 508 "cycle", 509 "data", 510 "datalink", 511 "datetime_interval_code", 512 "datetime_interval_precision", 513 "day", 514 "dbtimezone", 515 "deallocate", 516 "dec", 517 "decimal", 518 "declare", 519 "default", 520 "default_like_escape_character", 521 "deferrable", 522 "deferred", 523 "defined", 524 "definer", 525 "delete", 526 "deref", 527 "derived", 528 "desc", 529 "describe", 530 "descriptor", 531 "deterministic", 532 "disable", 533 "disabled", 534 "disconnect", 535 "dispatch", 536 "distinct", 537 "dlurlcomplete", 538 "dlurlpath", 539 "dlurlpathonly", 540 "dlurlscheme", 541 "dlurlserver", 542 "dlvalue", 543 "do", 544 "domain", 545 "double", 546 "drop", 547 "dynamic", 548 "dynamic_function", 549 "dynamic_function_code", 550 "each", 551 "else", 552 "elseif", 553 "elsif", 554 "emits", 555 "enable", 556 "enabled", 557 "end", 558 "end-exec", 559 "endif", 560 "enforce", 561 "equals", 562 "errors", 563 "escape", 564 "except", 565 "exception", 566 "exec", 567 "execute", 568 "exists", 569 "exit", 570 "export", 571 "external", 572 "extract", 573 "false", 574 "fbv", 575 "fetch", 576 "file", 577 "final", 578 "first", 579 "float", 580 "following", 581 "for", 582 "forall", 583 "force", 584 "format", 585 "found", 586 "free", 587 "from", 588 "fs", 589 "full", 590 "function", 591 "general", 592 "generated", 593 "geometry", 594 "get", 595 "global", 596 "go", 597 "goto", 598 "grant", 599 "granted", 600 "group", 601 "group_concat", 602 "grouping", 603 "groups", 604 "hashtype", 605 "hashtype_format", 606 "having", 607 "high", 608 "hold", 609 "hour", 610 "identity", 611 "if", 612 "ifnull", 613 "immediate", 614 "impersonate", 615 "implementation", 616 "import", 617 "in", 618 "index", 619 "indicator", 620 "inner", 621 "inout", 622 "input", 623 "insensitive", 624 "insert", 625 "instance", 626 "instantiable", 627 "int", 628 "integer", 629 "integrity", 630 "intersect", 631 "interval", 632 "into", 633 "inverse", 634 "invoker", 635 "is", 636 "iterate", 637 "join", 638 "key_member", 639 "key_type", 640 "large", 641 "last", 642 "lateral", 643 "ldap", 644 "leading", 645 "leave", 646 "left", 647 "level", 648 "like", 649 "limit", 650 "listagg", 651 "localtime", 652 "localtimestamp", 653 "locator", 654 "log", 655 "longvarchar", 656 "loop", 657 "low", 658 "map", 659 "match", 660 "matched", 661 "merge", 662 "method", 663 "minus", 664 "minute", 665 "mod", 666 "modifies", 667 "modify", 668 "module", 669 "month", 670 "names", 671 "national", 672 "natural", 673 "nchar", 674 "nclob", 675 "new", 676 "next", 677 "nls_date_format", 678 "nls_date_language", 679 "nls_first_day_of_week", 680 "nls_numeric_characters", 681 "nls_timestamp_format", 682 "no", 683 "nocycle", 684 "nologging", 685 "none", 686 "not", 687 "null", 688 "nullif", 689 "number", 690 "numeric", 691 "nvarchar", 692 "nvarchar2", 693 "object", 694 "of", 695 "off", 696 "old", 697 "on", 698 "only", 699 "open", 700 "option", 701 "options", 702 "or", 703 "order", 704 "ordering", 705 "ordinality", 706 "others", 707 "out", 708 "outer", 709 "output", 710 "over", 711 "overlaps", 712 "overlay", 713 "overriding", 714 "pad", 715 "parallel_enable", 716 "parameter", 717 "parameter_specific_catalog", 718 "parameter_specific_name", 719 "parameter_specific_schema", 720 "parquet", 721 "partial", 722 "path", 723 "permission", 724 "placing", 725 "plus", 726 "preceding", 727 "preferring", 728 "prepare", 729 "preserve", 730 "prior", 731 "privileges", 732 "procedure", 733 "profile", 734 "qualify", 735 "random", 736 "range", 737 "read", 738 "reads", 739 "real", 740 "recovery", 741 "recursive", 742 "ref", 743 "references", 744 "referencing", 745 "refresh", 746 "regexp_like", 747 "relative", 748 "release", 749 "rename", 750 "repeat", 751 "replace", 752 "restore", 753 "restrict", 754 "result", 755 "return", 756 "returned_length", 757 "returned_octet_length", 758 "returns", 759 "revoke", 760 "right", 761 "rollback", 762 "rollup", 763 "routine", 764 "row", 765 "rows", 766 "rowtype", 767 "savepoint", 768 "schema", 769 "scope", 770 "scope_user", 771 "script", 772 "scroll", 773 "search", 774 "second", 775 "section", 776 "security", 777 "select", 778 "selective", 779 "self", 780 "sensitive", 781 "separator", 782 "sequence", 783 "session", 784 "session_user", 785 "sessiontimezone", 786 "set", 787 "sets", 788 "shortint", 789 "similar", 790 "smallint", 791 "some", 792 "source", 793 "space", 794 "specific", 795 "specifictype", 796 "sql", 797 "sql_bigint", 798 "sql_bit", 799 "sql_char", 800 "sql_date", 801 "sql_decimal", 802 "sql_double", 803 "sql_float", 804 "sql_integer", 805 "sql_longvarchar", 806 "sql_numeric", 807 "sql_preprocessor_script", 808 "sql_real", 809 "sql_smallint", 810 "sql_timestamp", 811 "sql_tinyint", 812 "sql_type_date", 813 "sql_type_timestamp", 814 "sql_varchar", 815 "sqlexception", 816 "sqlstate", 817 "sqlwarning", 818 "start", 819 "state", 820 "statement", 821 "static", 822 "structure", 823 "style", 824 "substring", 825 "subtype", 826 "sysdate", 827 "system", 828 "system_user", 829 "systimestamp", 830 "table", 831 "temporary", 832 "text", 833 "then", 834 "time", 835 "timestamp", 836 "timezone_hour", 837 "timezone_minute", 838 "tinyint", 839 "to", 840 "trailing", 841 "transaction", 842 "transform", 843 "transforms", 844 "translation", 845 "treat", 846 "trigger", 847 "trim", 848 "true", 849 "truncate", 850 "under", 851 "union", 852 "unique", 853 "unknown", 854 "unlink", 855 "unnest", 856 "until", 857 "update", 858 "usage", 859 "user", 860 "using", 861 "value", 862 "values", 863 "varchar", 864 "varchar2", 865 "varray", 866 "verify", 867 "view", 868 "when", 869 "whenever", 870 "where", 871 "while", 872 "window", 873 "with", 874 "within", 875 "without", 876 "work", 877 "year", 878 "yes", 879 "zone", 880 } 881 882 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 883 from_tz = expression.args.get("source_tz") 884 to_tz = expression.args.get("target_tz") 885 datetime = expression.args.get("timestamp") 886 options = expression.args.get("options") 887 888 return self.func("CONVERT_TZ", datetime, from_tz, to_tz, options) 889 890 def if_sql(self, expression: exp.If) -> str: 891 this = self.sql(expression, "this") 892 true = self.sql(expression, "true") 893 false = self.sql(expression, "false") 894 return f"IF {this} THEN {true} ELSE {false} ENDIF" 895 896 # https://docs.exasol.com/db/latest/sql/open_schema.htm 897 def use_sql(self, expression: exp.Use) -> str: 898 kind = expression.args.get("kind") 899 if kind and self.sql(kind).upper() != "SCHEMA": 900 self.unsupported(f"'USE {self.sql(kind)}' is not supported in Exasol") 901 return super().use_sql(expression) 902 this = self.sql(expression, "this") 903 return f"OPEN SCHEMA {this}" 904 905 # https://docs.exasol.com/db/latest/sql_references/metadata/metadata_system_tables.htm 906 def show_sql(self, expression: exp.Show) -> str: 907 if expression.name == "TABLES": 908 db_name = expression.text("db") 909 schema_filter: exp.Expression = ( 910 exp.Literal.string(db_name.upper()) if db_name else exp.CurrentSchema() 911 ) 912 select = ( 913 exp.select(exp.column("TABLE_NAME")) 914 .from_(exp.table_("EXA_ALL_TABLES", db="SYS")) 915 .where(exp.column("TABLE_SCHEMA").eq(schema_filter)) 916 ) 917 return self.sql(select) 918 919 return super().show_sql(expression) 920 921 def collate_sql(self, expression: exp.Collate) -> str: 922 return self.sql(expression.this) 923 924 def jsonextract_sql(self, expression: exp.JSONExtract) -> str: 925 sql = self.func( 926 "JSON_EXTRACT", expression.this, expression.expression, *expression.expressions 927 ) 928 929 emits = self.sql(expression, "emits") 930 if emits: 931 sql = f"{sql} EMITS {emits}" 932 933 return sql 934 935 @unsupported_args("flag") 936 def regexplike_sql(self, expression: exp.RegexpLike) -> str: 937 if not expression.args.get("full_match"): 938 pattern = expression.expression 939 if pattern.is_string: 940 expression.set("expression", exp.Literal.string(f".*{pattern.name}.*")) 941 else: 942 expression.set( 943 "expression", 944 exp.Paren( 945 this=exp.Concat( 946 expressions=[ 947 exp.Literal.string(".*"), 948 pattern, 949 exp.Literal.string(".*"), 950 ] 951 ) 952 ), 953 ) 954 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( 353 self, e, func_name="LISTAGG", within_group=True 354 ), 355 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/edit_distance.htm#EDIT_DISTANCE 356 exp.Levenshtein: unsupported_args("ins_cost", "del_cost", "sub_cost", "max_dist")( 357 rename_func("EDIT_DISTANCE") 358 ), 359 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/mod.htm 360 exp.Mod: rename_func("MOD"), 361 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/from_posix_time.htm 362 exp.UnixToTime: lambda self, e: self.func("FROM_POSIX_TIME", e.this), 363 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/rank.htm 364 exp.Rank: unsupported_args("expressions")(lambda *_: "RANK()"), 365 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/dense_rank.htm 366 exp.DenseRank: unsupported_args("expressions")(lambda *_: "DENSE_RANK()"), 367 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/regexp_substr.htm 368 exp.RegexpExtract: unsupported_args("parameters", "group")(rename_func("REGEXP_SUBSTR")), 369 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/regexp_replace.htm 370 exp.RegexpReplace: unsupported_args("modifiers")(rename_func("REGEXP_REPLACE")), 371 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/var_pop.htm 372 exp.VariancePop: rename_func("VAR_POP"), 373 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/approximate_count_distinct.htm 374 exp.ApproxDistinct: unsupported_args("accuracy")(rename_func("APPROXIMATE_COUNT_DISTINCT")), 375 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_char%20(datetime).htm 376 exp.TimeToStr: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)), 377 exp.ToChar: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)), 378 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_date.htm 379 exp.TsOrDsToDate: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)), 380 exp.TimeStrToTime: timestrtotime_sql, 381 exp.TimestampTrunc: _timestamp_trunc_sql, 382 exp.StrToTime: lambda self, e: self.func("TO_DATE", e.this, self.format_time(e)), 383 exp.CurrentUser: lambda *_: "CURRENT_USER", 384 exp.AtTimeZone: lambda self, e: self.func( 385 "CONVERT_TZ", 386 e.this, 387 "'UTC'", 388 e.args.get("zone"), 389 ), 390 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/instr.htm 391 exp.StrPosition: lambda self, e: strposition_sql( 392 self, e, func_name="INSTR", supports_position=True, supports_occurrence=True 393 ), 394 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha%5B1%5D.htm#HASH_SHA%5B1%5D 395 exp.SHA: rename_func("HASH_SHA"), 396 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha256.htm 397 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha512.htm 398 exp.SHA2: _sha2_sql, 399 exp.MD5: rename_func("HASH_MD5"), 400 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hashtype_md5.htm 401 exp.MD5Digest: rename_func("HASHTYPE_MD5"), 402 # https://docs.exasol.com/db/latest/sql/create_view.htm 403 exp.CommentColumnConstraint: lambda self, e: f"COMMENT IS {self.sql(e, 'this')}", 404 exp.SubstringIndex: _substring_index_sql, 405 exp.WeekOfYear: rename_func("WEEK"), 406 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_date.htm 407 exp.Date: rename_func("TO_DATE"), 408 # https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/to_timestamp.htm 409 exp.Timestamp: rename_func("TO_TIMESTAMP"), 410 exp.Quarter: lambda self, e: f"CEIL(MONTH(TO_DATE({self.sql(e, 'this')}))/3)", 411 exp.LastDay: no_last_day_sql, 412 } 413 414 # https://docs.exasol.com/db/7.1/sql_references/system_tables/metadata/exa_sql_keywords.htm 415 RESERVED_KEYWORDS = { 416 "absolute", 417 "action", 418 "add", 419 "after", 420 "all", 421 "allocate", 422 "alter", 423 "and", 424 "any", 425 "append", 426 "are", 427 "array", 428 "as", 429 "asc", 430 "asensitive", 431 "assertion", 432 "at", 433 "attribute", 434 "authid", 435 "authorization", 436 "before", 437 "begin", 438 "between", 439 "bigint", 440 "binary", 441 "bit", 442 "blob", 443 "blocked", 444 "bool", 445 "boolean", 446 "both", 447 "by", 448 "byte", 449 "call", 450 "called", 451 "cardinality", 452 "cascade", 453 "cascaded", 454 "case", 455 "casespecific", 456 "cast", 457 "catalog", 458 "chain", 459 "char", 460 "character", 461 "character_set_catalog", 462 "character_set_name", 463 "character_set_schema", 464 "characteristics", 465 "check", 466 "checked", 467 "clob", 468 "close", 469 "coalesce", 470 "collate", 471 "collation", 472 "collation_catalog", 473 "collation_name", 474 "collation_schema", 475 "column", 476 "commit", 477 "condition", 478 "connect_by_iscycle", 479 "connect_by_isleaf", 480 "connect_by_root", 481 "connection", 482 "constant", 483 "constraint", 484 "constraint_state_default", 485 "constraints", 486 "constructor", 487 "contains", 488 "continue", 489 "control", 490 "convert", 491 "corresponding", 492 "create", 493 "cs", 494 "csv", 495 "cube", 496 "current", 497 "current_cluster", 498 "current_cluster_uid", 499 "current_date", 500 "current_path", 501 "current_role", 502 "current_schema", 503 "current_session", 504 "current_statement", 505 "current_time", 506 "current_timestamp", 507 "current_user", 508 "cursor", 509 "cycle", 510 "data", 511 "datalink", 512 "datetime_interval_code", 513 "datetime_interval_precision", 514 "day", 515 "dbtimezone", 516 "deallocate", 517 "dec", 518 "decimal", 519 "declare", 520 "default", 521 "default_like_escape_character", 522 "deferrable", 523 "deferred", 524 "defined", 525 "definer", 526 "delete", 527 "deref", 528 "derived", 529 "desc", 530 "describe", 531 "descriptor", 532 "deterministic", 533 "disable", 534 "disabled", 535 "disconnect", 536 "dispatch", 537 "distinct", 538 "dlurlcomplete", 539 "dlurlpath", 540 "dlurlpathonly", 541 "dlurlscheme", 542 "dlurlserver", 543 "dlvalue", 544 "do", 545 "domain", 546 "double", 547 "drop", 548 "dynamic", 549 "dynamic_function", 550 "dynamic_function_code", 551 "each", 552 "else", 553 "elseif", 554 "elsif", 555 "emits", 556 "enable", 557 "enabled", 558 "end", 559 "end-exec", 560 "endif", 561 "enforce", 562 "equals", 563 "errors", 564 "escape", 565 "except", 566 "exception", 567 "exec", 568 "execute", 569 "exists", 570 "exit", 571 "export", 572 "external", 573 "extract", 574 "false", 575 "fbv", 576 "fetch", 577 "file", 578 "final", 579 "first", 580 "float", 581 "following", 582 "for", 583 "forall", 584 "force", 585 "format", 586 "found", 587 "free", 588 "from", 589 "fs", 590 "full", 591 "function", 592 "general", 593 "generated", 594 "geometry", 595 "get", 596 "global", 597 "go", 598 "goto", 599 "grant", 600 "granted", 601 "group", 602 "group_concat", 603 "grouping", 604 "groups", 605 "hashtype", 606 "hashtype_format", 607 "having", 608 "high", 609 "hold", 610 "hour", 611 "identity", 612 "if", 613 "ifnull", 614 "immediate", 615 "impersonate", 616 "implementation", 617 "import", 618 "in", 619 "index", 620 "indicator", 621 "inner", 622 "inout", 623 "input", 624 "insensitive", 625 "insert", 626 "instance", 627 "instantiable", 628 "int", 629 "integer", 630 "integrity", 631 "intersect", 632 "interval", 633 "into", 634 "inverse", 635 "invoker", 636 "is", 637 "iterate", 638 "join", 639 "key_member", 640 "key_type", 641 "large", 642 "last", 643 "lateral", 644 "ldap", 645 "leading", 646 "leave", 647 "left", 648 "level", 649 "like", 650 "limit", 651 "listagg", 652 "localtime", 653 "localtimestamp", 654 "locator", 655 "log", 656 "longvarchar", 657 "loop", 658 "low", 659 "map", 660 "match", 661 "matched", 662 "merge", 663 "method", 664 "minus", 665 "minute", 666 "mod", 667 "modifies", 668 "modify", 669 "module", 670 "month", 671 "names", 672 "national", 673 "natural", 674 "nchar", 675 "nclob", 676 "new", 677 "next", 678 "nls_date_format", 679 "nls_date_language", 680 "nls_first_day_of_week", 681 "nls_numeric_characters", 682 "nls_timestamp_format", 683 "no", 684 "nocycle", 685 "nologging", 686 "none", 687 "not", 688 "null", 689 "nullif", 690 "number", 691 "numeric", 692 "nvarchar", 693 "nvarchar2", 694 "object", 695 "of", 696 "off", 697 "old", 698 "on", 699 "only", 700 "open", 701 "option", 702 "options", 703 "or", 704 "order", 705 "ordering", 706 "ordinality", 707 "others", 708 "out", 709 "outer", 710 "output", 711 "over", 712 "overlaps", 713 "overlay", 714 "overriding", 715 "pad", 716 "parallel_enable", 717 "parameter", 718 "parameter_specific_catalog", 719 "parameter_specific_name", 720 "parameter_specific_schema", 721 "parquet", 722 "partial", 723 "path", 724 "permission", 725 "placing", 726 "plus", 727 "preceding", 728 "preferring", 729 "prepare", 730 "preserve", 731 "prior", 732 "privileges", 733 "procedure", 734 "profile", 735 "qualify", 736 "random", 737 "range", 738 "read", 739 "reads", 740 "real", 741 "recovery", 742 "recursive", 743 "ref", 744 "references", 745 "referencing", 746 "refresh", 747 "regexp_like", 748 "relative", 749 "release", 750 "rename", 751 "repeat", 752 "replace", 753 "restore", 754 "restrict", 755 "result", 756 "return", 757 "returned_length", 758 "returned_octet_length", 759 "returns", 760 "revoke", 761 "right", 762 "rollback", 763 "rollup", 764 "routine", 765 "row", 766 "rows", 767 "rowtype", 768 "savepoint", 769 "schema", 770 "scope", 771 "scope_user", 772 "script", 773 "scroll", 774 "search", 775 "second", 776 "section", 777 "security", 778 "select", 779 "selective", 780 "self", 781 "sensitive", 782 "separator", 783 "sequence", 784 "session", 785 "session_user", 786 "sessiontimezone", 787 "set", 788 "sets", 789 "shortint", 790 "similar", 791 "smallint", 792 "some", 793 "source", 794 "space", 795 "specific", 796 "specifictype", 797 "sql", 798 "sql_bigint", 799 "sql_bit", 800 "sql_char", 801 "sql_date", 802 "sql_decimal", 803 "sql_double", 804 "sql_float", 805 "sql_integer", 806 "sql_longvarchar", 807 "sql_numeric", 808 "sql_preprocessor_script", 809 "sql_real", 810 "sql_smallint", 811 "sql_timestamp", 812 "sql_tinyint", 813 "sql_type_date", 814 "sql_type_timestamp", 815 "sql_varchar", 816 "sqlexception", 817 "sqlstate", 818 "sqlwarning", 819 "start", 820 "state", 821 "statement", 822 "static", 823 "structure", 824 "style", 825 "substring", 826 "subtype", 827 "sysdate", 828 "system", 829 "system_user", 830 "systimestamp", 831 "table", 832 "temporary", 833 "text", 834 "then", 835 "time", 836 "timestamp", 837 "timezone_hour", 838 "timezone_minute", 839 "tinyint", 840 "to", 841 "trailing", 842 "transaction", 843 "transform", 844 "transforms", 845 "translation", 846 "treat", 847 "trigger", 848 "trim", 849 "true", 850 "truncate", 851 "under", 852 "union", 853 "unique", 854 "unknown", 855 "unlink", 856 "unnest", 857 "until", 858 "update", 859 "usage", 860 "user", 861 "using", 862 "value", 863 "values", 864 "varchar", 865 "varchar2", 866 "varray", 867 "verify", 868 "view", 869 "when", 870 "whenever", 871 "where", 872 "while", 873 "window", 874 "with", 875 "within", 876 "without", 877 "work", 878 "year", 879 "yes", 880 "zone", 881 } 882 883 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 884 from_tz = expression.args.get("source_tz") 885 to_tz = expression.args.get("target_tz") 886 datetime = expression.args.get("timestamp") 887 options = expression.args.get("options") 888 889 return self.func("CONVERT_TZ", datetime, from_tz, to_tz, options) 890 891 def if_sql(self, expression: exp.If) -> str: 892 this = self.sql(expression, "this") 893 true = self.sql(expression, "true") 894 false = self.sql(expression, "false") 895 return f"IF {this} THEN {true} ELSE {false} ENDIF" 896 897 # https://docs.exasol.com/db/latest/sql/open_schema.htm 898 def use_sql(self, expression: exp.Use) -> str: 899 kind = expression.args.get("kind") 900 if kind and self.sql(kind).upper() != "SCHEMA": 901 self.unsupported(f"'USE {self.sql(kind)}' is not supported in Exasol") 902 return super().use_sql(expression) 903 this = self.sql(expression, "this") 904 return f"OPEN SCHEMA {this}" 905 906 # https://docs.exasol.com/db/latest/sql_references/metadata/metadata_system_tables.htm 907 def show_sql(self, expression: exp.Show) -> str: 908 if expression.name == "TABLES": 909 db_name = expression.text("db") 910 schema_filter: exp.Expression = ( 911 exp.Literal.string(db_name.upper()) if db_name else exp.CurrentSchema() 912 ) 913 select = ( 914 exp.select(exp.column("TABLE_NAME")) 915 .from_(exp.table_("EXA_ALL_TABLES", db="SYS")) 916 .where(exp.column("TABLE_SCHEMA").eq(schema_filter)) 917 ) 918 return self.sql(select) 919 920 return super().show_sql(expression) 921 922 def collate_sql(self, expression: exp.Collate) -> str: 923 return self.sql(expression.this) 924 925 def jsonextract_sql(self, expression: exp.JSONExtract) -> str: 926 sql = self.func( 927 "JSON_EXTRACT", expression.this, expression.expression, *expression.expressions 928 ) 929 930 emits = self.sql(expression, "emits") 931 if emits: 932 sql = f"{sql} EMITS {emits}" 933 934 return sql 935 936 @unsupported_args("flag") 937 def regexplike_sql(self, expression: exp.RegexpLike) -> str: 938 if not expression.args.get("full_match"): 939 pattern = expression.expression 940 if pattern.is_string: 941 expression.set("expression", exp.Literal.string(f".*{pattern.name}.*")) 942 else: 943 expression.set( 944 "expression", 945 exp.Paren( 946 this=exp.Concat( 947 expressions=[ 948 exp.Literal.string(".*"), 949 pattern, 950 exp.Literal.string(".*"), 951 ] 952 ) 953 ), 954 ) 955 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.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.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.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 =
{'authorization', 'plus', 'iterate', 'go', 'grouping', 'limit', 'join', 'execute', 'get', 'current_cluster_uid', 'dlurlpath', 'domain', 'modifies', 'create', 'descriptor', 'of', 'hashtype_format', 'file', 'asc', 'privileges', 'cardinality', 'as', 'no', 'localtimestamp', 'boolean', 'having', 'left', 'random', 'real', 'each', 'double', 'read', 'sql_date', 'exists', 'varchar', 'usage', 'false', 'start', 'full', 'into', 'instance', 'authid', 'current_user', 'group_concat', 'minus', 'numeric', 'system', 'inout', 'session_user', 'allocate', 'default', 'specific', 'constraint', 'hour', 'datetime_interval_precision', 'module', 'constraint_state_default', 'impersonate', 'first', 'both', 'exception', 'systimestamp', 'leading', 'any', 'restore', 'invoker', 'without', 'window', 'sysdate', 'update', 'enabled', 'implementation', 'current_date', 'overlay', 'others', 'log', 'national', 'placing', 'state', 'output', 'order', 'security', 'sql_preprocessor_script', 'character', 'overlaps', 'ref', 'transforms', 'append', 'sessiontimezone', 'timezone_hour', 'subtype', 'sequence', 'characteristics', 'dynamic_function_code', 'connect_by_root', 'asensitive', 'begin', 'return', 'using', 'following', 'key_type', 'select', 'work', 'assertion', 'bool', 'groups', 'right', 'all', 'treat', 'indicator', 'exit', 'corresponding', 'cursor', 'sql_char', 'array', 'collate', 'elseif', 'true', 'binary', 'map', 'view', 'routine', 'between', 'text', 'by', 'nchar', 'current_timestamp', 'large', 'referencing', 'preceding', 'nologging', 'export', 'structure', 'alter', 'dbtimezone', 'sql_smallint', 'or', 'endif', 'parameter_specific_catalog', 'chain', 'high', 'savepoint', 'column', 'decimal', 'collation_name', 'current_role', 'hashtype', 'release', 'drop', 'unknown', 'import', 'bigint', 'disable', 'set', 'sql', 'sql_bit', 'checked', 'nls_numeric_characters', 'varray', 'under', 'trailing', 'merge', 'values', 'sensitive', 'scope_user', 'dec', 'current_session', 'instantiable', 'current_time', 'last', 'rollup', 'final', 'sql_timestamp', 'escape', 'ldap', 'deterministic', 'collation_schema', 'unique', 'low', 'preferring', 'delete', 'if', 'index', 'immediate', 'deferred', 'dynamic_function', 'current_cluster', 'transaction', 'inner', 'longvarchar', 'style', 'data', 'not', 'extract', 'insensitive', 'modify', 'nvarchar', 'timezone_minute', 'system_user', 'dynamic', 'datalink', 'do', 'in', 'definer', 'relative', 'case', 'identity', 'sql_integer', 'attribute', 'timestamp', 'substring', 'end-exec', 'object', 'ifnull', 'input', 'loop', 'current', 'cascade', 'external', 'sql_type_date', 'sql_type_timestamp', 'defined', 'constant', 'add', 'until', 'equals', 'sql_varchar', 'desc', 'refresh', 'time', 'commit', 'describe', 'errors', 'yes', 'sqlwarning', 'static', 'default_like_escape_character', 'insert', 'off', 'returned_octet_length', 'collation_catalog', 'rename', 'match', 'none', 'qualify', 'declare', 'parameter_specific_name', 'forall', 'parquet', 'script', 'interval', 'convert', 'fetch', 'restrict', 'out', 'value', 'sqlexception', 'emits', 'sqlstate', 'level', 'then', 'exec', 'current_path', 'enforce', 'locator', 'similar', 'fbv', 'options', 'permission', 'mod', 'to', 'union', 'space', 'before', 'dispatch', 'user', 'character_set_catalog', 'constructor', 'repeat', 'separator', 'sql_bigint', 'is', 'nclob', 'sql_float', 'revoke', 'session', 'csv', 'at', 'option', 'rows', 'key_member', 'temporary', 'cycle', 'range', 'after', 'sql_numeric', 'connect_by_isleaf', 'current_schema', 'names', 'connect_by_iscycle', 'shortint', 'deallocate', 'trigger', 'result', 'year', 'byte', 'inverse', 'cascaded', 'sql_double', 'close', 'self', 'leave', 'section', 'contains', 'check', 'fs', 'zone', 'dlurlserver', 'scroll', 'dlurlcomplete', 'lateral', 'nullif', 'character_set_schema', 'schema', 'global', 'rowtype', 'sql_tinyint', 'casespecific', 'cube', 'matched', 'ordinality', 'derived', 'second', 'translation', 'bit', 'integrity', 'path', 'within', 'prepare', 'nls_first_day_of_week', 'unlink', 'rollback', 'like', 'table', 'row', 'int', 'natural', 'with', 'new', 'action', 'verify', 'dlurlpathonly', 'open', 'character_set_name', 'group', 'truncate', 'sql_decimal', 'blob', 'found', 'float', 'references', 'catalog', 'statement', 'procedure', 'localtime', 'called', 'returns', 'granted', 'constraints', 'outer', 'tinyint', 'disconnect', 'except', 'sql_real', 'overriding', 'some', 'datetime_interval_code', 'coalesce', 'only', 'control', 'generated', 'regexp_like', 'sql_longvarchar', 'replace', 'method', 'parameter', 'clob', 'nvarchar2', 'reads', 'else', 'cs', 'selective', 'sets', 'while', 'smallint', 'transform', 'listagg', 'distinct', 'null', 'grant', 'end', 'cast', 'integer', 'collation', 'profile', 'where', 'free', 'nocycle', 'blocked', 'pad', 'month', 'recovery', 'connection', 'hold', 'dlvalue', 'from', 'disabled', 'unnest', 'continue', 'current_statement', 'elsif', 'trim', 'search', 'specifictype', 'absolute', 'ordering', 'recursive', 'varchar2', 'goto', 'deref', 'condition', 'intersect', 'parameter_specific_schema', 'dlurlscheme', 'minute', 'parallel_enable', 'on', 'nls_timestamp_format', 'nls_date_language', 'over', 'prior', 'format', 'day', 'deferrable', 'are', 'call', 'old', 'function', 'nls_date_format', 'when', 'for', 'number', 'scope', 'partial', 'returned_length', 'preserve', 'char', 'force', 'source', 'general', 'geometry', 'whenever', 'and', 'next', 'enable'}
883 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 884 from_tz = expression.args.get("source_tz") 885 to_tz = expression.args.get("target_tz") 886 datetime = expression.args.get("timestamp") 887 options = expression.args.get("options") 888 889 return self.func("CONVERT_TZ", datetime, from_tz, to_tz, options)
898 def use_sql(self, expression: exp.Use) -> str: 899 kind = expression.args.get("kind") 900 if kind and self.sql(kind).upper() != "SCHEMA": 901 self.unsupported(f"'USE {self.sql(kind)}' is not supported in Exasol") 902 return super().use_sql(expression) 903 this = self.sql(expression, "this") 904 return f"OPEN SCHEMA {this}"
907 def show_sql(self, expression: exp.Show) -> str: 908 if expression.name == "TABLES": 909 db_name = expression.text("db") 910 schema_filter: exp.Expression = ( 911 exp.Literal.string(db_name.upper()) if db_name else exp.CurrentSchema() 912 ) 913 select = ( 914 exp.select(exp.column("TABLE_NAME")) 915 .from_(exp.table_("EXA_ALL_TABLES", db="SYS")) 916 .where(exp.column("TABLE_SCHEMA").eq(schema_filter)) 917 ) 918 return self.sql(select) 919 920 return super().show_sql(expression)
@unsupported_args('flag')
def
regexplike_sql(self, expression: sqlglot.expressions.core.RegexpLike) -> str:
936 @unsupported_args("flag") 937 def regexplike_sql(self, expression: exp.RegexpLike) -> str: 938 if not expression.args.get("full_match"): 939 pattern = expression.expression 940 if pattern.is_string: 941 expression.set("expression", exp.Literal.string(f".*{pattern.name}.*")) 942 else: 943 expression.set( 944 "expression", 945 exp.Paren( 946 this=exp.Concat( 947 expressions=[ 948 exp.Literal.string(".*"), 949 pattern, 950 exp.Literal.string(".*"), 951 ] 952 ) 953 ), 954 ) 955 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
- 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
- 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
- distribute_sql
- sort_sql
- ordered_sql
- matchrecognizemeasure_sql
- matchrecognize_sql
- query_modifiers
- options_modifier
- for_modifiers
- 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
- 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
- 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
- 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
- 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