sqlglot 27.6.0__py3-none-any.whl → 27.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sqlglot/_version.py +2 -2
- sqlglot/dialects/bigquery.py +40 -5
- sqlglot/dialects/clickhouse.py +27 -8
- sqlglot/dialects/dialect.py +10 -2
- sqlglot/dialects/doris.py +43 -2
- sqlglot/dialects/dremio.py +24 -3
- sqlglot/dialects/duckdb.py +32 -3
- sqlglot/dialects/exasol.py +25 -29
- sqlglot/dialects/singlestore.py +28 -1
- sqlglot/dialects/snowflake.py +1 -1
- sqlglot/dialects/spark.py +1 -0
- sqlglot/dialects/teradata.py +58 -0
- sqlglot/expressions.py +58 -1
- sqlglot/generator.py +21 -2
- sqlglot/optimizer/annotate_types.py +4 -1
- sqlglot/optimizer/merge_subqueries.py +4 -0
- sqlglot/optimizer/qualify_tables.py +0 -8
- sqlglot/parser.py +29 -5
- {sqlglot-27.6.0.dist-info → sqlglot-27.7.0.dist-info}/METADATA +1 -1
- {sqlglot-27.6.0.dist-info → sqlglot-27.7.0.dist-info}/RECORD +23 -23
- {sqlglot-27.6.0.dist-info → sqlglot-27.7.0.dist-info}/WHEEL +0 -0
- {sqlglot-27.6.0.dist-info → sqlglot-27.7.0.dist-info}/licenses/LICENSE +0 -0
- {sqlglot-27.6.0.dist-info → sqlglot-27.7.0.dist-info}/top_level.txt +0 -0
sqlglot/_version.py
CHANGED
sqlglot/dialects/bigquery.py
CHANGED
|
@@ -481,10 +481,20 @@ class BigQuery(Dialect):
|
|
|
481
481
|
exp.BitwiseOrAgg: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
|
|
482
482
|
exp.BitwiseXorAgg: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
|
|
483
483
|
exp.BitwiseCountAgg: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
|
|
484
|
+
exp.ByteLength: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
|
|
485
|
+
exp.ByteString: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BINARY),
|
|
486
|
+
exp.CodePointsToString: lambda self, e: self._annotate_with_type(
|
|
487
|
+
e, exp.DataType.Type.VARCHAR
|
|
488
|
+
),
|
|
484
489
|
exp.Concat: _annotate_concat,
|
|
485
490
|
exp.Corr: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
|
|
486
491
|
exp.CovarPop: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
|
|
487
492
|
exp.CovarSamp: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
|
|
493
|
+
exp.DateFromUnixDate: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DATE),
|
|
494
|
+
exp.DateTrunc: lambda self, e: self._annotate_by_args(e, "this"),
|
|
495
|
+
exp.GenerateTimestampArray: lambda self, e: self._annotate_with_type(
|
|
496
|
+
e, exp.DataType.build("ARRAY<TIMESTAMP>", dialect="bigquery")
|
|
497
|
+
),
|
|
488
498
|
exp.JSONArray: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.JSON),
|
|
489
499
|
exp.JSONExtractScalar: lambda self, e: self._annotate_with_type(
|
|
490
500
|
e, exp.DataType.Type.VARCHAR
|
|
@@ -494,6 +504,9 @@ class BigQuery(Dialect):
|
|
|
494
504
|
),
|
|
495
505
|
exp.JSONType: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.VARCHAR),
|
|
496
506
|
exp.Lag: lambda self, e: self._annotate_by_args(e, "this", "default"),
|
|
507
|
+
exp.ParseTime: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.TIME),
|
|
508
|
+
exp.ParseDatetime: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DATETIME),
|
|
509
|
+
exp.Reverse: lambda self, e: self._annotate_by_args(e, "this"),
|
|
497
510
|
exp.SHA: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BINARY),
|
|
498
511
|
exp.SHA2: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BINARY),
|
|
499
512
|
exp.Sign: lambda self, e: self._annotate_by_args(e, "this"),
|
|
@@ -501,6 +514,10 @@ class BigQuery(Dialect):
|
|
|
501
514
|
exp.TimestampFromParts: lambda self, e: self._annotate_with_type(
|
|
502
515
|
e, exp.DataType.Type.DATETIME
|
|
503
516
|
),
|
|
517
|
+
exp.TimestampTrunc: lambda self, e: self._annotate_by_args(e, "this"),
|
|
518
|
+
exp.TimeFromParts: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.TIME),
|
|
519
|
+
exp.TsOrDsToTime: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.TIME),
|
|
520
|
+
exp.TimeTrunc: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.TIME),
|
|
504
521
|
exp.Unicode: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
|
|
505
522
|
}
|
|
506
523
|
|
|
@@ -621,7 +638,13 @@ class BigQuery(Dialect):
|
|
|
621
638
|
"PARSE_DATE": lambda args: build_formatted_time(exp.StrToDate, "bigquery")(
|
|
622
639
|
[seq_get(args, 1), seq_get(args, 0)]
|
|
623
640
|
),
|
|
641
|
+
"PARSE_TIME": lambda args: build_formatted_time(exp.ParseTime, "bigquery")(
|
|
642
|
+
[seq_get(args, 1), seq_get(args, 0)]
|
|
643
|
+
),
|
|
624
644
|
"PARSE_TIMESTAMP": _build_parse_timestamp,
|
|
645
|
+
"PARSE_DATETIME": lambda args: build_formatted_time(exp.ParseDatetime, "bigquery")(
|
|
646
|
+
[seq_get(args, 1), seq_get(args, 0)]
|
|
647
|
+
),
|
|
625
648
|
"REGEXP_CONTAINS": exp.RegexpLike.from_arg_list,
|
|
626
649
|
"REGEXP_EXTRACT": _build_regexp_extract(exp.RegexpExtract),
|
|
627
650
|
"REGEXP_SUBSTR": _build_regexp_extract(exp.RegexpExtract),
|
|
@@ -652,6 +675,8 @@ class BigQuery(Dialect):
|
|
|
652
675
|
"TO_JSON_STRING": exp.JSONFormat.from_arg_list,
|
|
653
676
|
"FORMAT_DATETIME": _build_format_time(exp.TsOrDsToDatetime),
|
|
654
677
|
"FORMAT_TIMESTAMP": _build_format_time(exp.TsOrDsToTimestamp),
|
|
678
|
+
"FORMAT_TIME": _build_format_time(exp.TsOrDsToTime),
|
|
679
|
+
"WEEK": lambda args: exp.WeekStart(this=exp.var(seq_get(args, 0))),
|
|
655
680
|
}
|
|
656
681
|
|
|
657
682
|
FUNCTION_PARSERS = {
|
|
@@ -994,6 +1019,13 @@ class BigQuery(Dialect):
|
|
|
994
1019
|
EXCEPT_INTERSECT_SUPPORT_ALL_CLAUSE = False
|
|
995
1020
|
SUPPORTS_UNIX_SECONDS = True
|
|
996
1021
|
|
|
1022
|
+
TS_OR_DS_TYPES = (
|
|
1023
|
+
exp.TsOrDsToDatetime,
|
|
1024
|
+
exp.TsOrDsToTimestamp,
|
|
1025
|
+
exp.TsOrDsToTime,
|
|
1026
|
+
exp.TsOrDsToDate,
|
|
1027
|
+
)
|
|
1028
|
+
|
|
997
1029
|
TRANSFORMS = {
|
|
998
1030
|
**generator.Generator.TRANSFORMS,
|
|
999
1031
|
exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"),
|
|
@@ -1022,6 +1054,7 @@ class BigQuery(Dialect):
|
|
|
1022
1054
|
exp.DateSub: date_add_interval_sql("DATE", "SUB"),
|
|
1023
1055
|
exp.DatetimeAdd: date_add_interval_sql("DATETIME", "ADD"),
|
|
1024
1056
|
exp.DatetimeSub: date_add_interval_sql("DATETIME", "SUB"),
|
|
1057
|
+
exp.DateFromUnixDate: rename_func("DATE_FROM_UNIX_DATE"),
|
|
1025
1058
|
exp.FromTimeZone: lambda self, e: self.func(
|
|
1026
1059
|
"DATETIME", self.func("TIMESTAMP", e.this, e.args.get("zone")), "'UTC'"
|
|
1027
1060
|
),
|
|
@@ -1059,6 +1092,10 @@ class BigQuery(Dialect):
|
|
|
1059
1092
|
exp.RegexpLike: rename_func("REGEXP_CONTAINS"),
|
|
1060
1093
|
exp.ReturnsProperty: _returnsproperty_sql,
|
|
1061
1094
|
exp.Rollback: lambda *_: "ROLLBACK TRANSACTION",
|
|
1095
|
+
exp.ParseTime: lambda self, e: self.func("PARSE_TIME", self.format_time(e), e.this),
|
|
1096
|
+
exp.ParseDatetime: lambda self, e: self.func(
|
|
1097
|
+
"PARSE_DATETIME", self.format_time(e), e.this
|
|
1098
|
+
),
|
|
1062
1099
|
exp.Select: transforms.preprocess(
|
|
1063
1100
|
[
|
|
1064
1101
|
transforms.explode_projection_to_unnest(),
|
|
@@ -1297,14 +1334,12 @@ class BigQuery(Dialect):
|
|
|
1297
1334
|
func_name = "FORMAT_DATETIME"
|
|
1298
1335
|
elif isinstance(this, exp.TsOrDsToTimestamp):
|
|
1299
1336
|
func_name = "FORMAT_TIMESTAMP"
|
|
1337
|
+
elif isinstance(this, exp.TsOrDsToTime):
|
|
1338
|
+
func_name = "FORMAT_TIME"
|
|
1300
1339
|
else:
|
|
1301
1340
|
func_name = "FORMAT_DATE"
|
|
1302
1341
|
|
|
1303
|
-
time_expr = (
|
|
1304
|
-
this
|
|
1305
|
-
if isinstance(this, (exp.TsOrDsToDatetime, exp.TsOrDsToTimestamp, exp.TsOrDsToDate))
|
|
1306
|
-
else expression
|
|
1307
|
-
)
|
|
1342
|
+
time_expr = this if isinstance(this, self.TS_OR_DS_TYPES) else expression
|
|
1308
1343
|
return self.func(
|
|
1309
1344
|
func_name, self.format_time(expression), time_expr.this, expression.args.get("zone")
|
|
1310
1345
|
)
|
sqlglot/dialects/clickhouse.py
CHANGED
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
import typing as t
|
|
3
3
|
import datetime
|
|
4
4
|
from sqlglot import exp, generator, parser, tokens
|
|
5
|
+
from sqlglot._typing import E
|
|
5
6
|
from sqlglot.dialects.dialect import (
|
|
6
7
|
Dialect,
|
|
7
8
|
NormalizationStrategy,
|
|
@@ -31,14 +32,19 @@ from sqlglot.generator import unsupported_args
|
|
|
31
32
|
DATEΤΙΜΕ_DELTA = t.Union[exp.DateAdd, exp.DateDiff, exp.DateSub, exp.TimestampSub, exp.TimestampAdd]
|
|
32
33
|
|
|
33
34
|
|
|
34
|
-
def
|
|
35
|
-
|
|
35
|
+
def _build_datetime_format(
|
|
36
|
+
expr_type: t.Type[E],
|
|
37
|
+
) -> t.Callable[[t.List], E]:
|
|
38
|
+
def _builder(args: t.List) -> E:
|
|
39
|
+
expr = build_formatted_time(expr_type, "clickhouse")(args)
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
timezone = seq_get(args, 2)
|
|
42
|
+
if timezone:
|
|
43
|
+
expr.set("zone", timezone)
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
return expr
|
|
46
|
+
|
|
47
|
+
return _builder
|
|
42
48
|
|
|
43
49
|
|
|
44
50
|
def _unix_to_time_sql(self: ClickHouse.Generator, expression: exp.UnixToTime) -> str:
|
|
@@ -310,16 +316,17 @@ class ClickHouse(Dialect):
|
|
|
310
316
|
"DATEADD": build_date_delta(exp.DateAdd, default_unit=None),
|
|
311
317
|
"DATE_DIFF": build_date_delta(exp.DateDiff, default_unit=None, supports_timezone=True),
|
|
312
318
|
"DATEDIFF": build_date_delta(exp.DateDiff, default_unit=None, supports_timezone=True),
|
|
313
|
-
"DATE_FORMAT":
|
|
319
|
+
"DATE_FORMAT": _build_datetime_format(exp.TimeToStr),
|
|
314
320
|
"DATE_SUB": build_date_delta(exp.DateSub, default_unit=None),
|
|
315
321
|
"DATESUB": build_date_delta(exp.DateSub, default_unit=None),
|
|
316
|
-
"FORMATDATETIME":
|
|
322
|
+
"FORMATDATETIME": _build_datetime_format(exp.TimeToStr),
|
|
317
323
|
"JSONEXTRACTSTRING": build_json_extract_path(
|
|
318
324
|
exp.JSONExtractScalar, zero_based_indexing=False
|
|
319
325
|
),
|
|
320
326
|
"LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True),
|
|
321
327
|
"MAP": parser.build_var_map,
|
|
322
328
|
"MATCH": exp.RegexpLike.from_arg_list,
|
|
329
|
+
"PARSEDATETIME": _build_datetime_format(exp.ParseDatetime),
|
|
323
330
|
"RANDCANONICAL": exp.Rand.from_arg_list,
|
|
324
331
|
"STR_TO_DATE": _build_str_to_date,
|
|
325
332
|
"TUPLE": exp.Struct.from_arg_list,
|
|
@@ -1141,6 +1148,7 @@ class ClickHouse(Dialect):
|
|
|
1141
1148
|
exp.Levenshtein: unsupported_args("ins_cost", "del_cost", "sub_cost", "max_dist")(
|
|
1142
1149
|
rename_func("editDistance")
|
|
1143
1150
|
),
|
|
1151
|
+
exp.ParseDatetime: rename_func("parseDateTime"),
|
|
1144
1152
|
}
|
|
1145
1153
|
|
|
1146
1154
|
PROPERTIES_LOCATION = {
|
|
@@ -1177,6 +1185,17 @@ class ClickHouse(Dialect):
|
|
|
1177
1185
|
exp.DataType.Type.MULTIPOLYGON,
|
|
1178
1186
|
}
|
|
1179
1187
|
|
|
1188
|
+
def offset_sql(self, expression: exp.Offset) -> str:
|
|
1189
|
+
offset = super().offset_sql(expression)
|
|
1190
|
+
|
|
1191
|
+
# OFFSET ... FETCH syntax requires a "ROW" or "ROWS" keyword
|
|
1192
|
+
# https://clickhouse.com/docs/sql-reference/statements/select/offset
|
|
1193
|
+
parent = expression.parent
|
|
1194
|
+
if isinstance(parent, exp.Select) and isinstance(parent.args.get("limit"), exp.Fetch):
|
|
1195
|
+
offset = f"{offset} ROWS"
|
|
1196
|
+
|
|
1197
|
+
return offset
|
|
1198
|
+
|
|
1180
1199
|
def strtodate_sql(self, expression: exp.StrToDate) -> str:
|
|
1181
1200
|
strtodate_sql = self.function_fallback_sql(expression)
|
|
1182
1201
|
|
sqlglot/dialects/dialect.py
CHANGED
|
@@ -654,6 +654,8 @@ class Dialect(metaclass=_Dialect):
|
|
|
654
654
|
exp.Length,
|
|
655
655
|
exp.UnixDate,
|
|
656
656
|
exp.UnixSeconds,
|
|
657
|
+
exp.UnixMicros,
|
|
658
|
+
exp.UnixMillis,
|
|
657
659
|
},
|
|
658
660
|
exp.DataType.Type.BINARY: {
|
|
659
661
|
exp.FromBase64,
|
|
@@ -674,6 +676,7 @@ class Dialect(metaclass=_Dialect):
|
|
|
674
676
|
exp.DateFromParts,
|
|
675
677
|
exp.DateStrToDate,
|
|
676
678
|
exp.DiToDate,
|
|
679
|
+
exp.LastDay,
|
|
677
680
|
exp.StrToDate,
|
|
678
681
|
exp.TimeStrToDate,
|
|
679
682
|
exp.TsOrDsToDate,
|
|
@@ -718,6 +721,9 @@ class Dialect(metaclass=_Dialect):
|
|
|
718
721
|
},
|
|
719
722
|
exp.DataType.Type.INTERVAL: {
|
|
720
723
|
exp.Interval,
|
|
724
|
+
exp.JustifyDays,
|
|
725
|
+
exp.JustifyHours,
|
|
726
|
+
exp.JustifyInterval,
|
|
721
727
|
exp.MakeInterval,
|
|
722
728
|
},
|
|
723
729
|
exp.DataType.Type.JSON: {
|
|
@@ -1650,9 +1656,11 @@ def unit_to_str(expression: exp.Expression, default: str = "DAY") -> t.Optional[
|
|
|
1650
1656
|
def unit_to_var(expression: exp.Expression, default: str = "DAY") -> t.Optional[exp.Expression]:
|
|
1651
1657
|
unit = expression.args.get("unit")
|
|
1652
1658
|
|
|
1653
|
-
if isinstance(unit, (exp.Var, exp.Placeholder)):
|
|
1659
|
+
if isinstance(unit, (exp.Var, exp.Placeholder, exp.WeekStart)):
|
|
1654
1660
|
return unit
|
|
1655
|
-
|
|
1661
|
+
|
|
1662
|
+
value = unit.name if unit else default
|
|
1663
|
+
return exp.Var(this=value) if value else None
|
|
1656
1664
|
|
|
1657
1665
|
|
|
1658
1666
|
@t.overload
|
sqlglot/dialects/doris.py
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
3
5
|
from sqlglot import exp
|
|
4
6
|
from sqlglot.dialects.dialect import (
|
|
5
7
|
approx_count_distinct_sql,
|
|
6
|
-
build_timestamp_trunc,
|
|
7
8
|
property_sql,
|
|
8
9
|
rename_func,
|
|
9
10
|
time_format,
|
|
10
11
|
unit_to_str,
|
|
11
12
|
)
|
|
12
13
|
from sqlglot.dialects.mysql import MySQL
|
|
14
|
+
from sqlglot.helper import seq_get
|
|
13
15
|
from sqlglot.tokens import TokenType
|
|
14
16
|
|
|
15
17
|
|
|
@@ -22,6 +24,22 @@ def _lag_lead_sql(self, expression: exp.Lag | exp.Lead) -> str:
|
|
|
22
24
|
)
|
|
23
25
|
|
|
24
26
|
|
|
27
|
+
# Accept both DATE_TRUNC(datetime, unit) and DATE_TRUNC(unit, datetime)
|
|
28
|
+
def _build_date_trunc(args: t.List[exp.Expression]) -> exp.Expression:
|
|
29
|
+
a0, a1 = seq_get(args, 0), seq_get(args, 1)
|
|
30
|
+
|
|
31
|
+
def _is_unit_like(e: exp.Expression | None) -> bool:
|
|
32
|
+
if not (isinstance(e, exp.Literal) and e.is_string):
|
|
33
|
+
return False
|
|
34
|
+
text = e.this
|
|
35
|
+
return not any(ch.isdigit() for ch in text)
|
|
36
|
+
|
|
37
|
+
# Determine which argument is the unit
|
|
38
|
+
unit, this = (a0, a1) if _is_unit_like(a0) else (a1, a0)
|
|
39
|
+
|
|
40
|
+
return exp.TimestampTrunc(this=this, unit=unit)
|
|
41
|
+
|
|
42
|
+
|
|
25
43
|
class Doris(MySQL):
|
|
26
44
|
DATE_FORMAT = "'yyyy-MM-dd'"
|
|
27
45
|
DATEINT_FORMAT = "'yyyyMMdd'"
|
|
@@ -31,7 +49,7 @@ class Doris(MySQL):
|
|
|
31
49
|
FUNCTIONS = {
|
|
32
50
|
**MySQL.Parser.FUNCTIONS,
|
|
33
51
|
"COLLECT_SET": exp.ArrayUniqueAgg.from_arg_list,
|
|
34
|
-
"DATE_TRUNC":
|
|
52
|
+
"DATE_TRUNC": _build_date_trunc,
|
|
35
53
|
"MONTHS_ADD": exp.AddMonths.from_arg_list,
|
|
36
54
|
"REGEXP": exp.RegexpLike.from_arg_list,
|
|
37
55
|
"TO_DATE": exp.TsOrDsToDate.from_arg_list,
|
|
@@ -40,6 +58,9 @@ class Doris(MySQL):
|
|
|
40
58
|
FUNCTION_PARSERS = MySQL.Parser.FUNCTION_PARSERS.copy()
|
|
41
59
|
FUNCTION_PARSERS.pop("GROUP_CONCAT")
|
|
42
60
|
|
|
61
|
+
NO_PAREN_FUNCTIONS = MySQL.Parser.NO_PAREN_FUNCTIONS.copy()
|
|
62
|
+
NO_PAREN_FUNCTIONS.pop(TokenType.CURRENT_DATE)
|
|
63
|
+
|
|
43
64
|
PROPERTY_PARSERS = {
|
|
44
65
|
**MySQL.Parser.PROPERTY_PARSERS,
|
|
45
66
|
"PROPERTIES": lambda self: self._parse_wrapped_properties(),
|
|
@@ -111,6 +132,7 @@ class Doris(MySQL):
|
|
|
111
132
|
LAST_DAY_SUPPORTS_DATE_PART = False
|
|
112
133
|
VARCHAR_REQUIRES_SIZE = False
|
|
113
134
|
WITH_PROPERTIES_PREFIX = "PROPERTIES"
|
|
135
|
+
RENAME_TABLE_WITH_DB = False
|
|
114
136
|
|
|
115
137
|
TYPE_MAPPING = {
|
|
116
138
|
**MySQL.Generator.TYPE_MAPPING,
|
|
@@ -123,6 +145,7 @@ class Doris(MySQL):
|
|
|
123
145
|
**MySQL.Generator.PROPERTIES_LOCATION,
|
|
124
146
|
exp.UniqueKeyProperty: exp.Properties.Location.POST_SCHEMA,
|
|
125
147
|
exp.PartitionByRangeProperty: exp.Properties.Location.POST_SCHEMA,
|
|
148
|
+
exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA,
|
|
126
149
|
}
|
|
127
150
|
|
|
128
151
|
CAST_MAPPING = {}
|
|
@@ -137,6 +160,7 @@ class Doris(MySQL):
|
|
|
137
160
|
exp.ArrayAgg: rename_func("COLLECT_LIST"),
|
|
138
161
|
exp.ArrayToString: rename_func("ARRAY_JOIN"),
|
|
139
162
|
exp.ArrayUniqueAgg: rename_func("COLLECT_SET"),
|
|
163
|
+
exp.CurrentDate: lambda self, _: self.func("CURRENT_DATE"),
|
|
140
164
|
exp.CurrentTimestamp: lambda self, _: self.func("NOW"),
|
|
141
165
|
exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, unit_to_str(e)),
|
|
142
166
|
exp.GroupConcat: lambda self, e: self.func(
|
|
@@ -683,3 +707,20 @@ class Doris(MySQL):
|
|
|
683
707
|
# Handle both static and dynamic partition definitions
|
|
684
708
|
create_sql = ", ".join(self.sql(e) for e in create_expressions)
|
|
685
709
|
return f"PARTITION BY RANGE ({partition_expressions}) ({create_sql})"
|
|
710
|
+
|
|
711
|
+
def partitionedbyproperty_sql(self, expression: exp.PartitionedByProperty) -> str:
|
|
712
|
+
node = expression.this
|
|
713
|
+
if isinstance(node, exp.Schema):
|
|
714
|
+
parts = ", ".join(self.sql(e) for e in node.expressions)
|
|
715
|
+
return f"PARTITION BY ({parts})"
|
|
716
|
+
return f"PARTITION BY ({self.sql(node)})"
|
|
717
|
+
|
|
718
|
+
def table_sql(self, expression: exp.Table, sep: str = " AS ") -> str:
|
|
719
|
+
"""Override table_sql to avoid AS keyword in UPDATE and DELETE statements."""
|
|
720
|
+
ancestor = expression.find_ancestor(exp.Update, exp.Delete, exp.Select)
|
|
721
|
+
if not isinstance(ancestor, exp.Select):
|
|
722
|
+
sep = " "
|
|
723
|
+
return super().table_sql(expression, sep=sep)
|
|
724
|
+
|
|
725
|
+
def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
|
|
726
|
+
return super().alterrename_sql(expression, include_to=False)
|
sqlglot/dialects/dremio.py
CHANGED
|
@@ -42,30 +42,51 @@ class Dremio(Dialect):
|
|
|
42
42
|
TIME_MAPPING = {
|
|
43
43
|
# year
|
|
44
44
|
"YYYY": "%Y",
|
|
45
|
+
"yyyy": "%Y",
|
|
45
46
|
"YY": "%y",
|
|
47
|
+
"yy": "%y",
|
|
46
48
|
# month / day
|
|
47
49
|
"MM": "%m",
|
|
50
|
+
"mm": "%m",
|
|
48
51
|
"MON": "%b",
|
|
52
|
+
"mon": "%b",
|
|
49
53
|
"MONTH": "%B",
|
|
54
|
+
"month": "%B",
|
|
50
55
|
"DDD": "%j",
|
|
56
|
+
"ddd": "%j",
|
|
51
57
|
"DD": "%d",
|
|
58
|
+
"dd": "%d",
|
|
52
59
|
"DY": "%a",
|
|
60
|
+
"dy": "%a",
|
|
53
61
|
"DAY": "%A",
|
|
62
|
+
"day": "%A",
|
|
54
63
|
# hours / minutes / seconds
|
|
55
64
|
"HH24": "%H",
|
|
65
|
+
"hh24": "%H",
|
|
56
66
|
"HH12": "%I",
|
|
57
|
-
"
|
|
67
|
+
"hh12": "%I",
|
|
68
|
+
"HH": "%I",
|
|
69
|
+
"hh": "%I", # 24- / 12-hour
|
|
58
70
|
"MI": "%M",
|
|
71
|
+
"mi": "%M",
|
|
59
72
|
"SS": "%S",
|
|
73
|
+
"ss": "%S",
|
|
60
74
|
"FFF": "%f",
|
|
75
|
+
"fff": "%f",
|
|
61
76
|
"AMPM": "%p",
|
|
77
|
+
"ampm": "%p",
|
|
62
78
|
# ISO week / century etc.
|
|
63
79
|
"WW": "%W",
|
|
80
|
+
"ww": "%W",
|
|
64
81
|
"D": "%w",
|
|
82
|
+
"d": "%w",
|
|
65
83
|
"CC": "%C",
|
|
84
|
+
"cc": "%C",
|
|
66
85
|
# timezone
|
|
67
|
-
"TZD": "%Z",
|
|
68
|
-
"
|
|
86
|
+
"TZD": "%Z",
|
|
87
|
+
"tzd": "%Z", # abbreviation (UTC, PST, ...)
|
|
88
|
+
"TZO": "%z",
|
|
89
|
+
"tzo": "%z", # numeric offset (+0200)
|
|
69
90
|
}
|
|
70
91
|
|
|
71
92
|
class Parser(parser.Parser):
|
sqlglot/dialects/duckdb.py
CHANGED
|
@@ -396,6 +396,7 @@ class DuckDB(Dialect):
|
|
|
396
396
|
|
|
397
397
|
FUNCTIONS = {
|
|
398
398
|
**parser.Parser.FUNCTIONS,
|
|
399
|
+
"ANY_VALUE": lambda args: exp.IgnoreNulls(this=exp.AnyValue.from_arg_list(args)),
|
|
399
400
|
"ARRAY_REVERSE_SORT": _build_sort_array_desc,
|
|
400
401
|
"ARRAY_SORT": exp.SortArray.from_arg_list,
|
|
401
402
|
"DATEDIFF": _build_date_diff,
|
|
@@ -920,6 +921,7 @@ class DuckDB(Dialect):
|
|
|
920
921
|
PROPERTIES_LOCATION[exp.LikeProperty] = exp.Properties.Location.POST_SCHEMA
|
|
921
922
|
PROPERTIES_LOCATION[exp.TemporaryProperty] = exp.Properties.Location.POST_CREATE
|
|
922
923
|
PROPERTIES_LOCATION[exp.ReturnsProperty] = exp.Properties.Location.POST_ALIAS
|
|
924
|
+
PROPERTIES_LOCATION[exp.SequenceProperties] = exp.Properties.Location.POST_EXPRESSION
|
|
923
925
|
|
|
924
926
|
IGNORE_RESPECT_NULLS_WINDOW_FUNCTIONS = (
|
|
925
927
|
exp.FirstValue,
|
|
@@ -1136,9 +1138,10 @@ class DuckDB(Dialect):
|
|
|
1136
1138
|
|
|
1137
1139
|
# If BQ's UNNEST is aliased, we transform it from a column alias to a table alias in DDB
|
|
1138
1140
|
alias = expression.args.get("alias")
|
|
1139
|
-
if alias:
|
|
1141
|
+
if isinstance(alias, exp.TableAlias):
|
|
1140
1142
|
expression.set("alias", None)
|
|
1141
|
-
|
|
1143
|
+
if alias.columns:
|
|
1144
|
+
alias = exp.TableAlias(this=seq_get(alias.columns, 0))
|
|
1142
1145
|
|
|
1143
1146
|
unnest_sql = super().unnest_sql(expression)
|
|
1144
1147
|
select = exp.Select(expressions=[unnest_sql]).subquery(alias)
|
|
@@ -1152,7 +1155,9 @@ class DuckDB(Dialect):
|
|
|
1152
1155
|
# window functions that accept it e.g. FIRST_VALUE(... IGNORE NULLS) OVER (...)
|
|
1153
1156
|
return super().ignorenulls_sql(expression)
|
|
1154
1157
|
|
|
1155
|
-
|
|
1158
|
+
if not isinstance(expression.this, exp.AnyValue):
|
|
1159
|
+
self.unsupported("IGNORE NULLS is not supported for non-window functions.")
|
|
1160
|
+
|
|
1156
1161
|
return self.sql(expression, "this")
|
|
1157
1162
|
|
|
1158
1163
|
def respectnulls_sql(self, expression: exp.RespectNulls) -> str:
|
|
@@ -1247,3 +1252,27 @@ class DuckDB(Dialect):
|
|
|
1247
1252
|
return self.sql(exp.Subquery(this=exp.Select(expressions=[posexplode_sql])))
|
|
1248
1253
|
|
|
1249
1254
|
return posexplode_sql
|
|
1255
|
+
|
|
1256
|
+
def addmonths_sql(self, expression: exp.AddMonths) -> str:
|
|
1257
|
+
this = expression.this
|
|
1258
|
+
|
|
1259
|
+
if not this.type:
|
|
1260
|
+
from sqlglot.optimizer.annotate_types import annotate_types
|
|
1261
|
+
|
|
1262
|
+
this = annotate_types(this, dialect=self.dialect)
|
|
1263
|
+
|
|
1264
|
+
if this.is_type(*exp.DataType.TEXT_TYPES):
|
|
1265
|
+
this = exp.Cast(this=this, to=exp.DataType(this=exp.DataType.Type.TIMESTAMP))
|
|
1266
|
+
|
|
1267
|
+
func = self.func(
|
|
1268
|
+
"DATE_ADD", this, exp.Interval(this=expression.expression, unit=exp.var("MONTH"))
|
|
1269
|
+
)
|
|
1270
|
+
|
|
1271
|
+
# DuckDB's DATE_ADD function returns TIMESTAMP/DATETIME by default, even when the input is DATE
|
|
1272
|
+
# To match for example Snowflake's ADD_MONTHS behavior (which preserves the input type)
|
|
1273
|
+
# We need to cast the result back to the original type when the input is DATE or TIMESTAMPTZ
|
|
1274
|
+
# Example: ADD_MONTHS('2023-01-31'::date, 1) should return DATE, not TIMESTAMP
|
|
1275
|
+
if this.is_type(exp.DataType.Type.DATE, exp.DataType.Type.TIMESTAMPTZ):
|
|
1276
|
+
return self.sql(exp.Cast(this=func, to=this.type))
|
|
1277
|
+
|
|
1278
|
+
return self.sql(func)
|
sqlglot/dialects/exasol.py
CHANGED
|
@@ -28,6 +28,16 @@ def _sha2_sql(self: Exasol.Generator, expression: exp.SHA2) -> str:
|
|
|
28
28
|
return self.func(func_name, expression.this)
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
def _date_diff_sql(self: Exasol.Generator, expression: exp.DateDiff | exp.TsOrDsDiff) -> str:
|
|
32
|
+
unit = expression.text("unit").upper() or "DAY"
|
|
33
|
+
|
|
34
|
+
if unit not in DATE_UNITS:
|
|
35
|
+
self.unsupported(f"'{unit}' is not supported in Exasol.")
|
|
36
|
+
return self.function_fallback_sql(expression)
|
|
37
|
+
|
|
38
|
+
return self.func(f"{unit}S_BETWEEN", expression.this, expression.expression)
|
|
39
|
+
|
|
40
|
+
|
|
31
41
|
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/trunc%5Bate%5D%20(datetime).htm
|
|
32
42
|
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/trunc%5Bate%5D%20(number).htm
|
|
33
43
|
def _build_trunc(args: t.List[exp.Expression], dialect: DialectType) -> exp.Expression:
|
|
@@ -59,6 +69,9 @@ def _build_nullifzero(args: t.List) -> exp.If:
|
|
|
59
69
|
return exp.If(this=cond, true=exp.Null(), false=seq_get(args, 0))
|
|
60
70
|
|
|
61
71
|
|
|
72
|
+
DATE_UNITS = {"DAY", "WEEK", "MONTH", "YEAR", "HOUR", "MINUTE", "SECOND"}
|
|
73
|
+
|
|
74
|
+
|
|
62
75
|
class Exasol(Dialect):
|
|
63
76
|
TIME_MAPPING = {
|
|
64
77
|
"yyyy": "%Y",
|
|
@@ -100,20 +113,14 @@ class Exasol(Dialect):
|
|
|
100
113
|
class Parser(parser.Parser):
|
|
101
114
|
FUNCTIONS = {
|
|
102
115
|
**parser.Parser.FUNCTIONS,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/add_hour.htm
|
|
112
|
-
"ADD_HOURS": build_date_delta(exp.DateAdd, default_unit="HOUR"),
|
|
113
|
-
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/add_minutes.htm
|
|
114
|
-
"ADD_MINUTES": build_date_delta(exp.DateAdd, default_unit="MINUTE"),
|
|
115
|
-
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/add_seconds.htm
|
|
116
|
-
"ADD_SECONDS": build_date_delta(exp.DateAdd, default_unit="SECOND"),
|
|
116
|
+
**{
|
|
117
|
+
f"ADD_{unit}S": build_date_delta(exp.DateAdd, default_unit=unit)
|
|
118
|
+
for unit in DATE_UNITS
|
|
119
|
+
},
|
|
120
|
+
**{
|
|
121
|
+
f"{unit}S_BETWEEN": build_date_delta(exp.DateDiff, default_unit=unit)
|
|
122
|
+
for unit in DATE_UNITS
|
|
123
|
+
},
|
|
117
124
|
"BIT_AND": binary_from_function(exp.BitwiseAnd),
|
|
118
125
|
"BIT_OR": binary_from_function(exp.BitwiseOr),
|
|
119
126
|
"BIT_XOR": binary_from_function(exp.BitwiseXor),
|
|
@@ -196,16 +203,6 @@ class Exasol(Dialect):
|
|
|
196
203
|
exp.DataType.Type.DATETIME: "TIMESTAMP",
|
|
197
204
|
}
|
|
198
205
|
|
|
199
|
-
DATE_ADD_FUNCTION_BY_UNIT = {
|
|
200
|
-
"DAY": "ADD_DAYS",
|
|
201
|
-
"WEEK": "ADD_WEEKS",
|
|
202
|
-
"MONTH": "ADD_MONTHS",
|
|
203
|
-
"YEAR": "ADD_YEARS",
|
|
204
|
-
"HOUR": "ADD_HOURS",
|
|
205
|
-
"MINUTE": "ADD_MINUTES",
|
|
206
|
-
"SECOND": "ADD_SECONDS",
|
|
207
|
-
}
|
|
208
|
-
|
|
209
206
|
def datatype_sql(self, expression: exp.DataType) -> str:
|
|
210
207
|
# Exasol supports a fixed default precision of 3 for TIMESTAMP WITH LOCAL TIME ZONE
|
|
211
208
|
# and does not allow specifying a different custom precision
|
|
@@ -230,8 +227,8 @@ class Exasol(Dialect):
|
|
|
230
227
|
exp.BitwiseRightShift: rename_func("BIT_RSHIFT"),
|
|
231
228
|
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/bit_xor.htm
|
|
232
229
|
exp.BitwiseXor: rename_func("BIT_XOR"),
|
|
233
|
-
|
|
234
|
-
exp.
|
|
230
|
+
exp.DateDiff: _date_diff_sql,
|
|
231
|
+
exp.TsOrDsDiff: _date_diff_sql,
|
|
235
232
|
exp.DateTrunc: lambda self, e: self.func("TRUNC", e.this, unit_to_str(e)),
|
|
236
233
|
exp.DatetimeTrunc: timestamptrunc_sql(),
|
|
237
234
|
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/edit_distance.htm#EDIT_DISTANCE
|
|
@@ -301,9 +298,8 @@ class Exasol(Dialect):
|
|
|
301
298
|
|
|
302
299
|
def dateadd_sql(self, expression: exp.DateAdd) -> str:
|
|
303
300
|
unit = expression.text("unit").upper() or "DAY"
|
|
304
|
-
|
|
305
|
-
if not func_name:
|
|
301
|
+
if unit not in DATE_UNITS:
|
|
306
302
|
self.unsupported(f"'{unit}' is not supported in Exasol.")
|
|
307
303
|
return self.function_fallback_sql(expression)
|
|
308
304
|
|
|
309
|
-
return self.func(
|
|
305
|
+
return self.func(f"ADD_{unit}S", expression.this, expression.expression)
|
sqlglot/dialects/singlestore.py
CHANGED
|
@@ -2,7 +2,7 @@ from sqlglot import TokenType
|
|
|
2
2
|
import typing as t
|
|
3
3
|
|
|
4
4
|
from sqlglot import exp
|
|
5
|
-
from sqlglot.dialects.dialect import build_formatted_time
|
|
5
|
+
from sqlglot.dialects.dialect import build_formatted_time, rename_func
|
|
6
6
|
from sqlglot.dialects.mysql import MySQL
|
|
7
7
|
from sqlglot.generator import unsupported_args
|
|
8
8
|
from sqlglot.helper import seq_get
|
|
@@ -64,6 +64,8 @@ class SingleStore(MySQL):
|
|
|
64
64
|
),
|
|
65
65
|
format=MySQL.format_time(seq_get(args, 1)),
|
|
66
66
|
),
|
|
67
|
+
"UNIX_TIMESTAMP": exp.StrToUnix.from_arg_list,
|
|
68
|
+
"FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"),
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
CAST_COLUMN_OPERATORS = {TokenType.COLON_GT, TokenType.NCOLON_GT}
|
|
@@ -111,6 +113,31 @@ class SingleStore(MySQL):
|
|
|
111
113
|
exp.TryCast: unsupported_args("format", "action", "default")(
|
|
112
114
|
lambda self, e: f"{self.sql(e, 'this')} !:> {self.sql(e, 'to')}"
|
|
113
115
|
),
|
|
116
|
+
exp.StrToUnix: unsupported_args("format")(rename_func("UNIX_TIMESTAMP")),
|
|
117
|
+
exp.TimeToUnix: rename_func("UNIX_TIMESTAMP"),
|
|
118
|
+
exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
|
|
119
|
+
exp.UnixSeconds: rename_func("UNIX_TIMESTAMP"),
|
|
120
|
+
exp.UnixToStr: lambda self, e: self.func(
|
|
121
|
+
"FROM_UNIXTIME",
|
|
122
|
+
e.this,
|
|
123
|
+
self.format_time(
|
|
124
|
+
e,
|
|
125
|
+
inverse_time_mapping=MySQL.INVERSE_TIME_MAPPING,
|
|
126
|
+
inverse_time_trie=MySQL.INVERSE_TIME_TRIE,
|
|
127
|
+
),
|
|
128
|
+
),
|
|
129
|
+
exp.UnixToTime: unsupported_args("scale", "zone", "hours", "minutes")(
|
|
130
|
+
lambda self, e: self.func(
|
|
131
|
+
"FROM_UNIXTIME",
|
|
132
|
+
e.this,
|
|
133
|
+
self.format_time(
|
|
134
|
+
e,
|
|
135
|
+
inverse_time_mapping=MySQL.INVERSE_TIME_MAPPING,
|
|
136
|
+
inverse_time_trie=MySQL.INVERSE_TIME_TRIE,
|
|
137
|
+
),
|
|
138
|
+
),
|
|
139
|
+
),
|
|
140
|
+
exp.UnixToTimeStr: lambda self, e: f"FROM_UNIXTIME({self.sql(e, 'this')}) :> TEXT",
|
|
114
141
|
}
|
|
115
142
|
|
|
116
143
|
# https://docs.singlestore.com/cloud/reference/sql-reference/restricted-keywords/list-of-restricted-keywords/
|
sqlglot/dialects/snowflake.py
CHANGED
|
@@ -461,7 +461,7 @@ def _eliminate_dot_variant_lookup(expression: exp.Expression) -> exp.Expression:
|
|
|
461
461
|
unnest_alias = unnest.args.get("alias")
|
|
462
462
|
if (
|
|
463
463
|
isinstance(unnest_alias, exp.TableAlias)
|
|
464
|
-
and
|
|
464
|
+
and not unnest_alias.this
|
|
465
465
|
and len(unnest_alias.columns) == 1
|
|
466
466
|
):
|
|
467
467
|
unnest_aliases.add(unnest_alias.columns[0].name)
|
sqlglot/dialects/spark.py
CHANGED
|
@@ -194,6 +194,7 @@ class Spark(Spark2):
|
|
|
194
194
|
move_partitioned_by_to_schema_columns,
|
|
195
195
|
]
|
|
196
196
|
),
|
|
197
|
+
exp.DateFromUnixDate: rename_func("DATE_FROM_UNIX_DATE"),
|
|
197
198
|
exp.GroupConcat: _groupconcat_sql,
|
|
198
199
|
exp.EndsWith: rename_func("ENDSWITH"),
|
|
199
200
|
exp.PartitionedByProperty: lambda self,
|
sqlglot/dialects/teradata.py
CHANGED
|
@@ -90,6 +90,7 @@ class Teradata(Dialect):
|
|
|
90
90
|
"HELP": TokenType.COMMAND,
|
|
91
91
|
"INS": TokenType.INSERT,
|
|
92
92
|
"LE": TokenType.LTE,
|
|
93
|
+
"LOCKING": TokenType.LOCK,
|
|
93
94
|
"LT": TokenType.LT,
|
|
94
95
|
"MINUS": TokenType.EXCEPT,
|
|
95
96
|
"MOD": TokenType.MOD,
|
|
@@ -155,6 +156,26 @@ class Teradata(Dialect):
|
|
|
155
156
|
exp.Use, this=self._parse_table(schema=False)
|
|
156
157
|
),
|
|
157
158
|
TokenType.REPLACE: lambda self: self._parse_create(),
|
|
159
|
+
TokenType.LOCK: lambda self: self._parse_locking_statement(),
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
def _parse_locking_statement(self) -> exp.LockingStatement:
|
|
163
|
+
# Reuse exp.LockingProperty parsing for the lock kind, type etc
|
|
164
|
+
locking_property = self._parse_locking()
|
|
165
|
+
wrapped_query = self._parse_select()
|
|
166
|
+
|
|
167
|
+
if not wrapped_query:
|
|
168
|
+
self.raise_error("Expected SELECT statement after LOCKING clause")
|
|
169
|
+
|
|
170
|
+
return self.expression(
|
|
171
|
+
exp.LockingStatement,
|
|
172
|
+
this=locking_property,
|
|
173
|
+
expression=wrapped_query,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
SET_PARSERS = {
|
|
177
|
+
**parser.Parser.SET_PARSERS,
|
|
178
|
+
"QUERY_BAND": lambda self: self._parse_query_band(),
|
|
158
179
|
}
|
|
159
180
|
|
|
160
181
|
FUNCTION_PARSERS = {
|
|
@@ -210,6 +231,36 @@ class Teradata(Dialect):
|
|
|
210
231
|
|
|
211
232
|
return self.expression(exp.RangeN, this=this, expressions=expressions, each=each)
|
|
212
233
|
|
|
234
|
+
def _parse_query_band(self) -> exp.QueryBand:
|
|
235
|
+
# Parse: SET QUERY_BAND = 'key=value;key2=value2;' FOR SESSION|TRANSACTION
|
|
236
|
+
# Also supports: SET QUERY_BAND = 'key=value;' UPDATE FOR SESSION|TRANSACTION
|
|
237
|
+
# Also supports: SET QUERY_BAND = NONE FOR SESSION|TRANSACTION
|
|
238
|
+
self._match(TokenType.EQ)
|
|
239
|
+
|
|
240
|
+
# Handle both string literals and NONE keyword
|
|
241
|
+
if self._match_text_seq("NONE"):
|
|
242
|
+
query_band_string: t.Optional[exp.Expression] = exp.Var(this="NONE")
|
|
243
|
+
else:
|
|
244
|
+
query_band_string = self._parse_string()
|
|
245
|
+
|
|
246
|
+
update = self._match_text_seq("UPDATE")
|
|
247
|
+
self._match_text_seq("FOR")
|
|
248
|
+
|
|
249
|
+
# Handle scope - can be SESSION, TRANSACTION, VOLATILE, or SESSION VOLATILE
|
|
250
|
+
if self._match_text_seq("SESSION", "VOLATILE"):
|
|
251
|
+
scope = "SESSION VOLATILE"
|
|
252
|
+
elif self._match_texts(("SESSION", "TRANSACTION")):
|
|
253
|
+
scope = self._prev.text.upper()
|
|
254
|
+
else:
|
|
255
|
+
scope = None
|
|
256
|
+
|
|
257
|
+
return self.expression(
|
|
258
|
+
exp.QueryBand,
|
|
259
|
+
this=query_band_string,
|
|
260
|
+
scope=scope,
|
|
261
|
+
update=update,
|
|
262
|
+
)
|
|
263
|
+
|
|
213
264
|
def _parse_index_params(self) -> exp.IndexParameters:
|
|
214
265
|
this = super()._parse_index_params()
|
|
215
266
|
|
|
@@ -358,6 +409,13 @@ class Teradata(Dialect):
|
|
|
358
409
|
|
|
359
410
|
return f"RANGE_N({this} BETWEEN {expressions_sql}{each_sql})"
|
|
360
411
|
|
|
412
|
+
def lockingstatement_sql(self, expression: exp.LockingStatement) -> str:
|
|
413
|
+
"""Generate SQL for LOCKING statement"""
|
|
414
|
+
locking_clause = self.sql(expression, "this")
|
|
415
|
+
query_sql = self.sql(expression, "expression")
|
|
416
|
+
|
|
417
|
+
return f"{locking_clause} {query_sql}"
|
|
418
|
+
|
|
361
419
|
def createable_sql(self, expression: exp.Create, locations: t.DefaultDict) -> str:
|
|
362
420
|
kind = self.sql(expression, "kind").upper()
|
|
363
421
|
if kind == "TABLE" and locations.get(exp.Properties.Location.POST_NAME):
|
sqlglot/expressions.py
CHANGED
|
@@ -1458,6 +1458,11 @@ class DDL(Expression):
|
|
|
1458
1458
|
return self.expression.named_selects if isinstance(self.expression, Query) else []
|
|
1459
1459
|
|
|
1460
1460
|
|
|
1461
|
+
# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Manipulation-Language/Statement-Syntax/LOCKING-Request-Modifier/LOCKING-Request-Modifier-Syntax
|
|
1462
|
+
class LockingStatement(Expression):
|
|
1463
|
+
arg_types = {"this": True, "expression": True}
|
|
1464
|
+
|
|
1465
|
+
|
|
1461
1466
|
class DML(Expression):
|
|
1462
1467
|
def returning(
|
|
1463
1468
|
self,
|
|
@@ -1613,6 +1618,10 @@ class SetItem(Expression):
|
|
|
1613
1618
|
}
|
|
1614
1619
|
|
|
1615
1620
|
|
|
1621
|
+
class QueryBand(Expression):
|
|
1622
|
+
arg_types = {"this": True, "scope": False, "update": False}
|
|
1623
|
+
|
|
1624
|
+
|
|
1616
1625
|
class Show(Expression):
|
|
1617
1626
|
arg_types = {
|
|
1618
1627
|
"this": True,
|
|
@@ -1680,7 +1689,7 @@ class ProjectionDef(Expression):
|
|
|
1680
1689
|
|
|
1681
1690
|
|
|
1682
1691
|
class TableAlias(Expression):
|
|
1683
|
-
arg_types = {"this": False, "columns": False
|
|
1692
|
+
arg_types = {"this": False, "columns": False}
|
|
1684
1693
|
|
|
1685
1694
|
@property
|
|
1686
1695
|
def columns(self):
|
|
@@ -5416,6 +5425,10 @@ class BitwiseCountAgg(AggFunc):
|
|
|
5416
5425
|
_sql_names = ["BIT_COUNT"]
|
|
5417
5426
|
|
|
5418
5427
|
|
|
5428
|
+
class ByteLength(Func):
|
|
5429
|
+
pass
|
|
5430
|
+
|
|
5431
|
+
|
|
5419
5432
|
class ArrayRemove(Func):
|
|
5420
5433
|
arg_types = {"this": True, "expression": True}
|
|
5421
5434
|
|
|
@@ -5564,6 +5577,10 @@ class ConvertTimezone(Func):
|
|
|
5564
5577
|
}
|
|
5565
5578
|
|
|
5566
5579
|
|
|
5580
|
+
class CodePointsToString(Func):
|
|
5581
|
+
pass
|
|
5582
|
+
|
|
5583
|
+
|
|
5567
5584
|
class GenerateSeries(Func):
|
|
5568
5585
|
arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
|
|
5569
5586
|
|
|
@@ -5791,6 +5808,18 @@ class JSONCast(Cast):
|
|
|
5791
5808
|
pass
|
|
5792
5809
|
|
|
5793
5810
|
|
|
5811
|
+
class JustifyDays(Func):
|
|
5812
|
+
pass
|
|
5813
|
+
|
|
5814
|
+
|
|
5815
|
+
class JustifyHours(Func):
|
|
5816
|
+
pass
|
|
5817
|
+
|
|
5818
|
+
|
|
5819
|
+
class JustifyInterval(Func):
|
|
5820
|
+
pass
|
|
5821
|
+
|
|
5822
|
+
|
|
5794
5823
|
class Try(Func):
|
|
5795
5824
|
pass
|
|
5796
5825
|
|
|
@@ -5947,6 +5976,10 @@ class DatetimeTrunc(Func, TimeUnit):
|
|
|
5947
5976
|
arg_types = {"this": True, "unit": True, "zone": False}
|
|
5948
5977
|
|
|
5949
5978
|
|
|
5979
|
+
class DateFromUnixDate(Func):
|
|
5980
|
+
pass
|
|
5981
|
+
|
|
5982
|
+
|
|
5950
5983
|
class DayOfWeek(Func):
|
|
5951
5984
|
_sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
|
|
5952
5985
|
|
|
@@ -6509,6 +6542,14 @@ class ParseJSON(Func):
|
|
|
6509
6542
|
arg_types = {"this": True, "expression": False, "safe": False}
|
|
6510
6543
|
|
|
6511
6544
|
|
|
6545
|
+
class ParseTime(Func):
|
|
6546
|
+
arg_types = {"this": True, "format": True}
|
|
6547
|
+
|
|
6548
|
+
|
|
6549
|
+
class ParseDatetime(Func):
|
|
6550
|
+
arg_types = {"this": True, "format": False, "zone": False}
|
|
6551
|
+
|
|
6552
|
+
|
|
6512
6553
|
class Least(Func):
|
|
6513
6554
|
arg_types = {"this": True, "expressions": False}
|
|
6514
6555
|
is_var_len_args = True
|
|
@@ -6522,6 +6563,10 @@ class Right(Func):
|
|
|
6522
6563
|
arg_types = {"this": True, "expression": True}
|
|
6523
6564
|
|
|
6524
6565
|
|
|
6566
|
+
class Reverse(Func):
|
|
6567
|
+
pass
|
|
6568
|
+
|
|
6569
|
+
|
|
6525
6570
|
class Length(Func):
|
|
6526
6571
|
arg_types = {"this": True, "binary": False, "encoding": False}
|
|
6527
6572
|
_sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
|
|
@@ -7047,6 +7092,14 @@ class UnixSeconds(Func):
|
|
|
7047
7092
|
pass
|
|
7048
7093
|
|
|
7049
7094
|
|
|
7095
|
+
class UnixMicros(Func):
|
|
7096
|
+
pass
|
|
7097
|
+
|
|
7098
|
+
|
|
7099
|
+
class UnixMillis(Func):
|
|
7100
|
+
pass
|
|
7101
|
+
|
|
7102
|
+
|
|
7050
7103
|
class Uuid(Func):
|
|
7051
7104
|
_sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
|
|
7052
7105
|
|
|
@@ -7096,6 +7149,10 @@ class Week(Func):
|
|
|
7096
7149
|
arg_types = {"this": True, "mode": False}
|
|
7097
7150
|
|
|
7098
7151
|
|
|
7152
|
+
class WeekStart(Expression):
|
|
7153
|
+
pass
|
|
7154
|
+
|
|
7155
|
+
|
|
7099
7156
|
class XMLElement(Func):
|
|
7100
7157
|
_sql_names = ["XMLELEMENT"]
|
|
7101
7158
|
arg_types = {"this": True, "expressions": False}
|
sqlglot/generator.py
CHANGED
|
@@ -219,6 +219,7 @@ class Generator(metaclass=_Generator):
|
|
|
219
219
|
exp.VarMap: lambda self, e: self.func("MAP", e.args["keys"], e.args["values"]),
|
|
220
220
|
exp.ViewAttributeProperty: lambda self, e: f"WITH {self.sql(e, 'this')}",
|
|
221
221
|
exp.VolatileProperty: lambda *_: "VOLATILE",
|
|
222
|
+
exp.WeekStart: lambda self, e: f"WEEK({self.sql(e, 'this')})",
|
|
222
223
|
exp.WithJournalTableProperty: lambda self, e: f"WITH JOURNAL TABLE={self.sql(e, 'this')}",
|
|
223
224
|
exp.WithProcedureOptions: lambda self, e: f"WITH {self.expressions(e, flat=True)}",
|
|
224
225
|
exp.WithSchemaBindingProperty: lambda self, e: f"WITH SCHEMA {self.sql(e, 'this')}",
|
|
@@ -2405,6 +2406,14 @@ class Generator(metaclass=_Generator):
|
|
|
2405
2406
|
tag = " TAG" if expression.args.get("tag") else ""
|
|
2406
2407
|
return f"{'UNSET' if expression.args.get('unset') else 'SET'}{tag}{expressions}"
|
|
2407
2408
|
|
|
2409
|
+
def queryband_sql(self, expression: exp.QueryBand) -> str:
|
|
2410
|
+
this = self.sql(expression, "this")
|
|
2411
|
+
update = " UPDATE" if expression.args.get("update") else ""
|
|
2412
|
+
scope = self.sql(expression, "scope")
|
|
2413
|
+
scope = f" FOR {scope}" if scope else ""
|
|
2414
|
+
|
|
2415
|
+
return f"QUERY_BAND = {this}{update}{scope}"
|
|
2416
|
+
|
|
2408
2417
|
def pragma_sql(self, expression: exp.Pragma) -> str:
|
|
2409
2418
|
return f"PRAGMA {self.sql(expression, 'this')}"
|
|
2410
2419
|
|
|
@@ -3479,14 +3488,15 @@ class Generator(metaclass=_Generator):
|
|
|
3479
3488
|
expressions = f"({expressions})" if expressions else ""
|
|
3480
3489
|
return f"ALTER{compound} SORTKEY {this or expressions}"
|
|
3481
3490
|
|
|
3482
|
-
def alterrename_sql(self, expression: exp.AlterRename) -> str:
|
|
3491
|
+
def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
|
|
3483
3492
|
if not self.RENAME_TABLE_WITH_DB:
|
|
3484
3493
|
# Remove db from tables
|
|
3485
3494
|
expression = expression.transform(
|
|
3486
3495
|
lambda n: exp.table_(n.this) if isinstance(n, exp.Table) else n
|
|
3487
3496
|
).assert_is(exp.AlterRename)
|
|
3488
3497
|
this = self.sql(expression, "this")
|
|
3489
|
-
|
|
3498
|
+
to_kw = " TO" if include_to else ""
|
|
3499
|
+
return f"RENAME{to_kw} {this}"
|
|
3490
3500
|
|
|
3491
3501
|
def renamecolumn_sql(self, expression: exp.RenameColumn) -> str:
|
|
3492
3502
|
exists = " IF EXISTS" if expression.args.get("exists") else ""
|
|
@@ -5127,3 +5137,12 @@ class Generator(metaclass=_Generator):
|
|
|
5127
5137
|
return self.sql(exp.Bracket(this=this, expressions=[expr]))
|
|
5128
5138
|
|
|
5129
5139
|
return self.sql(exp.JSONExtract(this=this, expression=self.dialect.to_json_path(expr)))
|
|
5140
|
+
|
|
5141
|
+
def datefromunixdate_sql(self, expression: exp.DateFromUnixDate) -> str:
|
|
5142
|
+
return self.sql(
|
|
5143
|
+
exp.DateAdd(
|
|
5144
|
+
this=exp.cast(exp.Literal.string("1970-01-01"), exp.DataType.Type.DATE),
|
|
5145
|
+
expression=expression.this,
|
|
5146
|
+
unit=exp.var("DAY"),
|
|
5147
|
+
)
|
|
5148
|
+
)
|
|
@@ -326,7 +326,10 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
|
|
|
326
326
|
struct_type = exp.DataType(
|
|
327
327
|
this=exp.DataType.Type.STRUCT,
|
|
328
328
|
expressions=[
|
|
329
|
-
exp.ColumnDef(
|
|
329
|
+
exp.ColumnDef(
|
|
330
|
+
this=exp.to_identifier(select.output_name),
|
|
331
|
+
kind=select.type.copy() if select.type else None,
|
|
332
|
+
)
|
|
330
333
|
for select in scope.expression.selects
|
|
331
334
|
],
|
|
332
335
|
nested=True,
|
|
@@ -330,6 +330,10 @@ def _merge_expressions(outer_scope: Scope, inner_scope: Scope, alias: str) -> No
|
|
|
330
330
|
if isinstance(column.parent, (exp.Unary, exp.Binary)) and must_wrap_expression:
|
|
331
331
|
expression = exp.paren(expression, copy=False)
|
|
332
332
|
|
|
333
|
+
# make sure we do not accidentally change the name of the column
|
|
334
|
+
if isinstance(column.parent, exp.Select) and column.name != expression.name:
|
|
335
|
+
expression = exp.alias_(expression, column.name)
|
|
336
|
+
|
|
333
337
|
column.replace(expression.copy())
|
|
334
338
|
|
|
335
339
|
|
|
@@ -128,14 +128,6 @@ def qualify_tables(
|
|
|
128
128
|
table_alias = udtf.args.get("alias") or exp.TableAlias(
|
|
129
129
|
this=exp.to_identifier(next_alias_name())
|
|
130
130
|
)
|
|
131
|
-
if (
|
|
132
|
-
isinstance(udtf, exp.Unnest)
|
|
133
|
-
and dialect.UNNEST_COLUMN_ONLY
|
|
134
|
-
and not table_alias.columns
|
|
135
|
-
):
|
|
136
|
-
table_alias.set("columns", [table_alias.this.copy()])
|
|
137
|
-
table_alias.set("column_only", True)
|
|
138
|
-
|
|
139
131
|
udtf.set("alias", table_alias)
|
|
140
132
|
|
|
141
133
|
if not table_alias.name:
|
sqlglot/parser.py
CHANGED
|
@@ -2084,7 +2084,24 @@ class Parser(metaclass=_Parser):
|
|
|
2084
2084
|
|
|
2085
2085
|
if create_token.token_type == TokenType.SEQUENCE:
|
|
2086
2086
|
expression = self._parse_types()
|
|
2087
|
-
|
|
2087
|
+
props = self._parse_properties()
|
|
2088
|
+
if props:
|
|
2089
|
+
sequence_props = exp.SequenceProperties()
|
|
2090
|
+
options = []
|
|
2091
|
+
for prop in props:
|
|
2092
|
+
if isinstance(prop, exp.SequenceProperties):
|
|
2093
|
+
for arg, value in prop.args.items():
|
|
2094
|
+
if arg == "options":
|
|
2095
|
+
options.extend(value)
|
|
2096
|
+
else:
|
|
2097
|
+
sequence_props.set(arg, value)
|
|
2098
|
+
prop.pop()
|
|
2099
|
+
|
|
2100
|
+
if options:
|
|
2101
|
+
sequence_props.set("options", options)
|
|
2102
|
+
|
|
2103
|
+
props.append("expressions", sequence_props)
|
|
2104
|
+
extend_props(props)
|
|
2088
2105
|
else:
|
|
2089
2106
|
expression = self._parse_ddl_select()
|
|
2090
2107
|
|
|
@@ -2222,11 +2239,17 @@ class Parser(metaclass=_Parser):
|
|
|
2222
2239
|
return self.expression(exp.SqlSecurityProperty, definer=self._match_text_seq("DEFINER"))
|
|
2223
2240
|
|
|
2224
2241
|
index = self._index
|
|
2242
|
+
|
|
2243
|
+
seq_props = self._parse_sequence_properties()
|
|
2244
|
+
if seq_props:
|
|
2245
|
+
return seq_props
|
|
2246
|
+
|
|
2247
|
+
self._retreat(index)
|
|
2225
2248
|
key = self._parse_column()
|
|
2226
2249
|
|
|
2227
2250
|
if not self._match(TokenType.EQ):
|
|
2228
2251
|
self._retreat(index)
|
|
2229
|
-
return
|
|
2252
|
+
return None
|
|
2230
2253
|
|
|
2231
2254
|
# Transform the key to exp.Dot if it's dotted identifiers wrapped in exp.Column or to exp.Var otherwise
|
|
2232
2255
|
if isinstance(key, exp.Column):
|
|
@@ -3820,7 +3843,8 @@ class Parser(metaclass=_Parser):
|
|
|
3820
3843
|
elif self._match(TokenType.USING):
|
|
3821
3844
|
kwargs["using"] = self._parse_using_identifiers()
|
|
3822
3845
|
elif (
|
|
3823
|
-
not
|
|
3846
|
+
not method
|
|
3847
|
+
and not (outer_apply or cross_apply)
|
|
3824
3848
|
and not isinstance(kwargs["this"], exp.Unnest)
|
|
3825
3849
|
and not (kind and kind.token_type in (TokenType.CROSS, TokenType.ARRAY))
|
|
3826
3850
|
):
|
|
@@ -5255,7 +5279,7 @@ class Parser(metaclass=_Parser):
|
|
|
5255
5279
|
while self._match(TokenType.DOT):
|
|
5256
5280
|
type_name = f"{type_name}.{self._advance_any() and self._prev.text}"
|
|
5257
5281
|
|
|
5258
|
-
return exp.DataType.build(type_name, udt=True)
|
|
5282
|
+
return exp.DataType.build(type_name, dialect=self.dialect, udt=True)
|
|
5259
5283
|
|
|
5260
5284
|
def _parse_types(
|
|
5261
5285
|
self, check_func: bool = False, schema: bool = False, allow_identifiers: bool = True
|
|
@@ -6556,7 +6580,7 @@ class Parser(metaclass=_Parser):
|
|
|
6556
6580
|
elif not to:
|
|
6557
6581
|
self.raise_error("Expected TYPE after CAST")
|
|
6558
6582
|
elif isinstance(to, exp.Identifier):
|
|
6559
|
-
to = exp.DataType.build(to.name, udt=True)
|
|
6583
|
+
to = exp.DataType.build(to.name, dialect=self.dialect, udt=True)
|
|
6560
6584
|
elif to.this == exp.DataType.Type.CHAR:
|
|
6561
6585
|
if self._match(TokenType.CHARACTER_SET):
|
|
6562
6586
|
to = self.expression(exp.CharacterSet, this=self._parse_var_or_string())
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
sqlglot/__init__.py,sha256=za08rtdPh2v7dOpGdNomttlIVGgTrKja7rPd6sQwaTg,5391
|
|
2
2
|
sqlglot/__main__.py,sha256=022c173KqxsiABWTEpUIq_tJUxuNiW7a7ABsxBXqvu8,2069
|
|
3
3
|
sqlglot/_typing.py,sha256=-1HPyr3w5COlSJWqlgt8jhFk2dyMvBuvVBqIX1wyVCM,642
|
|
4
|
-
sqlglot/_version.py,sha256=
|
|
4
|
+
sqlglot/_version.py,sha256=5PUg50O7n_si_pQEvZg7Hxhtah6hzWUX8K6MSHG_oxc,513
|
|
5
5
|
sqlglot/diff.py,sha256=PtOllQMQa1Sw1-V2Y8eypmDqGujXYPaTOp_WLsWkAWk,17314
|
|
6
6
|
sqlglot/errors.py,sha256=QNKMr-pzLUDR-tuMmn_GK6iMHUIVdb_YSJ_BhGEvuso,2126
|
|
7
|
-
sqlglot/expressions.py,sha256=
|
|
8
|
-
sqlglot/generator.py,sha256=
|
|
7
|
+
sqlglot/expressions.py,sha256=Odk7emY-OtfIxyqDdhqgHM4m7AEvKGLo7nCDML2Y3Dw,247140
|
|
8
|
+
sqlglot/generator.py,sha256=hXFm8cL3QTVHrUKz0vNK0PnymYHWxHk4Gzy_4bepjxg,219142
|
|
9
9
|
sqlglot/helper.py,sha256=9nZjFVRBtMKFC3EdzpDQ6jkazFO19po6BF8xHiNGZIo,15111
|
|
10
10
|
sqlglot/jsonpath.py,sha256=jneO-A57n4ojVT2drCn2HBlx_Ka8wLcGpemW1JgvbjA,7666
|
|
11
11
|
sqlglot/lineage.py,sha256=Qj5ykuDNcATppb9vOjoIKBqRVLbu3OMPiZk9f3iyv40,15312
|
|
12
|
-
sqlglot/parser.py,sha256=
|
|
12
|
+
sqlglot/parser.py,sha256=Pt0uy-MgeTNYqwLMgiLhgB_hk2HlOJMFV1rDC-JrmlQ,328778
|
|
13
13
|
sqlglot/planner.py,sha256=ql7Li-bWJRcyXzNaZy_n6bQ6B2ZfunEIB8Ztv2xaxq4,14634
|
|
14
14
|
sqlglot/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
sqlglot/schema.py,sha256=13H2qKQs27EKdTpDLOvcNnSTDAUbYNKjWtJs4aQCSOA,20509
|
|
@@ -20,17 +20,17 @@ sqlglot/transforms.py,sha256=utNDsCBsA7hPUK3-aby3DDgiY_XVMAKQqeoLm1EyihI,41218
|
|
|
20
20
|
sqlglot/trie.py,sha256=v27uXMrHfqrXlJ6GmeTSMovsB_3o0ctnlKhdNt7W6fI,2245
|
|
21
21
|
sqlglot/dialects/__init__.py,sha256=BQUv9EuMmvhP_wVitGLo0PlCi15atvfXgvREpsTsxeQ,3799
|
|
22
22
|
sqlglot/dialects/athena.py,sha256=ofArmayYLev4qZQ15GM8mevG04qqR5WGFb2ZcuYm6x4,10966
|
|
23
|
-
sqlglot/dialects/bigquery.py,sha256=
|
|
24
|
-
sqlglot/dialects/clickhouse.py,sha256=
|
|
23
|
+
sqlglot/dialects/bigquery.py,sha256=d9RdAVLTIgHaOYi6INMNQL38S_zagdl9vNbIL_Ds21c,58896
|
|
24
|
+
sqlglot/dialects/clickhouse.py,sha256=ygkVXh8fAxQ2sPvsDIP3y-1bUxV2PSLeS-983MI1uKs,57780
|
|
25
25
|
sqlglot/dialects/databricks.py,sha256=mJN2lFpqgH95x3mtry3qWbuRf4q7NV5jbRAOspqclzY,4548
|
|
26
|
-
sqlglot/dialects/dialect.py,sha256=
|
|
27
|
-
sqlglot/dialects/doris.py,sha256=
|
|
28
|
-
sqlglot/dialects/dremio.py,sha256=
|
|
26
|
+
sqlglot/dialects/dialect.py,sha256=g6gUxzNFXJYFDYkDJY314pup63-2OvGek2kdufEn59g,71267
|
|
27
|
+
sqlglot/dialects/doris.py,sha256=HT3NyPORz8E1Kk6nNT00CEe4cwz1CfXGhhBcg8Hht1s,21709
|
|
28
|
+
sqlglot/dialects/dremio.py,sha256=vOVu-L9QYLMV8gkbY6vfDh_iffhw3D58IKk0yqvd0Lo,4512
|
|
29
29
|
sqlglot/dialects/drill.py,sha256=FOh7_KjPx_77pv0DiHKZog0CcmzqeF9_PEmGnJ1ESSM,5825
|
|
30
30
|
sqlglot/dialects/druid.py,sha256=kh3snZtneehNOWqs3XcPjsrhNaRbkCQ8E4hHbWJ1fHM,690
|
|
31
|
-
sqlglot/dialects/duckdb.py,sha256=
|
|
31
|
+
sqlglot/dialects/duckdb.py,sha256=kZ1LkGEtztkYwxh8Oad2GHUpmeM226h_uxSoCQ114Bo,52892
|
|
32
32
|
sqlglot/dialects/dune.py,sha256=gALut-fFfN2qMsr8LvZ1NQK3F3W9z2f4PwMvTMXVVVg,375
|
|
33
|
-
sqlglot/dialects/exasol.py,sha256=
|
|
33
|
+
sqlglot/dialects/exasol.py,sha256=w73rFG7jQVkBm2plWR8I12LMkHQVPofsEgWRf6VmiI8,14269
|
|
34
34
|
sqlglot/dialects/fabric.py,sha256=4Sng2ZhQSaf6eK3ituR9DqDZERaVwYS_UfdpusjsISg,10220
|
|
35
35
|
sqlglot/dialects/hive.py,sha256=bAZz0qnaOH9f5FyIMkqBu3XB2Cj7y-xnCPbxPsk8U9I,31959
|
|
36
36
|
sqlglot/dialects/materialize.py,sha256=LD2q1kTRrCwkIu1BfoBvnjTGbupDtoQ8JQMDCIYAXHg,3533
|
|
@@ -41,14 +41,14 @@ sqlglot/dialects/presto.py,sha256=Tm3Bx9AJilT1xlgunTpF0wUhIZBOPS-rB5Iwitnygxc,33
|
|
|
41
41
|
sqlglot/dialects/prql.py,sha256=fwN-SPEGx-drwf1K0U2MByN-PkW3C_rOgQ3xeJeychg,7908
|
|
42
42
|
sqlglot/dialects/redshift.py,sha256=MXI9W7CgKCtMNjNRPcZPxO8NBA9_PxZx14HB52o-aUc,15822
|
|
43
43
|
sqlglot/dialects/risingwave.py,sha256=BqWwW1iT_OIVMwfRamaww79snnBwIgCfr22Go-ggO68,3289
|
|
44
|
-
sqlglot/dialects/singlestore.py,sha256=
|
|
45
|
-
sqlglot/dialects/snowflake.py,sha256=
|
|
46
|
-
sqlglot/dialects/spark.py,sha256=
|
|
44
|
+
sqlglot/dialects/singlestore.py,sha256=dJp28vf7e9j87U7wnJF7cmXul9sypY1dU0vjZx63Fkc,31363
|
|
45
|
+
sqlglot/dialects/snowflake.py,sha256=XPsqYGBjn3dfddF2dcuM7Ur-4sYdthjW7cSPnptWq_s,70542
|
|
46
|
+
sqlglot/dialects/spark.py,sha256=qVZ96NqRnj2YhphWoJhRJTcwmrmNfXD2g442tL3MTrs,8956
|
|
47
47
|
sqlglot/dialects/spark2.py,sha256=aCwPqLduLRSUSPtbI1VtBjydK6haKgEy3iahmueGRo4,14742
|
|
48
48
|
sqlglot/dialects/sqlite.py,sha256=XIDmiNTswWcrDwlFm8gOODCrJ_rPmXQKkm9U_-YAlVs,13183
|
|
49
49
|
sqlglot/dialects/starrocks.py,sha256=2gav0PSNgRdAGXzawdznZliBpglJoQ0wBxPI7ZIMsRw,11314
|
|
50
50
|
sqlglot/dialects/tableau.py,sha256=oIawDzUITxGCWaEMB8OaNMPWhbC3U-2y09pYPm4eazc,2190
|
|
51
|
-
sqlglot/dialects/teradata.py,sha256=
|
|
51
|
+
sqlglot/dialects/teradata.py,sha256=7LxCcRwP0Idd_OnCzA57NCdheVjHcKC2aFAKG5N49IU,18202
|
|
52
52
|
sqlglot/dialects/trino.py,sha256=wgLsiX1NQvjGny_rgrU1e2r6kK1LD0KgaSdIDrYmjD0,4285
|
|
53
53
|
sqlglot/dialects/tsql.py,sha256=sz1t79iCcsMXw8PKYnKldZJbAQ2iobNsqLPVAj-QTXk,54036
|
|
54
54
|
sqlglot/executor/__init__.py,sha256=FslewzYQtQdDNg_0Ju2UaiP4vo4IMUgkfkmFsYUhcN0,2958
|
|
@@ -57,13 +57,13 @@ sqlglot/executor/env.py,sha256=tQhU5PpTBMcxgZIFddFqxWMNPtHN0vOOz72voncY3KY,8276
|
|
|
57
57
|
sqlglot/executor/python.py,sha256=09GYRzrPn3lZGfDJY9pbONOvmYxsRyeSWjUiqkSRHGo,16661
|
|
58
58
|
sqlglot/executor/table.py,sha256=xkuJlgLVNYUXsSUaX0zTcnFekldXLLU8LqDyjR5K9wY,4419
|
|
59
59
|
sqlglot/optimizer/__init__.py,sha256=FdAvVz6rQLLkiiH21-SD4RxB5zS3WDeU-s03PZkJ-F4,343
|
|
60
|
-
sqlglot/optimizer/annotate_types.py,sha256=
|
|
60
|
+
sqlglot/optimizer/annotate_types.py,sha256=MfxXNzYgxaqhv1yBmzuigWjc1oIw1ikZ_lXjcdT3RDc,25128
|
|
61
61
|
sqlglot/optimizer/canonicalize.py,sha256=RJpUbWDudjknRMtO_Kf8MGZ5Hv1twpPWac2u5kpV4Vw,7719
|
|
62
62
|
sqlglot/optimizer/eliminate_ctes.py,sha256=fUBM0RUnPrm2sYptEWBux98B7fcx7W-BM1zVqfgDz9c,1448
|
|
63
63
|
sqlglot/optimizer/eliminate_joins.py,sha256=2iYtG93aJGxvURqm1BVPosrnnnQ_IXI14RcD4pM8eHc,5942
|
|
64
64
|
sqlglot/optimizer/eliminate_subqueries.py,sha256=sAB_Pk94_n2n1PIaZ2Mc3M-n2TV-JmjjaomaY14u0Og,6292
|
|
65
65
|
sqlglot/optimizer/isolate_table_selects.py,sha256=_8rIKVMoL7eY3rrJsmgIdTRvfmBSLUxeHg42q1JW990,1464
|
|
66
|
-
sqlglot/optimizer/merge_subqueries.py,sha256
|
|
66
|
+
sqlglot/optimizer/merge_subqueries.py,sha256=-4C80Hob7gqJDHkt3IeH0oExmqPuU9RGB7JC_hlqr7s,15443
|
|
67
67
|
sqlglot/optimizer/normalize.py,sha256=wu3GeKY36PLyAb9f534jDDfzDwvZJpZ8g_H5QH6acZQ,6667
|
|
68
68
|
sqlglot/optimizer/normalize_identifiers.py,sha256=uD4xICJAgj0X7EFc2LYcDWxAW2aTHANO2wy7kfn9gfY,2098
|
|
69
69
|
sqlglot/optimizer/optimize_joins.py,sha256=tfEnTqBofveBXNKJ30GIvm2lyagAuD24bMNfu3iQi_k,3043
|
|
@@ -72,12 +72,12 @@ sqlglot/optimizer/pushdown_predicates.py,sha256=HGjs3Z4V3-X2d1VTfWhyByY3aL5SmKnV
|
|
|
72
72
|
sqlglot/optimizer/pushdown_projections.py,sha256=7NoK5NAUVYVhs0YnYyo6WuXfaO-BShSwS6lA8Y-ATQ4,6668
|
|
73
73
|
sqlglot/optimizer/qualify.py,sha256=oAPfwub7dEkrlCrsptcJWpLya4BgKhN6M5SwIs_86LY,4002
|
|
74
74
|
sqlglot/optimizer/qualify_columns.py,sha256=hOfhyczK9zBbUuysKdOK36PJ44nCzzw9BivJh8U5RBI,43921
|
|
75
|
-
sqlglot/optimizer/qualify_tables.py,sha256=
|
|
75
|
+
sqlglot/optimizer/qualify_tables.py,sha256=dA4ZazL7ShQh2JgBwpHuG-4c5lBw1TNzCnuN7m0iVTA,6645
|
|
76
76
|
sqlglot/optimizer/scope.py,sha256=T6iVYnYwubt-WB1BOFsFYdJ-D7WtWZGL37SuCRQK23s,31154
|
|
77
77
|
sqlglot/optimizer/simplify.py,sha256=-_yus42OYwqjQ9a2TSGhtG2G0pSkInUry1z7hEMz2pY,51062
|
|
78
78
|
sqlglot/optimizer/unnest_subqueries.py,sha256=kzWUVDlxs8z9nmRx-8U-pHXPtVZhEIwkKqmKhr2QLvc,10908
|
|
79
|
-
sqlglot-27.
|
|
80
|
-
sqlglot-27.
|
|
81
|
-
sqlglot-27.
|
|
82
|
-
sqlglot-27.
|
|
83
|
-
sqlglot-27.
|
|
79
|
+
sqlglot-27.7.0.dist-info/licenses/LICENSE,sha256=p1Yk0B4oa0l8Rh-_dYyy75d8spjPd_vTloXfz4FWxys,1065
|
|
80
|
+
sqlglot-27.7.0.dist-info/METADATA,sha256=hzW8lPG_bNI-kTX-iNRWj2ntlxyQRdHI-O3vUQU0_64,19437
|
|
81
|
+
sqlglot-27.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
82
|
+
sqlglot-27.7.0.dist-info/top_level.txt,sha256=5kRskCGA_gVADF9rSfSzPdLHXqvfMusDYeHePfNY2nQ,8
|
|
83
|
+
sqlglot-27.7.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|