sqlglot 27.16.3__py3-none-any.whl → 27.18.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/__init__.py +1 -0
- sqlglot/dialects/clickhouse.py +2 -3
- sqlglot/dialects/dialect.py +9 -0
- sqlglot/dialects/duckdb.py +6 -0
- sqlglot/dialects/mysql.py +15 -0
- sqlglot/dialects/postgres.py +3 -1
- sqlglot/dialects/snowflake.py +54 -7
- sqlglot/dialects/solr.py +22 -0
- sqlglot/expressions.py +64 -0
- sqlglot/generator.py +31 -7
- sqlglot/optimizer/simplify.py +1 -1
- sqlglot/parser.py +71 -21
- {sqlglot-27.16.3.dist-info → sqlglot-27.18.0.dist-info}/METADATA +3 -2
- {sqlglot-27.16.3.dist-info → sqlglot-27.18.0.dist-info}/RECORD +18 -17
- {sqlglot-27.16.3.dist-info → sqlglot-27.18.0.dist-info}/WHEEL +0 -0
- {sqlglot-27.16.3.dist-info → sqlglot-27.18.0.dist-info}/licenses/LICENSE +0 -0
- {sqlglot-27.16.3.dist-info → sqlglot-27.18.0.dist-info}/top_level.txt +0 -0
sqlglot/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '27.
|
|
32
|
-
__version_tuple__ = version_tuple = (27,
|
|
31
|
+
__version__ = version = '27.18.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (27, 18, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
sqlglot/dialects/__init__.py
CHANGED
sqlglot/dialects/clickhouse.py
CHANGED
|
@@ -332,7 +332,6 @@ class ClickHouse(Dialect):
|
|
|
332
332
|
"PARSEDATETIME": _build_datetime_format(exp.ParseDatetime),
|
|
333
333
|
"RANDCANONICAL": exp.Rand.from_arg_list,
|
|
334
334
|
"STR_TO_DATE": _build_str_to_date,
|
|
335
|
-
"TUPLE": exp.Struct.from_arg_list,
|
|
336
335
|
"TIMESTAMP_SUB": build_date_delta(exp.TimestampSub, default_unit=None),
|
|
337
336
|
"TIMESTAMPSUB": build_date_delta(exp.TimestampSub, default_unit=None),
|
|
338
337
|
"TIMESTAMP_ADD": build_date_delta(exp.TimestampAdd, default_unit=None),
|
|
@@ -505,14 +504,13 @@ class ClickHouse(Dialect):
|
|
|
505
504
|
}
|
|
506
505
|
)(AGG_FUNCTIONS, AGG_FUNCTIONS_SUFFIXES)
|
|
507
506
|
|
|
508
|
-
FUNCTIONS_WITH_ALIASED_ARGS = {*parser.Parser.FUNCTIONS_WITH_ALIASED_ARGS, "TUPLE"}
|
|
509
|
-
|
|
510
507
|
FUNCTION_PARSERS = {
|
|
511
508
|
**parser.Parser.FUNCTION_PARSERS,
|
|
512
509
|
"ARRAYJOIN": lambda self: self.expression(exp.Explode, this=self._parse_expression()),
|
|
513
510
|
"QUANTILE": lambda self: self._parse_quantile(),
|
|
514
511
|
"MEDIAN": lambda self: self._parse_quantile(),
|
|
515
512
|
"COLUMNS": lambda self: self._parse_columns(),
|
|
513
|
+
"TUPLE": lambda self: exp.Struct.from_arg_list(self._parse_function_args(alias=True)),
|
|
516
514
|
}
|
|
517
515
|
|
|
518
516
|
FUNCTION_PARSERS.pop("MATCH")
|
|
@@ -1126,6 +1124,7 @@ class ClickHouse(Dialect):
|
|
|
1126
1124
|
exp.RegexpLike: lambda self, e: self.func("match", e.this, e.expression),
|
|
1127
1125
|
exp.Rand: rename_func("randCanonical"),
|
|
1128
1126
|
exp.StartsWith: rename_func("startsWith"),
|
|
1127
|
+
exp.Struct: rename_func("tuple"),
|
|
1129
1128
|
exp.EndsWith: rename_func("endsWith"),
|
|
1130
1129
|
exp.EuclideanDistance: rename_func("L2Distance"),
|
|
1131
1130
|
exp.StrPosition: lambda self, e: strposition_sql(
|
sqlglot/dialects/dialect.py
CHANGED
|
@@ -99,6 +99,7 @@ class Dialects(str, Enum):
|
|
|
99
99
|
REDSHIFT = "redshift"
|
|
100
100
|
RISINGWAVE = "risingwave"
|
|
101
101
|
SNOWFLAKE = "snowflake"
|
|
102
|
+
SOLR = "solr"
|
|
102
103
|
SPARK = "spark"
|
|
103
104
|
SPARK2 = "spark2"
|
|
104
105
|
SQLITE = "sqlite"
|
|
@@ -291,6 +292,12 @@ class _Dialect(type):
|
|
|
291
292
|
TokenType.SEMI,
|
|
292
293
|
}
|
|
293
294
|
|
|
295
|
+
klass.VALID_INTERVAL_UNITS = {
|
|
296
|
+
*klass.VALID_INTERVAL_UNITS,
|
|
297
|
+
*klass.DATE_PART_MAPPING.keys(),
|
|
298
|
+
*klass.DATE_PART_MAPPING.values(),
|
|
299
|
+
}
|
|
300
|
+
|
|
294
301
|
return klass
|
|
295
302
|
|
|
296
303
|
|
|
@@ -551,6 +558,8 @@ class Dialect(metaclass=_Dialect):
|
|
|
551
558
|
IDENTIFIER_START = '"'
|
|
552
559
|
IDENTIFIER_END = '"'
|
|
553
560
|
|
|
561
|
+
VALID_INTERVAL_UNITS: t.Set[str] = set()
|
|
562
|
+
|
|
554
563
|
# Delimiters for bit, hex, byte and unicode literals
|
|
555
564
|
BIT_START: t.Optional[str] = None
|
|
556
565
|
BIT_END: t.Optional[str] = None
|
sqlglot/dialects/duckdb.py
CHANGED
|
@@ -1296,3 +1296,9 @@ class DuckDB(Dialect):
|
|
|
1296
1296
|
return self.sql(exp.Cast(this=func, to=this.type))
|
|
1297
1297
|
|
|
1298
1298
|
return self.sql(func)
|
|
1299
|
+
|
|
1300
|
+
def format_sql(self, expression: exp.Format) -> str:
|
|
1301
|
+
if expression.name.lower() == "%s" and len(expression.expressions) == 1:
|
|
1302
|
+
return self.func("FORMAT", "'{}'", expression.expressions[0])
|
|
1303
|
+
|
|
1304
|
+
return self.function_fallback_sql(expression)
|
sqlglot/dialects/mysql.py
CHANGED
|
@@ -179,6 +179,21 @@ class MySQL(Dialect):
|
|
|
179
179
|
"%W": "%A",
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
VALID_INTERVAL_UNITS = {
|
|
183
|
+
*Dialect.VALID_INTERVAL_UNITS,
|
|
184
|
+
"SECOND_MICROSECOND",
|
|
185
|
+
"MINUTE_MICROSECOND",
|
|
186
|
+
"MINUTE_SECOND",
|
|
187
|
+
"HOUR_MICROSECOND",
|
|
188
|
+
"HOUR_SECOND",
|
|
189
|
+
"HOUR_MINUTE",
|
|
190
|
+
"DAY_MICROSECOND",
|
|
191
|
+
"DAY_SECOND",
|
|
192
|
+
"DAY_MINUTE",
|
|
193
|
+
"DAY_HOUR",
|
|
194
|
+
"YEAR_MONTH",
|
|
195
|
+
}
|
|
196
|
+
|
|
182
197
|
class Tokenizer(tokens.Tokenizer):
|
|
183
198
|
QUOTES = ["'", '"']
|
|
184
199
|
COMMENTS = ["--", "#", ("/*", "*/")]
|
sqlglot/dialects/postgres.py
CHANGED
|
@@ -375,6 +375,8 @@ class Postgres(Dialect):
|
|
|
375
375
|
VAR_SINGLE_TOKENS = {"$"}
|
|
376
376
|
|
|
377
377
|
class Parser(parser.Parser):
|
|
378
|
+
SUPPORTS_OMITTED_INTERVAL_SPAN_UNIT = True
|
|
379
|
+
|
|
378
380
|
PROPERTY_PARSERS = {
|
|
379
381
|
**parser.Parser.PROPERTY_PARSERS,
|
|
380
382
|
"SET": lambda self: self.expression(exp.SetConfigProperty, this=self._parse_set()),
|
|
@@ -426,7 +428,7 @@ class Postgres(Dialect):
|
|
|
426
428
|
"DATE_PART": lambda self: self._parse_date_part(),
|
|
427
429
|
"JSON_AGG": lambda self: self.expression(
|
|
428
430
|
exp.JSONArrayAgg,
|
|
429
|
-
this=self.
|
|
431
|
+
this=self._parse_lambda(),
|
|
430
432
|
order=self._parse_order(),
|
|
431
433
|
),
|
|
432
434
|
"JSONB_EXISTS": lambda self: self._parse_jsonb_exists(),
|
sqlglot/dialects/snowflake.py
CHANGED
|
@@ -324,6 +324,15 @@ def _build_regexp_extract(expr_type: t.Type[E]) -> t.Callable[[t.List], E]:
|
|
|
324
324
|
return _builder
|
|
325
325
|
|
|
326
326
|
|
|
327
|
+
def _build_like(expr_type: t.Type[E]) -> t.Callable[[t.List], E | exp.Escape]:
|
|
328
|
+
def _builder(args: t.List) -> E | exp.Escape:
|
|
329
|
+
like_expr = expr_type(this=args[0], expression=args[1])
|
|
330
|
+
escape = seq_get(args, 2)
|
|
331
|
+
return exp.Escape(this=like_expr, expression=escape) if escape else like_expr
|
|
332
|
+
|
|
333
|
+
return _builder
|
|
334
|
+
|
|
335
|
+
|
|
327
336
|
def _regexpextract_sql(self, expression: exp.RegexpExtract | exp.RegexpExtractAll) -> str:
|
|
328
337
|
# Other dialects don't support all of the following parameters, so we need to
|
|
329
338
|
# generate default values as necessary to ensure the transpilation is correct
|
|
@@ -522,14 +531,27 @@ class Snowflake(Dialect):
|
|
|
522
531
|
**Dialect.TYPE_TO_EXPRESSIONS,
|
|
523
532
|
exp.DataType.Type.INT: {
|
|
524
533
|
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.INT],
|
|
534
|
+
exp.Ascii,
|
|
525
535
|
exp.Length,
|
|
536
|
+
exp.BitLength,
|
|
537
|
+
exp.Levenshtein,
|
|
538
|
+
exp.JarowinklerSimilarity,
|
|
526
539
|
},
|
|
527
540
|
exp.DataType.Type.VARCHAR: {
|
|
528
541
|
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.VARCHAR],
|
|
542
|
+
exp.Base64DecodeString,
|
|
543
|
+
exp.Base64Encode,
|
|
544
|
+
exp.DecompressString,
|
|
529
545
|
exp.MD5,
|
|
530
546
|
exp.AIAgg,
|
|
531
547
|
exp.AIClassify,
|
|
532
548
|
exp.AISummarizeAgg,
|
|
549
|
+
exp.Chr,
|
|
550
|
+
exp.Collate,
|
|
551
|
+
exp.Collation,
|
|
552
|
+
exp.HexDecodeString,
|
|
553
|
+
exp.HexEncode,
|
|
554
|
+
exp.Initcap,
|
|
533
555
|
exp.RegexpExtract,
|
|
534
556
|
exp.RegexpReplace,
|
|
535
557
|
exp.Repeat,
|
|
@@ -541,9 +563,13 @@ class Snowflake(Dialect):
|
|
|
541
563
|
},
|
|
542
564
|
exp.DataType.Type.BINARY: {
|
|
543
565
|
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.BINARY],
|
|
566
|
+
exp.Base64DecodeBinary,
|
|
567
|
+
exp.Compress,
|
|
568
|
+
exp.DecompressBinary,
|
|
544
569
|
exp.MD5Digest,
|
|
545
570
|
exp.SHA1Digest,
|
|
546
571
|
exp.SHA2Digest,
|
|
572
|
+
exp.Unhex,
|
|
547
573
|
},
|
|
548
574
|
exp.DataType.Type.BIGINT: {
|
|
549
575
|
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.BIGINT],
|
|
@@ -566,7 +592,9 @@ class Snowflake(Dialect):
|
|
|
566
592
|
expr_type: lambda self, e: self._annotate_by_args(e, "this")
|
|
567
593
|
for expr_type in (
|
|
568
594
|
exp.Left,
|
|
595
|
+
exp.Pad,
|
|
569
596
|
exp.Right,
|
|
597
|
+
exp.Stuff,
|
|
570
598
|
exp.Substring,
|
|
571
599
|
)
|
|
572
600
|
},
|
|
@@ -678,6 +706,7 @@ class Snowflake(Dialect):
|
|
|
678
706
|
"DATE_TRUNC": _date_trunc_to_time,
|
|
679
707
|
"DATEADD": _build_date_time_add(exp.DateAdd),
|
|
680
708
|
"DATEDIFF": _build_datediff,
|
|
709
|
+
"DAYOFWEEKISO": exp.DayOfWeekIso.from_arg_list,
|
|
681
710
|
"DIV0": _build_if_from_div0,
|
|
682
711
|
"EDITDISTANCE": lambda args: exp.Levenshtein(
|
|
683
712
|
this=seq_get(args, 0), expression=seq_get(args, 1), max_dist=seq_get(args, 2)
|
|
@@ -746,6 +775,8 @@ class Snowflake(Dialect):
|
|
|
746
775
|
"TO_JSON": exp.JSONFormat.from_arg_list,
|
|
747
776
|
"VECTOR_L2_DISTANCE": exp.EuclideanDistance.from_arg_list,
|
|
748
777
|
"ZEROIFNULL": _build_if_from_zeroifnull,
|
|
778
|
+
"LIKE": _build_like(exp.Like),
|
|
779
|
+
"ILIKE": _build_like(exp.ILike),
|
|
749
780
|
}
|
|
750
781
|
FUNCTIONS.pop("PREDICT")
|
|
751
782
|
|
|
@@ -1478,13 +1509,23 @@ class Snowflake(Dialect):
|
|
|
1478
1509
|
|
|
1479
1510
|
def datatype_sql(self, expression: exp.DataType) -> str:
|
|
1480
1511
|
expressions = expression.expressions
|
|
1481
|
-
if (
|
|
1482
|
-
expressions
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1512
|
+
if expressions and expression.is_type(*exp.DataType.STRUCT_TYPES):
|
|
1513
|
+
for field_type in expressions:
|
|
1514
|
+
# The correct syntax is OBJECT [ (<key> <value_type [NOT NULL] [, ...]) ]
|
|
1515
|
+
if isinstance(field_type, exp.DataType):
|
|
1516
|
+
return "OBJECT"
|
|
1517
|
+
if (
|
|
1518
|
+
isinstance(field_type, exp.ColumnDef)
|
|
1519
|
+
and field_type.this
|
|
1520
|
+
and field_type.this.is_string
|
|
1521
|
+
):
|
|
1522
|
+
# Doing OBJECT('foo' VARCHAR) is invalid snowflake Syntax. Moreover, besides
|
|
1523
|
+
# converting 'foo' into an identifier, we also need to quote it because these
|
|
1524
|
+
# keys are case-sensitive. For example:
|
|
1525
|
+
#
|
|
1526
|
+
# WITH t AS (SELECT OBJECT_CONSTRUCT('x', 'y') AS c) SELECT c:x FROM t -- correct
|
|
1527
|
+
# WITH t AS (SELECT OBJECT_CONSTRUCT('x', 'y') AS c) SELECT c:X FROM t -- incorrect, returns NULL
|
|
1528
|
+
field_type.this.replace(exp.to_identifier(field_type.name, quoted=True))
|
|
1488
1529
|
|
|
1489
1530
|
return super().datatype_sql(expression)
|
|
1490
1531
|
|
|
@@ -1816,3 +1857,9 @@ class Snowflake(Dialect):
|
|
|
1816
1857
|
|
|
1817
1858
|
def modelattribute_sql(self, expression: exp.ModelAttribute) -> str:
|
|
1818
1859
|
return f"{self.sql(expression, 'this')}!{self.sql(expression, 'expression')}"
|
|
1860
|
+
|
|
1861
|
+
def format_sql(self, expression: exp.Format) -> str:
|
|
1862
|
+
if expression.name.lower() == "%s" and len(expression.expressions) == 1:
|
|
1863
|
+
return self.func("TO_CHAR", expression.expressions[0])
|
|
1864
|
+
|
|
1865
|
+
return self.function_fallback_sql(expression)
|
sqlglot/dialects/solr.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from sqlglot import exp, parser, tokens
|
|
2
|
+
from sqlglot.dialects.dialect import Dialect, NormalizationStrategy
|
|
3
|
+
from sqlglot.tokens import TokenType
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# https://solr.apache.org/guide/solr/latest/query-guide/sql-query.html
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Solr(Dialect):
|
|
10
|
+
NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
|
|
11
|
+
DPIPE_IS_STRING_CONCAT = False
|
|
12
|
+
SUPPORTS_SEMI_ANTI_JOIN = False
|
|
13
|
+
|
|
14
|
+
class Parser(parser.Parser):
|
|
15
|
+
DISJUNCTION = {
|
|
16
|
+
**parser.Parser.DISJUNCTION,
|
|
17
|
+
TokenType.DPIPE: exp.Or,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class Tokenizer(tokens.Tokenizer):
|
|
21
|
+
QUOTES = ["'"]
|
|
22
|
+
IDENTIFIERS = ["`"]
|
sqlglot/expressions.py
CHANGED
|
@@ -5531,6 +5531,10 @@ class EuclideanDistance(Func):
|
|
|
5531
5531
|
arg_types = {"this": True, "expression": True}
|
|
5532
5532
|
|
|
5533
5533
|
|
|
5534
|
+
class JarowinklerSimilarity(Func):
|
|
5535
|
+
arg_types = {"this": True, "expression": True}
|
|
5536
|
+
|
|
5537
|
+
|
|
5534
5538
|
class AggFunc(Func):
|
|
5535
5539
|
pass
|
|
5536
5540
|
|
|
@@ -6022,6 +6026,10 @@ class Collate(Binary, Func):
|
|
|
6022
6026
|
pass
|
|
6023
6027
|
|
|
6024
6028
|
|
|
6029
|
+
class Collation(Func):
|
|
6030
|
+
pass
|
|
6031
|
+
|
|
6032
|
+
|
|
6025
6033
|
class Ceil(Func):
|
|
6026
6034
|
arg_types = {"this": True, "decimals": False, "to": False}
|
|
6027
6035
|
_sql_names = ["CEIL", "CEILING"]
|
|
@@ -6414,6 +6422,19 @@ class ToBase64(Func):
|
|
|
6414
6422
|
pass
|
|
6415
6423
|
|
|
6416
6424
|
|
|
6425
|
+
# https://docs.snowflake.com/en/sql-reference/functions/base64_decode_binary
|
|
6426
|
+
class Base64DecodeBinary(Func):
|
|
6427
|
+
arg_types = {"this": True, "alphabet": False}
|
|
6428
|
+
|
|
6429
|
+
|
|
6430
|
+
class Base64DecodeString(Func):
|
|
6431
|
+
arg_types = {"this": True, "alphabet": False}
|
|
6432
|
+
|
|
6433
|
+
|
|
6434
|
+
class Base64Encode(Func):
|
|
6435
|
+
arg_types = {"this": True, "max_line_length": False, "alphabet": False}
|
|
6436
|
+
|
|
6437
|
+
|
|
6417
6438
|
# https://trino.io/docs/current/functions/datetime.html#from_iso8601_timestamp
|
|
6418
6439
|
class FromISO8601Timestamp(Func):
|
|
6419
6440
|
_sql_names = ["FROM_ISO8601_TIMESTAMP"]
|
|
@@ -6465,6 +6486,32 @@ class Hex(Func):
|
|
|
6465
6486
|
pass
|
|
6466
6487
|
|
|
6467
6488
|
|
|
6489
|
+
# https://docs.snowflake.com/en/sql-reference/functions/hex_decode_string
|
|
6490
|
+
class HexDecodeString(Func):
|
|
6491
|
+
pass
|
|
6492
|
+
|
|
6493
|
+
|
|
6494
|
+
# https://docs.snowflake.com/en/sql-reference/functions/hex_encode
|
|
6495
|
+
class HexEncode(Func):
|
|
6496
|
+
arg_types = {"this": True, "case": False}
|
|
6497
|
+
|
|
6498
|
+
|
|
6499
|
+
# T-SQL: https://learn.microsoft.com/en-us/sql/t-sql/functions/compress-transact-sql?view=sql-server-ver17
|
|
6500
|
+
# Snowflake: https://docs.snowflake.com/en/sql-reference/functions/compress
|
|
6501
|
+
class Compress(Func):
|
|
6502
|
+
arg_types = {"this": True, "method": False}
|
|
6503
|
+
|
|
6504
|
+
|
|
6505
|
+
# Snowflake: https://docs.snowflake.com/en/sql-reference/functions/decompress_binary
|
|
6506
|
+
class DecompressBinary(Func):
|
|
6507
|
+
arg_types = {"this": True, "method": True}
|
|
6508
|
+
|
|
6509
|
+
|
|
6510
|
+
# Snowflake: https://docs.snowflake.com/en/sql-reference/functions/decompress_string
|
|
6511
|
+
class DecompressString(Func):
|
|
6512
|
+
arg_types = {"this": True, "method": True}
|
|
6513
|
+
|
|
6514
|
+
|
|
6468
6515
|
class LowerHex(Hex):
|
|
6469
6516
|
pass
|
|
6470
6517
|
|
|
@@ -6871,6 +6918,10 @@ class Length(Func):
|
|
|
6871
6918
|
_sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
|
|
6872
6919
|
|
|
6873
6920
|
|
|
6921
|
+
class BitLength(Func):
|
|
6922
|
+
pass
|
|
6923
|
+
|
|
6924
|
+
|
|
6874
6925
|
class Levenshtein(Func):
|
|
6875
6926
|
arg_types = {
|
|
6876
6927
|
"this": True,
|
|
@@ -8557,6 +8608,19 @@ def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Ide
|
|
|
8557
8608
|
|
|
8558
8609
|
INTERVAL_STRING_RE = re.compile(r"\s*(-?[0-9]+(?:\.[0-9]+)?)\s*([a-zA-Z]+)\s*")
|
|
8559
8610
|
|
|
8611
|
+
# Matches day-time interval strings that contain
|
|
8612
|
+
# - A number of days (possibly negative or with decimals)
|
|
8613
|
+
# - At least one space
|
|
8614
|
+
# - Portions of a time-like signature, potentially negative
|
|
8615
|
+
# - Standard format [-]h+:m+:s+[.f+]
|
|
8616
|
+
# - Just minutes/seconds/frac seconds [-]m+:s+.f+
|
|
8617
|
+
# - Just hours, minutes, maybe colon [-]h+:m+[:]
|
|
8618
|
+
# - Just hours, maybe colon [-]h+[:]
|
|
8619
|
+
# - Just colon :
|
|
8620
|
+
INTERVAL_DAY_TIME_RE = re.compile(
|
|
8621
|
+
r"\s*-?\s*\d+(?:\.\d+)?\s+(?:-?(?:\d+:)?\d+:\d+(?:\.\d+)?|-?(?:\d+:){1,2}|:)\s*"
|
|
8622
|
+
)
|
|
8623
|
+
|
|
8560
8624
|
|
|
8561
8625
|
def to_interval(interval: str | Literal) -> Interval:
|
|
8562
8626
|
"""Builds an interval expression from a string like '1 day' or '5 months'."""
|
sqlglot/generator.py
CHANGED
|
@@ -727,6 +727,7 @@ class Generator(metaclass=_Generator):
|
|
|
727
727
|
"dialect",
|
|
728
728
|
"unsupported_messages",
|
|
729
729
|
"_escaped_quote_end",
|
|
730
|
+
"_escaped_byte_quote_end",
|
|
730
731
|
"_escaped_identifier_end",
|
|
731
732
|
"_next_name",
|
|
732
733
|
"_identifier_start",
|
|
@@ -773,6 +774,11 @@ class Generator(metaclass=_Generator):
|
|
|
773
774
|
self._escaped_quote_end: str = (
|
|
774
775
|
self.dialect.tokenizer_class.STRING_ESCAPES[0] + self.dialect.QUOTE_END
|
|
775
776
|
)
|
|
777
|
+
self._escaped_byte_quote_end: str = (
|
|
778
|
+
self.dialect.tokenizer_class.STRING_ESCAPES[0] + self.dialect.BYTE_END
|
|
779
|
+
if self.dialect.BYTE_END
|
|
780
|
+
else ""
|
|
781
|
+
)
|
|
776
782
|
self._escaped_identifier_end = self.dialect.IDENTIFIER_END * 2
|
|
777
783
|
|
|
778
784
|
self._next_name = name_sequence("_t")
|
|
@@ -1376,7 +1382,13 @@ class Generator(metaclass=_Generator):
|
|
|
1376
1382
|
def bytestring_sql(self, expression: exp.ByteString) -> str:
|
|
1377
1383
|
this = self.sql(expression, "this")
|
|
1378
1384
|
if self.dialect.BYTE_START:
|
|
1379
|
-
|
|
1385
|
+
escaped_byte_string = self.escape_str(
|
|
1386
|
+
this,
|
|
1387
|
+
escape_backslash=False,
|
|
1388
|
+
delimiter=self.dialect.BYTE_END,
|
|
1389
|
+
escaped_delimiter=self._escaped_byte_quote_end,
|
|
1390
|
+
)
|
|
1391
|
+
return f"{self.dialect.BYTE_START}{escaped_byte_string}{self.dialect.BYTE_END}"
|
|
1380
1392
|
return this
|
|
1381
1393
|
|
|
1382
1394
|
def unicodestring_sql(self, expression: exp.UnicodeString) -> str:
|
|
@@ -2475,16 +2487,23 @@ class Generator(metaclass=_Generator):
|
|
|
2475
2487
|
text = f"{self.dialect.QUOTE_START}{self.escape_str(text)}{self.dialect.QUOTE_END}"
|
|
2476
2488
|
return text
|
|
2477
2489
|
|
|
2478
|
-
def escape_str(
|
|
2490
|
+
def escape_str(
|
|
2491
|
+
self,
|
|
2492
|
+
text: str,
|
|
2493
|
+
escape_backslash: bool = True,
|
|
2494
|
+
delimiter: t.Optional[str] = None,
|
|
2495
|
+
escaped_delimiter: t.Optional[str] = None,
|
|
2496
|
+
) -> str:
|
|
2479
2497
|
if self.dialect.ESCAPED_SEQUENCES:
|
|
2480
2498
|
to_escaped = self.dialect.ESCAPED_SEQUENCES
|
|
2481
2499
|
text = "".join(
|
|
2482
2500
|
to_escaped.get(ch, ch) if escape_backslash or ch != "\\" else ch for ch in text
|
|
2483
2501
|
)
|
|
2484
2502
|
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2503
|
+
delimiter = delimiter or self.dialect.QUOTE_END
|
|
2504
|
+
escaped_delimiter = escaped_delimiter or self._escaped_quote_end
|
|
2505
|
+
|
|
2506
|
+
return self._replace_line_breaks(text).replace(delimiter, escaped_delimiter)
|
|
2488
2507
|
|
|
2489
2508
|
def loaddata_sql(self, expression: exp.LoadData) -> str:
|
|
2490
2509
|
local = " LOCAL" if expression.args.get("local") else ""
|
|
@@ -3256,14 +3275,19 @@ class Generator(metaclass=_Generator):
|
|
|
3256
3275
|
return f"(SELECT {self.sql(unnest)})"
|
|
3257
3276
|
|
|
3258
3277
|
def interval_sql(self, expression: exp.Interval) -> str:
|
|
3259
|
-
|
|
3278
|
+
unit_expression = expression.args.get("unit")
|
|
3279
|
+
unit = self.sql(unit_expression) if unit_expression else ""
|
|
3260
3280
|
if not self.INTERVAL_ALLOWS_PLURAL_FORM:
|
|
3261
3281
|
unit = self.TIME_PART_SINGULARS.get(unit, unit)
|
|
3262
3282
|
unit = f" {unit}" if unit else ""
|
|
3263
3283
|
|
|
3264
3284
|
if self.SINGLE_STRING_INTERVAL:
|
|
3265
3285
|
this = expression.this.name if expression.this else ""
|
|
3266
|
-
|
|
3286
|
+
if this:
|
|
3287
|
+
if unit_expression and isinstance(unit_expression, exp.IntervalSpan):
|
|
3288
|
+
return f"INTERVAL '{this}'{unit}"
|
|
3289
|
+
return f"INTERVAL '{this}{unit}'"
|
|
3290
|
+
return f"INTERVAL{unit}"
|
|
3267
3291
|
|
|
3268
3292
|
this = self.sql(expression, "this")
|
|
3269
3293
|
if this:
|
sqlglot/optimizer/simplify.py
CHANGED
sqlglot/parser.py
CHANGED
|
@@ -1561,6 +1561,10 @@ class Parser(metaclass=_Parser):
|
|
|
1561
1561
|
# Adding an ON TRUE, makes transpilation semantically correct for other dialects
|
|
1562
1562
|
ADD_JOIN_ON_TRUE = False
|
|
1563
1563
|
|
|
1564
|
+
# Whether INTERVAL spans with literal format '\d+ hh:[mm:[ss[.ff]]]'
|
|
1565
|
+
# can omit the span unit `DAY TO MINUTE` or `DAY TO SECOND`
|
|
1566
|
+
SUPPORTS_OMITTED_INTERVAL_SPAN_UNIT = False
|
|
1567
|
+
|
|
1564
1568
|
__slots__ = (
|
|
1565
1569
|
"error_level",
|
|
1566
1570
|
"error_message_context",
|
|
@@ -3119,21 +3123,26 @@ class Parser(metaclass=_Parser):
|
|
|
3119
3123
|
)
|
|
3120
3124
|
|
|
3121
3125
|
def _parse_update(self) -> exp.Update:
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
"
|
|
3130
|
-
|
|
3131
|
-
"
|
|
3132
|
-
|
|
3133
|
-
"
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3126
|
+
kwargs: t.Dict[str, t.Any] = {
|
|
3127
|
+
"this": self._parse_table(joins=True, alias_tokens=self.UPDATE_ALIAS_TOKENS),
|
|
3128
|
+
}
|
|
3129
|
+
while self._curr:
|
|
3130
|
+
if self._match(TokenType.SET):
|
|
3131
|
+
kwargs["expressions"] = self._parse_csv(self._parse_equality)
|
|
3132
|
+
elif self._match(TokenType.RETURNING, advance=False):
|
|
3133
|
+
kwargs["returning"] = self._parse_returning()
|
|
3134
|
+
elif self._match(TokenType.FROM, advance=False):
|
|
3135
|
+
kwargs["from"] = self._parse_from(joins=True)
|
|
3136
|
+
elif self._match(TokenType.WHERE, advance=False):
|
|
3137
|
+
kwargs["where"] = self._parse_where()
|
|
3138
|
+
elif self._match(TokenType.ORDER_BY, advance=False):
|
|
3139
|
+
kwargs["order"] = self._parse_order()
|
|
3140
|
+
elif self._match(TokenType.LIMIT, advance=False):
|
|
3141
|
+
kwargs["limit"] = self._parse_limit()
|
|
3142
|
+
else:
|
|
3143
|
+
break
|
|
3144
|
+
|
|
3145
|
+
return self.expression(exp.Update, **kwargs)
|
|
3137
3146
|
|
|
3138
3147
|
def _parse_use(self) -> exp.Use:
|
|
3139
3148
|
return self.expression(
|
|
@@ -4236,9 +4245,11 @@ class Parser(metaclass=_Parser):
|
|
|
4236
4245
|
)
|
|
4237
4246
|
|
|
4238
4247
|
def _parse_unnest(self, with_alias: bool = True) -> t.Optional[exp.Unnest]:
|
|
4239
|
-
if not self.
|
|
4248
|
+
if not self._match_pair(TokenType.UNNEST, TokenType.L_PAREN, advance=False):
|
|
4240
4249
|
return None
|
|
4241
4250
|
|
|
4251
|
+
self._advance()
|
|
4252
|
+
|
|
4242
4253
|
expressions = self._parse_wrapped_csv(self._parse_equality)
|
|
4243
4254
|
offset = self._match_pair(TokenType.WITH, TokenType.ORDINALITY)
|
|
4244
4255
|
|
|
@@ -4613,7 +4624,7 @@ class Parser(metaclass=_Parser):
|
|
|
4613
4624
|
|
|
4614
4625
|
def _parse_grouping_set(self) -> t.Optional[exp.Expression]:
|
|
4615
4626
|
if self._match(TokenType.L_PAREN):
|
|
4616
|
-
grouping_set = self._parse_csv(self.
|
|
4627
|
+
grouping_set = self._parse_csv(self._parse_bitwise)
|
|
4617
4628
|
self._match_r_paren()
|
|
4618
4629
|
return self.expression(exp.Tuple, expressions=grouping_set)
|
|
4619
4630
|
|
|
@@ -5100,14 +5111,43 @@ class Parser(metaclass=_Parser):
|
|
|
5100
5111
|
isinstance(this, exp.Column)
|
|
5101
5112
|
and not this.table
|
|
5102
5113
|
and not this.this.quoted
|
|
5103
|
-
and
|
|
5114
|
+
and self._curr
|
|
5115
|
+
and self._curr.text.upper() not in self.dialect.VALID_INTERVAL_UNITS
|
|
5104
5116
|
):
|
|
5105
5117
|
self._retreat(index)
|
|
5106
5118
|
return None
|
|
5107
5119
|
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5120
|
+
# handle day-time format interval span with omitted units:
|
|
5121
|
+
# INTERVAL '<number days> hh[:][mm[:ss[.ff]]]' <maybe `unit TO unit`>
|
|
5122
|
+
interval_span_units_omitted = None
|
|
5123
|
+
if (
|
|
5124
|
+
this
|
|
5125
|
+
and this.is_string
|
|
5126
|
+
and self.SUPPORTS_OMITTED_INTERVAL_SPAN_UNIT
|
|
5127
|
+
and exp.INTERVAL_DAY_TIME_RE.match(this.name)
|
|
5128
|
+
):
|
|
5129
|
+
index = self._index
|
|
5130
|
+
|
|
5131
|
+
# Var "TO" Var
|
|
5132
|
+
first_unit = self._parse_var(any_token=True, upper=True)
|
|
5133
|
+
second_unit = None
|
|
5134
|
+
if first_unit and self._match_text_seq("TO"):
|
|
5135
|
+
second_unit = self._parse_var(any_token=True, upper=True)
|
|
5136
|
+
|
|
5137
|
+
interval_span_units_omitted = not (first_unit and second_unit)
|
|
5138
|
+
|
|
5139
|
+
self._retreat(index)
|
|
5140
|
+
|
|
5141
|
+
unit = (
|
|
5142
|
+
None
|
|
5143
|
+
if interval_span_units_omitted
|
|
5144
|
+
else (
|
|
5145
|
+
self._parse_function()
|
|
5146
|
+
or (
|
|
5147
|
+
not self._match(TokenType.ALIAS, advance=False)
|
|
5148
|
+
and self._parse_var(any_token=True, upper=True)
|
|
5149
|
+
)
|
|
5150
|
+
)
|
|
5111
5151
|
)
|
|
5112
5152
|
|
|
5113
5153
|
# Most dialects support, e.g., the form INTERVAL '5' day, thus we try to parse
|
|
@@ -5124,6 +5164,7 @@ class Parser(metaclass=_Parser):
|
|
|
5124
5164
|
if len(parts) == 1:
|
|
5125
5165
|
this = exp.Literal.string(parts[0][0])
|
|
5126
5166
|
unit = self.expression(exp.Var, this=parts[0][1].upper())
|
|
5167
|
+
|
|
5127
5168
|
if self.INTERVAL_SPANS and self._match_text_seq("TO"):
|
|
5128
5169
|
unit = self.expression(
|
|
5129
5170
|
exp.IntervalSpan, this=unit, expression=self._parse_var(any_token=True, upper=True)
|
|
@@ -5490,6 +5531,11 @@ class Parser(metaclass=_Parser):
|
|
|
5490
5531
|
|
|
5491
5532
|
type_token = unsigned_type_token or type_token
|
|
5492
5533
|
|
|
5534
|
+
# NULLABLE without parentheses can be a column (Presto/Trino)
|
|
5535
|
+
if type_token == TokenType.NULLABLE and not expressions:
|
|
5536
|
+
self._retreat(index)
|
|
5537
|
+
return None
|
|
5538
|
+
|
|
5493
5539
|
this = exp.DataType(
|
|
5494
5540
|
this=exp.DataType.Type[type_token.value],
|
|
5495
5541
|
expressions=expressions,
|
|
@@ -5760,6 +5806,10 @@ class Parser(metaclass=_Parser):
|
|
|
5760
5806
|
this.add_comments(comments)
|
|
5761
5807
|
|
|
5762
5808
|
self._match_r_paren(expression=this)
|
|
5809
|
+
|
|
5810
|
+
if isinstance(this, exp.Paren) and isinstance(this.this, exp.AggFunc):
|
|
5811
|
+
return self._parse_window(this)
|
|
5812
|
+
|
|
5763
5813
|
return this
|
|
5764
5814
|
|
|
5765
5815
|
def _parse_primary(self) -> t.Optional[exp.Expression]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlglot
|
|
3
|
-
Version: 27.
|
|
3
|
+
Version: 27.18.0
|
|
4
4
|
Summary: An easily customizable SQL parser and transpiler
|
|
5
5
|
Author-email: Toby Mao <toby.mao@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -39,7 +39,7 @@ Dynamic: provides-extra
|
|
|
39
39
|
|
|
40
40
|

|
|
41
41
|
|
|
42
|
-
SQLGlot is a no-dependency SQL parser, transpiler, optimizer, and engine. It can be used to format SQL or translate between [
|
|
42
|
+
SQLGlot is a no-dependency SQL parser, transpiler, optimizer, and engine. It can be used to format SQL or translate between [31 different dialects](https://github.com/tobymao/sqlglot/blob/main/sqlglot/dialects/__init__.py) like [DuckDB](https://duckdb.org/), [Presto](https://prestodb.io/) / [Trino](https://trino.io/), [Spark](https://spark.apache.org/) / [Databricks](https://www.databricks.com/), [Snowflake](https://www.snowflake.com/en/), and [BigQuery](https://cloud.google.com/bigquery/). It aims to read a wide variety of SQL inputs and output syntactically and semantically correct SQL in the targeted dialects.
|
|
43
43
|
|
|
44
44
|
It is a very comprehensive generic SQL parser with a robust [test suite](https://github.com/tobymao/sqlglot/blob/main/tests/). It is also quite [performant](#benchmarks), while being written purely in Python.
|
|
45
45
|
|
|
@@ -613,6 +613,7 @@ x + interval '1' month
|
|
|
613
613
|
| RisingWave | Community |
|
|
614
614
|
| SingleStore | Community |
|
|
615
615
|
| Snowflake | Official |
|
|
616
|
+
| Solr | Community |
|
|
616
617
|
| Spark | Official |
|
|
617
618
|
| SQLite | Official |
|
|
618
619
|
| StarRocks | Official |
|
|
@@ -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=7UxZQRE12m08A5rXKriqghWBW14eGYzdfIFlvSEPOcI,708
|
|
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=KEMqwokmUV8udKzoUAQlkjZJXV-FkwAJLmSOIpGt4_k,258058
|
|
8
|
+
sqlglot/generator.py,sha256=ZHFzi6_EOJl5V-dnz71QJOIwtxj66oJdF6tUQoxBpck,226436
|
|
9
9
|
sqlglot/helper.py,sha256=9nZjFVRBtMKFC3EdzpDQ6jkazFO19po6BF8xHiNGZIo,15111
|
|
10
10
|
sqlglot/jsonpath.py,sha256=SQgaxzaEYBN7At9dkTK4N1Spk6xHxvHL6QtCIP6iM30,7905
|
|
11
11
|
sqlglot/lineage.py,sha256=Qj5ykuDNcATppb9vOjoIKBqRVLbu3OMPiZk9f3iyv40,15312
|
|
12
|
-
sqlglot/parser.py,sha256=
|
|
12
|
+
sqlglot/parser.py,sha256=wlw73WjzXAHC9AH7Ezkfyeh134P97HheLPueCgXk4Mc,337292
|
|
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
|
|
@@ -18,31 +18,32 @@ sqlglot/time.py,sha256=Q62gv6kL40OiRBF6BMESxKJcMVn7ZLNw7sv8H34z5FI,18400
|
|
|
18
18
|
sqlglot/tokens.py,sha256=M6E-2vbIs41CYwyLIFtRqre9Mh9kO7Qt9rQvpfVeB7w,49217
|
|
19
19
|
sqlglot/transforms.py,sha256=utNDsCBsA7hPUK3-aby3DDgiY_XVMAKQqeoLm1EyihI,41218
|
|
20
20
|
sqlglot/trie.py,sha256=v27uXMrHfqrXlJ6GmeTSMovsB_3o0ctnlKhdNt7W6fI,2245
|
|
21
|
-
sqlglot/dialects/__init__.py,sha256=
|
|
21
|
+
sqlglot/dialects/__init__.py,sha256=g3HRtyb32r3LooiHKTzuUNB0_rBO_RauuOegp42gB48,3811
|
|
22
22
|
sqlglot/dialects/athena.py,sha256=ofArmayYLev4qZQ15GM8mevG04qqR5WGFb2ZcuYm6x4,10966
|
|
23
23
|
sqlglot/dialects/bigquery.py,sha256=9Q-oCXcpa2vrT2eMgVGHWwEvECMm4RQeV1XkjJj0nPA,72483
|
|
24
|
-
sqlglot/dialects/clickhouse.py,sha256=
|
|
24
|
+
sqlglot/dialects/clickhouse.py,sha256=6kx1cm0YhtHbg5kvcY64Hau2KdeC7Y26SVlVHGLyPEA,58579
|
|
25
25
|
sqlglot/dialects/databricks.py,sha256=H4QTq7gg6tJylKc_YWsGp6049KydoI_wlQUHM7iCJtI,4753
|
|
26
|
-
sqlglot/dialects/dialect.py,sha256=
|
|
26
|
+
sqlglot/dialects/dialect.py,sha256=KfBctpr7VdrCdHrP1Tk7CqAml53tRq9x-aDAkaN-9l0,73540
|
|
27
27
|
sqlglot/dialects/doris.py,sha256=CFnF955Oav3IjZWA80ickOI8tPpCjxk7BN5R4Z6pA1U,25263
|
|
28
28
|
sqlglot/dialects/dremio.py,sha256=nOMxu_4xVKSOmMGNSwdxXSPc243cNbbpb-xXzYdgdeg,8460
|
|
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=hLbLqkh5X5Nx3y5yfbBc5h9ye6UWTiZr_VsS4BMY5Rw,54612
|
|
32
32
|
sqlglot/dialects/dune.py,sha256=gALut-fFfN2qMsr8LvZ1NQK3F3W9z2f4PwMvTMXVVVg,375
|
|
33
33
|
sqlglot/dialects/exasol.py,sha256=ay3g_VyT5WvHTgNyJuCQu0nBt4bpllLZ9IdMBizEgYM,15761
|
|
34
34
|
sqlglot/dialects/fabric.py,sha256=BdkvzM8s-m5DIdBwdjEYskp32ub7aHCAex_xlhQn92I,10222
|
|
35
35
|
sqlglot/dialects/hive.py,sha256=UGIkXjMCk5a9ndUXQtvfG560oi3emdpqOYLQCmGabBk,32046
|
|
36
36
|
sqlglot/dialects/materialize.py,sha256=LD2q1kTRrCwkIu1BfoBvnjTGbupDtoQ8JQMDCIYAXHg,3533
|
|
37
|
-
sqlglot/dialects/mysql.py,sha256=
|
|
37
|
+
sqlglot/dialects/mysql.py,sha256=xxVAR-pXMljYCUioavP3nROtOqKmK4kfdp4WWXX7X9g,50049
|
|
38
38
|
sqlglot/dialects/oracle.py,sha256=zWPCpzGiTlgCJ5E6FjfX3Rszjcw4SnHg6xeVboMYIyo,15972
|
|
39
|
-
sqlglot/dialects/postgres.py,sha256=
|
|
39
|
+
sqlglot/dialects/postgres.py,sha256=_pXSu29684utgeuzPziSJ0Sw54WEIIunwLugJw7KFD8,34853
|
|
40
40
|
sqlglot/dialects/presto.py,sha256=XVeYr2NP86x5enlRqI7MYR6le85_ucYg_BBRocGN3jM,33413
|
|
41
41
|
sqlglot/dialects/prql.py,sha256=fwN-SPEGx-drwf1K0U2MByN-PkW3C_rOgQ3xeJeychg,7908
|
|
42
42
|
sqlglot/dialects/redshift.py,sha256=FIwtP3yEg-way9pa32kxCJc6IaFkHVIvgYKZA-Ilmi0,15919
|
|
43
43
|
sqlglot/dialects/risingwave.py,sha256=BqWwW1iT_OIVMwfRamaww79snnBwIgCfr22Go-ggO68,3289
|
|
44
44
|
sqlglot/dialects/singlestore.py,sha256=0QqNYOucNklPQuyeGcsisLI97qPGx_RfWKOFarJz2qw,61711
|
|
45
|
-
sqlglot/dialects/snowflake.py,sha256=
|
|
45
|
+
sqlglot/dialects/snowflake.py,sha256=RqCEW6nMXlkJ-XqS3W4HA-ZPSQTHv_bc_CMBTmvZJOk,78425
|
|
46
|
+
sqlglot/dialects/solr.py,sha256=pydnl4ml-3M1Fc4ALm6cMVO9h-5EtqZxPZH_91Nz1Ss,617
|
|
46
47
|
sqlglot/dialects/spark.py,sha256=PzyhkelDzbCMgJ3RVHD6yyzLIFp9NdZfwVas5IymowM,10147
|
|
47
48
|
sqlglot/dialects/spark2.py,sha256=qz36FT9k4iuiqboRpyG4VpKGkPR0P2fifmqgZ9gNUEU,14851
|
|
48
49
|
sqlglot/dialects/sqlite.py,sha256=zzXEbnaLjJeg6hPLHricjpfSkuf8tpXECnjcHtoqIbw,13263
|
|
@@ -74,10 +75,10 @@ sqlglot/optimizer/qualify.py,sha256=oAPfwub7dEkrlCrsptcJWpLya4BgKhN6M5SwIs_86LY,
|
|
|
74
75
|
sqlglot/optimizer/qualify_columns.py,sha256=7aabZhD-dKNiwIW_ZjOEr0RPbWfhSbuR-WI6NnVCZAA,45298
|
|
75
76
|
sqlglot/optimizer/qualify_tables.py,sha256=dA4ZazL7ShQh2JgBwpHuG-4c5lBw1TNzCnuN7m0iVTA,6645
|
|
76
77
|
sqlglot/optimizer/scope.py,sha256=UOTrbwqcTc5iRQf0WStgYWXpE24w6riZy-tJYA18yTw,31229
|
|
77
|
-
sqlglot/optimizer/simplify.py,sha256
|
|
78
|
+
sqlglot/optimizer/simplify.py,sha256=27IYsqbz1kyMlURSfRkm_ADSQJg-4805AOMFOjKKytU,51049
|
|
78
79
|
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.
|
|
80
|
+
sqlglot-27.18.0.dist-info/licenses/LICENSE,sha256=p1Yk0B4oa0l8Rh-_dYyy75d8spjPd_vTloXfz4FWxys,1065
|
|
81
|
+
sqlglot-27.18.0.dist-info/METADATA,sha256=UxjiFljC-bu1PB4zuYgt_3aWXJu36fhzoq05oQnH8jU,20703
|
|
82
|
+
sqlglot-27.18.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
83
|
+
sqlglot-27.18.0.dist-info/top_level.txt,sha256=5kRskCGA_gVADF9rSfSzPdLHXqvfMusDYeHePfNY2nQ,8
|
|
84
|
+
sqlglot-27.18.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|