sqlglot 28.4.1__py3-none-any.whl → 28.8.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 +20 -23
- sqlglot/dialects/clickhouse.py +2 -0
- sqlglot/dialects/dialect.py +355 -18
- sqlglot/dialects/doris.py +38 -90
- sqlglot/dialects/druid.py +1 -0
- sqlglot/dialects/duckdb.py +1739 -163
- sqlglot/dialects/exasol.py +17 -1
- sqlglot/dialects/hive.py +27 -2
- sqlglot/dialects/mysql.py +103 -11
- sqlglot/dialects/oracle.py +38 -1
- sqlglot/dialects/postgres.py +142 -33
- sqlglot/dialects/presto.py +6 -2
- sqlglot/dialects/redshift.py +7 -1
- sqlglot/dialects/singlestore.py +13 -3
- sqlglot/dialects/snowflake.py +271 -21
- sqlglot/dialects/spark.py +25 -0
- sqlglot/dialects/spark2.py +4 -3
- sqlglot/dialects/starrocks.py +152 -17
- sqlglot/dialects/trino.py +1 -0
- sqlglot/dialects/tsql.py +5 -0
- sqlglot/diff.py +1 -1
- sqlglot/expressions.py +239 -47
- sqlglot/generator.py +173 -44
- sqlglot/optimizer/annotate_types.py +129 -60
- sqlglot/optimizer/merge_subqueries.py +13 -2
- sqlglot/optimizer/qualify_columns.py +7 -0
- sqlglot/optimizer/resolver.py +19 -0
- sqlglot/optimizer/scope.py +12 -0
- sqlglot/optimizer/unnest_subqueries.py +7 -0
- sqlglot/parser.py +251 -58
- sqlglot/schema.py +186 -14
- sqlglot/tokens.py +36 -6
- sqlglot/transforms.py +6 -5
- sqlglot/typing/__init__.py +29 -10
- sqlglot/typing/bigquery.py +5 -10
- sqlglot/typing/duckdb.py +39 -0
- sqlglot/typing/hive.py +50 -1
- sqlglot/typing/mysql.py +32 -0
- sqlglot/typing/presto.py +0 -1
- sqlglot/typing/snowflake.py +80 -17
- sqlglot/typing/spark.py +29 -0
- sqlglot/typing/spark2.py +9 -1
- sqlglot/typing/tsql.py +21 -0
- {sqlglot-28.4.1.dist-info → sqlglot-28.8.0.dist-info}/METADATA +47 -2
- sqlglot-28.8.0.dist-info/RECORD +95 -0
- {sqlglot-28.4.1.dist-info → sqlglot-28.8.0.dist-info}/WHEEL +1 -1
- sqlglot-28.4.1.dist-info/RECORD +0 -92
- {sqlglot-28.4.1.dist-info → sqlglot-28.8.0.dist-info}/licenses/LICENSE +0 -0
- {sqlglot-28.4.1.dist-info → sqlglot-28.8.0.dist-info}/top_level.txt +0 -0
sqlglot/typing/duckdb.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from sqlglot import exp
|
|
4
|
+
from sqlglot.typing import EXPRESSION_METADATA
|
|
5
|
+
|
|
6
|
+
EXPRESSION_METADATA = {
|
|
7
|
+
**EXPRESSION_METADATA,
|
|
8
|
+
**{
|
|
9
|
+
expr_type: {"returns": exp.DataType.Type.BIGINT}
|
|
10
|
+
for expr_type in {
|
|
11
|
+
exp.Quarter,
|
|
12
|
+
exp.Week,
|
|
13
|
+
exp.Year,
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
**{
|
|
17
|
+
expr_type: {"returns": exp.DataType.Type.INT128}
|
|
18
|
+
for expr_type in {
|
|
19
|
+
exp.Factorial,
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
**{
|
|
23
|
+
expr_type: {"returns": exp.DataType.Type.DOUBLE}
|
|
24
|
+
for expr_type in {
|
|
25
|
+
exp.Acosh,
|
|
26
|
+
exp.Asinh,
|
|
27
|
+
exp.Atanh,
|
|
28
|
+
exp.Atan2,
|
|
29
|
+
exp.Acos,
|
|
30
|
+
exp.Asin,
|
|
31
|
+
exp.Atan,
|
|
32
|
+
exp.Cos,
|
|
33
|
+
exp.Cot,
|
|
34
|
+
exp.Rand,
|
|
35
|
+
exp.Sin,
|
|
36
|
+
exp.Tan,
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
}
|
sqlglot/typing/hive.py
CHANGED
|
@@ -5,8 +5,57 @@ from sqlglot.typing import EXPRESSION_METADATA
|
|
|
5
5
|
|
|
6
6
|
EXPRESSION_METADATA = {
|
|
7
7
|
**EXPRESSION_METADATA,
|
|
8
|
-
|
|
8
|
+
**{
|
|
9
|
+
expr_type: {"returns": exp.DataType.Type.BINARY}
|
|
10
|
+
for expr_type in {
|
|
11
|
+
exp.Encode,
|
|
12
|
+
exp.Unhex,
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
**{
|
|
16
|
+
expr_type: {"returns": exp.DataType.Type.DOUBLE}
|
|
17
|
+
for expr_type in {
|
|
18
|
+
exp.Asin,
|
|
19
|
+
exp.Acos,
|
|
20
|
+
exp.Atan,
|
|
21
|
+
exp.Corr,
|
|
22
|
+
exp.Cos,
|
|
23
|
+
exp.Cosh,
|
|
24
|
+
exp.MonthsBetween,
|
|
25
|
+
exp.Sin,
|
|
26
|
+
exp.Sinh,
|
|
27
|
+
exp.Tan,
|
|
28
|
+
exp.Tanh,
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
**{
|
|
32
|
+
expr_type: {"returns": exp.DataType.Type.VARCHAR}
|
|
33
|
+
for expr_type in {
|
|
34
|
+
exp.CurrentCatalog,
|
|
35
|
+
exp.CurrentDatabase,
|
|
36
|
+
exp.CurrentSchema,
|
|
37
|
+
exp.CurrentUser,
|
|
38
|
+
exp.Hex,
|
|
39
|
+
exp.MD5,
|
|
40
|
+
exp.Soundex,
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
**{
|
|
44
|
+
expr_type: {"returns": exp.DataType.Type.BIGINT}
|
|
45
|
+
for expr_type in {
|
|
46
|
+
exp.StrToUnix,
|
|
47
|
+
exp.Factorial,
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
**{
|
|
51
|
+
expr_type: {"returns": exp.DataType.Type.INT}
|
|
52
|
+
for expr_type in {
|
|
53
|
+
exp.Month,
|
|
54
|
+
exp.Second,
|
|
55
|
+
}
|
|
56
|
+
},
|
|
9
57
|
exp.Coalesce: {
|
|
10
58
|
"annotator": lambda self, e: self._annotate_by_args(e, "this", "expressions", promote=True)
|
|
11
59
|
},
|
|
60
|
+
exp.If: {"annotator": lambda self, e: self._annotate_by_args(e, "true", "false", promote=True)},
|
|
12
61
|
}
|
sqlglot/typing/mysql.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from sqlglot import exp
|
|
4
|
+
from sqlglot.typing import EXPRESSION_METADATA
|
|
5
|
+
|
|
6
|
+
EXPRESSION_METADATA = {
|
|
7
|
+
**EXPRESSION_METADATA,
|
|
8
|
+
**{
|
|
9
|
+
expr_type: {"returns": exp.DataType.Type.DOUBLE}
|
|
10
|
+
for expr_type in {
|
|
11
|
+
exp.Acos,
|
|
12
|
+
exp.Asin,
|
|
13
|
+
exp.Atan,
|
|
14
|
+
exp.Atan2,
|
|
15
|
+
exp.Cos,
|
|
16
|
+
exp.Cot,
|
|
17
|
+
exp.Degrees,
|
|
18
|
+
exp.Sin,
|
|
19
|
+
exp.Tan,
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
**{expr_type: {"returns": exp.DataType.Type.VARCHAR} for expr_type in (exp.Elt,)},
|
|
23
|
+
**{
|
|
24
|
+
expr_type: {"returns": exp.DataType.Type.INT}
|
|
25
|
+
for expr_type in {
|
|
26
|
+
exp.DayOfWeek,
|
|
27
|
+
exp.Month,
|
|
28
|
+
exp.Second,
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
exp.Localtime: {"returns": exp.DataType.Type.DATETIME},
|
|
32
|
+
}
|
sqlglot/typing/presto.py
CHANGED
sqlglot/typing/snowflake.py
CHANGED
|
@@ -180,6 +180,29 @@ def _annotate_variance(self: TypeAnnotator, expression: exp.Expression) -> exp.E
|
|
|
180
180
|
return expression
|
|
181
181
|
|
|
182
182
|
|
|
183
|
+
def _annotate_kurtosis(self: TypeAnnotator, expression: exp.Kurtosis) -> exp.Kurtosis:
|
|
184
|
+
"""Annotate KURTOSIS with correct return type.
|
|
185
|
+
|
|
186
|
+
Based on Snowflake behavior:
|
|
187
|
+
- DECFLOAT input -> DECFLOAT
|
|
188
|
+
- DOUBLE or FLOAT input -> DOUBLE
|
|
189
|
+
- Other numeric types (INT, NUMBER) -> NUMBER(38, 12)
|
|
190
|
+
"""
|
|
191
|
+
expression = self._annotate_by_args(expression, "this")
|
|
192
|
+
input_type = expression.this.type
|
|
193
|
+
|
|
194
|
+
if input_type.is_type(exp.DataType.Type.DECFLOAT):
|
|
195
|
+
self._set_type(expression, exp.DataType.build("DECFLOAT", dialect="snowflake"))
|
|
196
|
+
elif input_type.is_type(exp.DataType.Type.FLOAT, exp.DataType.Type.DOUBLE):
|
|
197
|
+
self._set_type(expression, exp.DataType.Type.DOUBLE)
|
|
198
|
+
else:
|
|
199
|
+
self._set_type(
|
|
200
|
+
expression, exp.DataType.build(f"NUMBER({MAX_PRECISION}, 12)", dialect="snowflake")
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
return expression
|
|
204
|
+
|
|
205
|
+
|
|
183
206
|
def _annotate_math_with_float_decfloat(
|
|
184
207
|
self: TypeAnnotator, expression: exp.Expression
|
|
185
208
|
) -> exp.Expression:
|
|
@@ -202,6 +225,18 @@ def _annotate_math_with_float_decfloat(
|
|
|
202
225
|
return expression
|
|
203
226
|
|
|
204
227
|
|
|
228
|
+
def _annotate_str_to_time(self: TypeAnnotator, expression: exp.StrToTime) -> exp.StrToTime:
|
|
229
|
+
# target_type is stored as a DataType instance
|
|
230
|
+
target_type_arg = expression.args.get("target_type")
|
|
231
|
+
target_type = (
|
|
232
|
+
target_type_arg.this
|
|
233
|
+
if isinstance(target_type_arg, exp.DataType)
|
|
234
|
+
else exp.DataType.Type.TIMESTAMP
|
|
235
|
+
)
|
|
236
|
+
self._set_type(expression, target_type)
|
|
237
|
+
return expression
|
|
238
|
+
|
|
239
|
+
|
|
205
240
|
EXPRESSION_METADATA = {
|
|
206
241
|
**EXPRESSION_METADATA,
|
|
207
242
|
**{
|
|
@@ -227,10 +262,18 @@ EXPRESSION_METADATA = {
|
|
|
227
262
|
for expr_type in (
|
|
228
263
|
exp.ApproxTopK,
|
|
229
264
|
exp.ApproxTopKEstimate,
|
|
265
|
+
exp.Array,
|
|
230
266
|
exp.ArrayAgg,
|
|
267
|
+
exp.ArrayAppend,
|
|
268
|
+
exp.ArrayCompact,
|
|
269
|
+
exp.ArrayConcat,
|
|
231
270
|
exp.ArrayConstructCompact,
|
|
271
|
+
exp.ArrayPrepend,
|
|
272
|
+
exp.ArrayRemove,
|
|
273
|
+
exp.ArraysZip,
|
|
232
274
|
exp.ArrayUniqueAgg,
|
|
233
275
|
exp.ArrayUnionAgg,
|
|
276
|
+
exp.MapKeys,
|
|
234
277
|
exp.RegexpExtractAll,
|
|
235
278
|
exp.Split,
|
|
236
279
|
exp.StringToArray,
|
|
@@ -247,6 +290,7 @@ EXPRESSION_METADATA = {
|
|
|
247
290
|
exp.MD5NumberLower64,
|
|
248
291
|
exp.MD5NumberUpper64,
|
|
249
292
|
exp.Rand,
|
|
293
|
+
exp.Seq8,
|
|
250
294
|
exp.Zipf,
|
|
251
295
|
}
|
|
252
296
|
},
|
|
@@ -258,6 +302,10 @@ EXPRESSION_METADATA = {
|
|
|
258
302
|
exp.BitmapOrAgg,
|
|
259
303
|
exp.Compress,
|
|
260
304
|
exp.DecompressBinary,
|
|
305
|
+
exp.Decrypt,
|
|
306
|
+
exp.DecryptRaw,
|
|
307
|
+
exp.Encrypt,
|
|
308
|
+
exp.EncryptRaw,
|
|
261
309
|
exp.HexString,
|
|
262
310
|
exp.MD5Digest,
|
|
263
311
|
exp.SHA1Digest,
|
|
@@ -277,6 +325,7 @@ EXPRESSION_METADATA = {
|
|
|
277
325
|
exp.BoolxorAgg,
|
|
278
326
|
exp.EqualNull,
|
|
279
327
|
exp.IsNullValue,
|
|
328
|
+
exp.MapContainsKey,
|
|
280
329
|
exp.Search,
|
|
281
330
|
exp.SearchIp,
|
|
282
331
|
exp.ToBoolean,
|
|
@@ -311,9 +360,10 @@ EXPRESSION_METADATA = {
|
|
|
311
360
|
exp.ApproximateSimilarity,
|
|
312
361
|
exp.Asinh,
|
|
313
362
|
exp.Atanh,
|
|
314
|
-
exp.Cbrt,
|
|
315
363
|
exp.Cosh,
|
|
316
364
|
exp.CosineDistance,
|
|
365
|
+
exp.CovarPop,
|
|
366
|
+
exp.CovarSamp,
|
|
317
367
|
exp.DotProduct,
|
|
318
368
|
exp.EuclideanDistance,
|
|
319
369
|
exp.ManhattanDistance,
|
|
@@ -322,6 +372,7 @@ EXPRESSION_METADATA = {
|
|
|
322
372
|
exp.Sinh,
|
|
323
373
|
}
|
|
324
374
|
},
|
|
375
|
+
exp.Kurtosis: {"annotator": _annotate_kurtosis},
|
|
325
376
|
**{
|
|
326
377
|
expr_type: {"returns": exp.DataType.Type.DECFLOAT}
|
|
327
378
|
for expr_type in {
|
|
@@ -336,6 +387,7 @@ EXPRESSION_METADATA = {
|
|
|
336
387
|
exp.Asin,
|
|
337
388
|
exp.Atan,
|
|
338
389
|
exp.Atan2,
|
|
390
|
+
exp.Cbrt,
|
|
339
391
|
exp.Cos,
|
|
340
392
|
exp.Cot,
|
|
341
393
|
exp.Degrees,
|
|
@@ -364,20 +416,17 @@ EXPRESSION_METADATA = {
|
|
|
364
416
|
**{
|
|
365
417
|
expr_type: {"returns": exp.DataType.Type.INT}
|
|
366
418
|
for expr_type in {
|
|
367
|
-
exp.Ascii,
|
|
368
|
-
exp.BitLength,
|
|
369
419
|
exp.ByteLength,
|
|
370
|
-
exp.Getbit,
|
|
371
420
|
exp.Grouping,
|
|
372
421
|
exp.Hour,
|
|
373
422
|
exp.JarowinklerSimilarity,
|
|
374
|
-
exp.
|
|
375
|
-
exp.Levenshtein,
|
|
423
|
+
exp.MapSize,
|
|
376
424
|
exp.Minute,
|
|
377
425
|
exp.RtrimmedLength,
|
|
378
426
|
exp.Second,
|
|
379
|
-
exp.
|
|
380
|
-
exp.
|
|
427
|
+
exp.Seq1,
|
|
428
|
+
exp.Seq2,
|
|
429
|
+
exp.Seq4,
|
|
381
430
|
exp.WidthBucket,
|
|
382
431
|
}
|
|
383
432
|
},
|
|
@@ -394,6 +443,15 @@ EXPRESSION_METADATA = {
|
|
|
394
443
|
exp.XMLGet,
|
|
395
444
|
}
|
|
396
445
|
},
|
|
446
|
+
**{
|
|
447
|
+
expr_type: {"returns": exp.DataType.Type.MAP}
|
|
448
|
+
for expr_type in {
|
|
449
|
+
exp.MapCat,
|
|
450
|
+
exp.MapDelete,
|
|
451
|
+
exp.MapInsert,
|
|
452
|
+
exp.MapPick,
|
|
453
|
+
}
|
|
454
|
+
},
|
|
397
455
|
**{
|
|
398
456
|
expr_type: {"returns": exp.DataType.Type.FILE}
|
|
399
457
|
for expr_type in {
|
|
@@ -407,6 +465,19 @@ EXPRESSION_METADATA = {
|
|
|
407
465
|
exp.TsOrDsToTime,
|
|
408
466
|
}
|
|
409
467
|
},
|
|
468
|
+
**{
|
|
469
|
+
expr_type: {"returns": exp.DataType.Type.TIMESTAMPLTZ}
|
|
470
|
+
for expr_type in {
|
|
471
|
+
exp.CurrentTimestamp,
|
|
472
|
+
exp.Localtimestamp,
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
**{
|
|
476
|
+
expr_type: {"returns": exp.DataType.Type.TINYINT}
|
|
477
|
+
for expr_type in {
|
|
478
|
+
exp.Quarter,
|
|
479
|
+
}
|
|
480
|
+
},
|
|
410
481
|
**{
|
|
411
482
|
expr_type: {"returns": exp.DataType.Type.VARCHAR}
|
|
412
483
|
for expr_type in {
|
|
@@ -417,7 +488,6 @@ EXPRESSION_METADATA = {
|
|
|
417
488
|
exp.Base64Encode,
|
|
418
489
|
exp.CheckJson,
|
|
419
490
|
exp.CheckXml,
|
|
420
|
-
exp.Chr,
|
|
421
491
|
exp.Collate,
|
|
422
492
|
exp.Collation,
|
|
423
493
|
exp.CurrentAccount,
|
|
@@ -441,7 +511,6 @@ EXPRESSION_METADATA = {
|
|
|
441
511
|
exp.DecompressString,
|
|
442
512
|
exp.HexDecodeString,
|
|
443
513
|
exp.HexEncode,
|
|
444
|
-
exp.Initcap,
|
|
445
514
|
exp.MD5,
|
|
446
515
|
exp.Monthname,
|
|
447
516
|
exp.Randstr,
|
|
@@ -449,11 +518,8 @@ EXPRESSION_METADATA = {
|
|
|
449
518
|
exp.RegexpReplace,
|
|
450
519
|
exp.Repeat,
|
|
451
520
|
exp.Replace,
|
|
452
|
-
exp.SHA,
|
|
453
|
-
exp.SHA2,
|
|
454
521
|
exp.Soundex,
|
|
455
522
|
exp.SoundexP123,
|
|
456
|
-
exp.Space,
|
|
457
523
|
exp.SplitPart,
|
|
458
524
|
exp.Translate,
|
|
459
525
|
exp.TryBase64DecodeString,
|
|
@@ -488,17 +554,14 @@ EXPRESSION_METADATA = {
|
|
|
488
554
|
},
|
|
489
555
|
exp.DateAdd: {"annotator": _annotate_date_or_time_add},
|
|
490
556
|
exp.DecodeCase: {"annotator": _annotate_decode_case},
|
|
491
|
-
exp.GreatestIgnoreNulls: {
|
|
492
|
-
"annotator": lambda self, e: self._annotate_by_args(e, "expressions")
|
|
493
|
-
},
|
|
494
557
|
exp.HashAgg: {
|
|
495
558
|
"annotator": lambda self, e: self._set_type(
|
|
496
559
|
e, exp.DataType.build("NUMBER(19, 0)", dialect="snowflake")
|
|
497
560
|
)
|
|
498
561
|
},
|
|
499
|
-
exp.LeastIgnoreNulls: {"annotator": lambda self, e: self._annotate_by_args(e, "expressions")},
|
|
500
562
|
exp.Median: {"annotator": _annotate_median},
|
|
501
563
|
exp.Reverse: {"annotator": _annotate_reverse},
|
|
564
|
+
exp.StrToTime: {"annotator": _annotate_str_to_time},
|
|
502
565
|
exp.TimeAdd: {"annotator": _annotate_date_or_time_add},
|
|
503
566
|
exp.TimestampFromParts: {"annotator": _annotate_timestamp_from_parts},
|
|
504
567
|
exp.WithinGroup: {"annotator": _annotate_within_group},
|
sqlglot/typing/spark.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from sqlglot import exp
|
|
4
|
+
from sqlglot.typing.spark2 import EXPRESSION_METADATA
|
|
5
|
+
|
|
6
|
+
EXPRESSION_METADATA = {
|
|
7
|
+
**EXPRESSION_METADATA,
|
|
8
|
+
**{
|
|
9
|
+
exp_type: {"returns": exp.DataType.Type.DOUBLE}
|
|
10
|
+
for exp_type in {
|
|
11
|
+
exp.Acosh,
|
|
12
|
+
exp.Asinh,
|
|
13
|
+
exp.Atanh,
|
|
14
|
+
exp.Sec,
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
**{
|
|
18
|
+
exp_type: {"returns": exp.DataType.Type.VARCHAR}
|
|
19
|
+
for exp_type in {
|
|
20
|
+
exp.CurrentTimezone,
|
|
21
|
+
exp.Monthname,
|
|
22
|
+
exp.SessionUser,
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
exp.Localtimestamp: {"returns": exp.DataType.Type.TIMESTAMPNTZ},
|
|
26
|
+
exp.ToBinary: {"returns": exp.DataType.Type.BINARY},
|
|
27
|
+
exp.DateFromUnixDate: {"returns": exp.DataType.Type.DATE},
|
|
28
|
+
exp.ArraySize: {"returns": exp.DataType.Type.INT},
|
|
29
|
+
}
|
sqlglot/typing/spark2.py
CHANGED
|
@@ -44,7 +44,14 @@ def _annotate_by_similar_args(
|
|
|
44
44
|
|
|
45
45
|
EXPRESSION_METADATA: ExpressionMetadataType = {
|
|
46
46
|
**HIVE_EXPRESSION_METADATA,
|
|
47
|
-
|
|
47
|
+
**{
|
|
48
|
+
expr_type: {"returns": exp.DataType.Type.DOUBLE}
|
|
49
|
+
for expr_type in {
|
|
50
|
+
exp.Atan2,
|
|
51
|
+
exp.Cot,
|
|
52
|
+
exp.Randn,
|
|
53
|
+
}
|
|
54
|
+
},
|
|
48
55
|
exp.Concat: {
|
|
49
56
|
"annotator": lambda self, e: _annotate_by_similar_args(
|
|
50
57
|
self, e, "expressions", target_type=exp.DataType.Type.TEXT
|
|
@@ -55,4 +62,5 @@ EXPRESSION_METADATA: ExpressionMetadataType = {
|
|
|
55
62
|
self, e, "this", "fill_pattern", target_type=exp.DataType.Type.TEXT
|
|
56
63
|
)
|
|
57
64
|
},
|
|
65
|
+
exp.Substring: {"annotator": lambda self, e: self._annotate_by_args(e, "this")},
|
|
58
66
|
}
|
sqlglot/typing/tsql.py
CHANGED
|
@@ -5,5 +5,26 @@ from sqlglot.typing import EXPRESSION_METADATA
|
|
|
5
5
|
|
|
6
6
|
EXPRESSION_METADATA = {
|
|
7
7
|
**EXPRESSION_METADATA,
|
|
8
|
+
**{
|
|
9
|
+
expr_type: {"returns": exp.DataType.Type.FLOAT}
|
|
10
|
+
for expr_type in {
|
|
11
|
+
exp.Acos,
|
|
12
|
+
exp.Asin,
|
|
13
|
+
exp.Atan,
|
|
14
|
+
exp.Atan2,
|
|
15
|
+
exp.Cos,
|
|
16
|
+
exp.Cot,
|
|
17
|
+
exp.Sin,
|
|
18
|
+
exp.Tan,
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
**{
|
|
22
|
+
expr_type: {"returns": exp.DataType.Type.VARCHAR}
|
|
23
|
+
for expr_type in {
|
|
24
|
+
exp.Soundex,
|
|
25
|
+
exp.Stuff,
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
exp.CurrentTimezone: {"returns": exp.DataType.Type.NVARCHAR},
|
|
8
29
|
exp.Radians: {"annotator": lambda self, e: self._annotate_by_args(e, "this")},
|
|
9
30
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlglot
|
|
3
|
-
Version: 28.
|
|
3
|
+
Version: 28.8.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
|
|
@@ -33,7 +33,7 @@ Requires-Dist: typing_extensions; extra == "dev"
|
|
|
33
33
|
Requires-Dist: maturin<2.0,>=1.4; extra == "dev"
|
|
34
34
|
Requires-Dist: pyperf; extra == "dev"
|
|
35
35
|
Provides-Extra: rs
|
|
36
|
-
Requires-Dist: sqlglotrs==0.
|
|
36
|
+
Requires-Dist: sqlglotrs==0.12.0; extra == "rs"
|
|
37
37
|
Dynamic: license-file
|
|
38
38
|
Dynamic: provides-extra
|
|
39
39
|
|
|
@@ -71,6 +71,7 @@ Contributions are very welcome in SQLGlot; read the [contribution guide](https:/
|
|
|
71
71
|
* [Used By](#used-by)
|
|
72
72
|
* [Documentation](#documentation)
|
|
73
73
|
* [Run Tests and Lint](#run-tests-and-lint)
|
|
74
|
+
* [Deployment](#deployment)
|
|
74
75
|
* [Benchmarks](#benchmarks)
|
|
75
76
|
* [Optional Dependencies](#optional-dependencies)
|
|
76
77
|
* [Supported Dialects](#supported-dialects)
|
|
@@ -565,6 +566,21 @@ make test # Unit and integration tests (or test-rs, to use the Rust tokenizer)
|
|
|
565
566
|
make check # Full test suite & linter checks
|
|
566
567
|
```
|
|
567
568
|
|
|
569
|
+
## Deployment
|
|
570
|
+
|
|
571
|
+
To deploy a new SQLGlot version, follow these steps:
|
|
572
|
+
|
|
573
|
+
1. Run `git pull` to make sure the local git repo is at the head of the main branch
|
|
574
|
+
2. If the Rust tokenizer code changed since the last version release:
|
|
575
|
+
1. Bump the `version` attribute under the `package` header in `sqlglotrs/Cargo.toml`
|
|
576
|
+
2. Run `make install-dev`. This will update the `Cargo.lock` file
|
|
577
|
+
3. Commit the changes made to `Cargo.toml` and `Cargo.lock`
|
|
578
|
+
3. Do a `git tag` operation to bump the SQLGlot version, e.g. `git tag v28.5.0`
|
|
579
|
+
4. Run `git push && git push --tags` to deploy the new version
|
|
580
|
+
|
|
581
|
+
> [!IMPORTANT]
|
|
582
|
+
> If there are any breaking changes since the last version release, make sure to deploy either a minor or major version for both sqlglot and sqlglotrs. Refer to SQLGlot's [versioning scheme](#versioning) for more information.
|
|
583
|
+
|
|
568
584
|
## Benchmarks
|
|
569
585
|
|
|
570
586
|
[Benchmarks](https://github.com/tobymao/sqlglot/blob/main/benchmarks/bench.py) run on Python 3.10.12 in seconds.
|
|
@@ -623,7 +639,36 @@ x + interval '1' month
|
|
|
623
639
|
| Teradata | Community |
|
|
624
640
|
| Trino | Official |
|
|
625
641
|
| TSQL | Official |
|
|
642
|
+
| YDB | [Plugin](https://pypi.org/project/ydb-sqlglot-plugin) |
|
|
626
643
|
|
|
627
644
|
**Official Dialects** are maintained by the core SQLGlot team with higher priority for bug fixes and feature additions.
|
|
628
645
|
|
|
629
646
|
**Community Dialects** are developed and maintained primarily through community contributions. These are fully functional but may receive lower priority for issue resolution compared to officially supported dialects. We welcome and encourage community contributions to improve these dialects.
|
|
647
|
+
|
|
648
|
+
**Plugin Dialects** (supported since v28.6.0) are third-party dialects developed and maintained in external repositories by independent contributors. These dialects are not part of the SQLGlot codebase and are distributed as separate packages. The SQLGlot team does not provide support or maintenance for plugin dialects — please direct any issues or feature requests to their respective repositories. See [Creating a Dialect Plugin](#creating-a-dialect-plugin) below for information on how to build your own.
|
|
649
|
+
|
|
650
|
+
### Creating a Dialect Plugin
|
|
651
|
+
|
|
652
|
+
If your database isn't supported, you can create a plugin that registers a custom dialect via entry points. Create a package with your dialect class and register it in `setup.py`:
|
|
653
|
+
|
|
654
|
+
```python
|
|
655
|
+
from setuptools import setup
|
|
656
|
+
|
|
657
|
+
setup(
|
|
658
|
+
name="mydb-sqlglot-dialect",
|
|
659
|
+
entry_points={
|
|
660
|
+
"sqlglot.dialects": [
|
|
661
|
+
"mydb = my_package.dialect:MyDB",
|
|
662
|
+
],
|
|
663
|
+
},
|
|
664
|
+
)
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
The dialect will be automatically discovered and can be used like any built-in dialect:
|
|
668
|
+
|
|
669
|
+
```python
|
|
670
|
+
from sqlglot import transpile
|
|
671
|
+
transpile("SELECT * FROM t", read="mydb", write="postgres")
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
See the [Custom Dialects](#custom-dialects) section for implementation details.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
sqlglot/__init__.py,sha256=XtHbbz93ughtCoKNYTbB8UftQvN5Bzt8fJZcD09ZcM8,5423
|
|
2
|
+
sqlglot/__main__.py,sha256=uYiSNtOBgBjXkUIv1Db_EAq3822deKKfYjSc-uV6i-g,2179
|
|
3
|
+
sqlglot/_typing.py,sha256=-1HPyr3w5COlSJWqlgt8jhFk2dyMvBuvVBqIX1wyVCM,642
|
|
4
|
+
sqlglot/_version.py,sha256=N0TE9KUUD9_c50pn_-ok9jZCQRdvesIfo6WNiTM9I_k,706
|
|
5
|
+
sqlglot/diff.py,sha256=LgBNRYKvQW_dxOLv8JNwsHleKcwbkIyqMs0xnMbG3Eo,17371
|
|
6
|
+
sqlglot/errors.py,sha256=vE7dVGl8e21IyyVXq2j1S7HVwi6Y9mLEQfJe0GcR15s,4880
|
|
7
|
+
sqlglot/expressions.py,sha256=hNYzuW3ogcuME3zuyW8SYtAr-Zx_cAIlTc1Y9FSFpME,278479
|
|
8
|
+
sqlglot/generator.py,sha256=HDGOkCx_1_fV8HMUKBLgdc-W5a3SUfaV_qnanv_RU00,237807
|
|
9
|
+
sqlglot/helper.py,sha256=lCN5MS-SHGvipfRL8OI-Tr5_EpYVtipgdNz_MtnfHMg,13420
|
|
10
|
+
sqlglot/jsonpath.py,sha256=SQgaxzaEYBN7At9dkTK4N1Spk6xHxvHL6QtCIP6iM30,7905
|
|
11
|
+
sqlglot/lineage.py,sha256=OsJXG4tsXCkG-0RhU-EQTaTUUBgLimzbKJ-YC4yScqQ,15489
|
|
12
|
+
sqlglot/parser.py,sha256=CK6zZhS2NksqQ0DZXlUJ4Btp-Nr5EgRDTjGYZXmMxUI,350376
|
|
13
|
+
sqlglot/planner.py,sha256=9CHWo9WO0wr1NgqrwW1Uc66D52CcFbK3r8GogiPpU6g,14636
|
|
14
|
+
sqlglot/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
sqlglot/schema.py,sha256=fKjB2sEtn18X3UCLFFvSdGJwq4TtaK2AEFERa8qr5LU,26625
|
|
16
|
+
sqlglot/serde.py,sha256=nWpBFUjwZh06Li4qBuNb0YRU_QyflzSVyWkFxujM0WM,3175
|
|
17
|
+
sqlglot/time.py,sha256=Q62gv6kL40OiRBF6BMESxKJcMVn7ZLNw7sv8H34z5FI,18400
|
|
18
|
+
sqlglot/tokens.py,sha256=8qzIvg7VO-xN4yE8msL9S6VmRpt66-ExvGqIMWBeNLI,51606
|
|
19
|
+
sqlglot/transforms.py,sha256=hHiTO_RK-HEgiLdiLGMGUHkKHHIJqK-JadRIQ4AlwCQ,42361
|
|
20
|
+
sqlglot/trie.py,sha256=v27uXMrHfqrXlJ6GmeTSMovsB_3o0ctnlKhdNt7W6fI,2245
|
|
21
|
+
sqlglot/dialects/__init__.py,sha256=g3HRtyb32r3LooiHKTzuUNB0_rBO_RauuOegp42gB48,3811
|
|
22
|
+
sqlglot/dialects/athena.py,sha256=ofArmayYLev4qZQ15GM8mevG04qqR5WGFb2ZcuYm6x4,10966
|
|
23
|
+
sqlglot/dialects/bigquery.py,sha256=HV9lyUjlUCBpkbzorKx-YZCEqwJEUT4myn0o-8pzZFU,62125
|
|
24
|
+
sqlglot/dialects/clickhouse.py,sha256=1_wODM-WhHbCk7uqqme77x2fhZSoHHLrHq0fEk84UoY,61334
|
|
25
|
+
sqlglot/dialects/databricks.py,sha256=Cf_f6IYzwb0Ifkwu3ReX6Dm3tCVRMzSooWhwFI8Bj3Y,6216
|
|
26
|
+
sqlglot/dialects/dialect.py,sha256=P0rTDgOY-ylzMZ1J2-gYPxcubd3GDusmPwmWf3Zlecw,91422
|
|
27
|
+
sqlglot/dialects/doris.py,sha256=S5d4NX54UEPeA8fjirjduJpTPhg0JmIRpeTsPmsg7ag,22045
|
|
28
|
+
sqlglot/dialects/dremio.py,sha256=aQyWE40L1XkowP1G3RxCOZAsdOZLR8VR2M83lo5nayc,8552
|
|
29
|
+
sqlglot/dialects/drill.py,sha256=FOh7_KjPx_77pv0DiHKZog0CcmzqeF9_PEmGnJ1ESSM,5825
|
|
30
|
+
sqlglot/dialects/druid.py,sha256=BvD68THTsTX4w7Ig9Xpxhb5bbSkocJ8KFicpG8RutdE,762
|
|
31
|
+
sqlglot/dialects/duckdb.py,sha256=rfqjQfws72IVz1RFDxXFdVDPwt1RcSQiC6wpJlPbZNw,151929
|
|
32
|
+
sqlglot/dialects/dune.py,sha256=gALut-fFfN2qMsr8LvZ1NQK3F3W9z2f4PwMvTMXVVVg,375
|
|
33
|
+
sqlglot/dialects/exasol.py,sha256=nb7GfFsB7mn0VaMrnKt0k2CXRwmw3eYinoGIHV-CPwg,25326
|
|
34
|
+
sqlglot/dialects/fabric.py,sha256=BdkvzM8s-m5DIdBwdjEYskp32ub7aHCAex_xlhQn92I,10222
|
|
35
|
+
sqlglot/dialects/hive.py,sha256=FLT27S5Xf2dm10uqv_0eYrGG_Su6SsN5UydPXeFyNOM,35578
|
|
36
|
+
sqlglot/dialects/materialize.py,sha256=LD2q1kTRrCwkIu1BfoBvnjTGbupDtoQ8JQMDCIYAXHg,3533
|
|
37
|
+
sqlglot/dialects/mysql.py,sha256=3czNezOqHoEVxzBZI1bX-mr6HFVA4175kAmNZGTQrN0,54894
|
|
38
|
+
sqlglot/dialects/oracle.py,sha256=-GCRK0VegLWtPfhu5MKE62Rp8cvEEWXYZFtgKJ15RmY,18904
|
|
39
|
+
sqlglot/dialects/postgres.py,sha256=QvnA7vLv3dmK_DoBgowO6Ciuu354L8YeGk51zQej6uY,40848
|
|
40
|
+
sqlglot/dialects/presto.py,sha256=N1h1BPXLNYIZkdXKz-sEIm2Ua4ePAj8hmruJQZgMR4I,34277
|
|
41
|
+
sqlglot/dialects/prql.py,sha256=fwN-SPEGx-drwf1K0U2MByN-PkW3C_rOgQ3xeJeychg,7908
|
|
42
|
+
sqlglot/dialects/redshift.py,sha256=y91Y1BJviqBoL-G8v_g9nvHWz24Q-aunR_E4JHN1adM,16818
|
|
43
|
+
sqlglot/dialects/risingwave.py,sha256=ZhcadiZzJIvJnEnTTtzzKZGOfHiYMXtBiUaN_X4tPF8,3882
|
|
44
|
+
sqlglot/dialects/singlestore.py,sha256=qWVI98gT2JWMrWbdREjyNqiPgSAqs6rVliMv-To_LBs,62512
|
|
45
|
+
sqlglot/dialects/snowflake.py,sha256=oZhOQFUFhxHJqoPJ7WQ_rOzYRW-JNesy92FYARQmoE0,96100
|
|
46
|
+
sqlglot/dialects/solr.py,sha256=pydnl4ml-3M1Fc4ALm6cMVO9h-5EtqZxPZH_91Nz1Ss,617
|
|
47
|
+
sqlglot/dialects/spark.py,sha256=pBjwfORdixwzM8Sg8udh1Vodh4cEqlu5y-etYr3JfOE,11707
|
|
48
|
+
sqlglot/dialects/spark2.py,sha256=SqUe_xkmyef2cVAHL33tGWJYH5IKkqsrSBBK-jo6_V8,14729
|
|
49
|
+
sqlglot/dialects/sqlite.py,sha256=uTpMrv6pCh_biZftAxSrLe5p-4aDiMsPFhqsWz4oRMg,13964
|
|
50
|
+
sqlglot/dialects/starrocks.py,sha256=9FzTyB9Wg6qCqKALLLw9BJfvQ6mowKXQOY-ogLBexiM,17156
|
|
51
|
+
sqlglot/dialects/tableau.py,sha256=oIawDzUITxGCWaEMB8OaNMPWhbC3U-2y09pYPm4eazc,2190
|
|
52
|
+
sqlglot/dialects/teradata.py,sha256=xTrHW_Ee6Ly4xAtTWYxqyD4e43O2iYKRDSzUAut1iDw,18101
|
|
53
|
+
sqlglot/dialects/trino.py,sha256=kJJIfxLkbkrOnCMg9WZnCpcFoMfKkwXb5JmDb2KoXOg,4555
|
|
54
|
+
sqlglot/dialects/tsql.py,sha256=PgIk5pJG8LGbIJDLUrE0wSmcPLnydp7H-1spQKRfp-0,56564
|
|
55
|
+
sqlglot/executor/__init__.py,sha256=OfjbXmfIbD7azL72X47suMjYaIp1qZfmAFzCyc1jSiY,2827
|
|
56
|
+
sqlglot/executor/context.py,sha256=WJHJdYQCOeVXwLw0uSSrWSc25eBMn5Ix108RCvdsKRQ,3386
|
|
57
|
+
sqlglot/executor/env.py,sha256=tQhU5PpTBMcxgZIFddFqxWMNPtHN0vOOz72voncY3KY,8276
|
|
58
|
+
sqlglot/executor/python.py,sha256=0A9rNH1jJEykTid4uA00Iq1VNA6KyV4L8U33Kq8x9U4,15549
|
|
59
|
+
sqlglot/executor/table.py,sha256=xkuJlgLVNYUXsSUaX0zTcnFekldXLLU8LqDyjR5K9wY,4419
|
|
60
|
+
sqlglot/optimizer/__init__.py,sha256=FdAvVz6rQLLkiiH21-SD4RxB5zS3WDeU-s03PZkJ-F4,343
|
|
61
|
+
sqlglot/optimizer/annotate_types.py,sha256=0geTVIhtK-uVNPuMRPfQRdsHdsgElFqFpLM_AE1-TVM,33635
|
|
62
|
+
sqlglot/optimizer/canonicalize.py,sha256=ggeXs92ri_1ZZxAZdtmq74-UcbjmKPUXcprGumW_M6g,7916
|
|
63
|
+
sqlglot/optimizer/eliminate_ctes.py,sha256=fUBM0RUnPrm2sYptEWBux98B7fcx7W-BM1zVqfgDz9c,1448
|
|
64
|
+
sqlglot/optimizer/eliminate_joins.py,sha256=GK9om2CS653uvuRC8T80GZSHNug8Unx1DqsyaUWJdVE,5943
|
|
65
|
+
sqlglot/optimizer/eliminate_subqueries.py,sha256=wsh9EdWXm4a5DhwQVpsXL9h51gHICAUvvE1D0uX0yoo,6294
|
|
66
|
+
sqlglot/optimizer/isolate_table_selects.py,sha256=_8rIKVMoL7eY3rrJsmgIdTRvfmBSLUxeHg42q1JW990,1464
|
|
67
|
+
sqlglot/optimizer/merge_subqueries.py,sha256=EDkU-sEyyMZZArFbuzSXYVNJshIOLq6VzNb8RwlEids,16052
|
|
68
|
+
sqlglot/optimizer/normalize.py,sha256=FUwWqTaAt_6h5Yuer3uUqfykwjLNFEiqKmE5VONp3Uw,7017
|
|
69
|
+
sqlglot/optimizer/normalize_identifiers.py,sha256=9uYtvys1tN6INJbC5SD6Mkh3kT_CWg19MF7qh81lGe4,2834
|
|
70
|
+
sqlglot/optimizer/optimize_joins.py,sha256=nnfRpL03lpDQF1oBO1EgaABqnr6t2GP6uMWoSLPW3IQ,4120
|
|
71
|
+
sqlglot/optimizer/optimizer.py,sha256=3V6HYfjDV19kMt9uXdb4dnKAPcftkJrCa90Qvpm9NF0,3775
|
|
72
|
+
sqlglot/optimizer/pushdown_predicates.py,sha256=_xAd35y2PV3hkx9He0vs5-r9zZZ_237EMa6XO7AmrTs,8415
|
|
73
|
+
sqlglot/optimizer/pushdown_projections.py,sha256=7NoK5NAUVYVhs0YnYyo6WuXfaO-BShSwS6lA8Y-ATQ4,6668
|
|
74
|
+
sqlglot/optimizer/qualify.py,sha256=dBA6gyJVyDRUHIphUlgTAB67BYPIwL5P_Nhv9zqsZ7w,4374
|
|
75
|
+
sqlglot/optimizer/qualify_columns.py,sha256=m_45dlUQM_orX8XkJ7LHtg1aIkztE0d4HkbS_jDwBrA,38664
|
|
76
|
+
sqlglot/optimizer/qualify_tables.py,sha256=Wi1TSMMxmcml7FPg430nWqIqlNUwPDxQyGTGIRhvQlw,8483
|
|
77
|
+
sqlglot/optimizer/resolver.py,sha256=yTuOypKsvWwlzu0TT5iZyGMq49OcryfMmuR_NTz0An0,17068
|
|
78
|
+
sqlglot/optimizer/scope.py,sha256=HqZ8jZNre_qU3BY3LdeBVCdoLBifKWg7_3LLX-1P4vM,32076
|
|
79
|
+
sqlglot/optimizer/simplify.py,sha256=TjVPgydoNepaVU4vg3GzyDaJJJmVy1gTJM4RgroByys,59148
|
|
80
|
+
sqlglot/optimizer/unnest_subqueries.py,sha256=xhSZJFPq06f1UjPsupm6uAHsRT_5WFe3YdnQ3qRBMq0,11751
|
|
81
|
+
sqlglot/typing/__init__.py,sha256=sr4HpwllNnLcM4ji3Z9eC_35JPrGTjWsbttxvie-oro,10034
|
|
82
|
+
sqlglot/typing/bigquery.py,sha256=HzX9WP35ikLRCHK8XfhswuKAMbnFGcFvNv5MyllzwhM,12653
|
|
83
|
+
sqlglot/typing/duckdb.py,sha256=Pi-b0GvWnGmWQWUJd5EVPw_YkSqyz1G9QjB0HZ31IaI,848
|
|
84
|
+
sqlglot/typing/hive.py,sha256=YI71Rl4rASbIa2LE5Zpa_ff4FqkZbVCDY_k-NaXWxmc,1520
|
|
85
|
+
sqlglot/typing/mysql.py,sha256=xe1hRNWIFlTAZCu2VRvfW3QiYIKVwK4XGml3qj0iKjs,795
|
|
86
|
+
sqlglot/typing/presto.py,sha256=q7F-sSobGDuJWVpJY9lb4OnJ-xyAS4hTAYq9UO7z7L4,649
|
|
87
|
+
sqlglot/typing/snowflake.py,sha256=klP5mDiuYHW3A4B9sbzmhEYXuOJOmn5Gr1eOueOyghM,17919
|
|
88
|
+
sqlglot/typing/spark.py,sha256=p6nXqOcI76KkN_t-t_IQBjyCi0k0ChyT-S3oqsNVS1Q,806
|
|
89
|
+
sqlglot/typing/spark2.py,sha256=sbKFVCNG2f1AiBittiQFbReN98iTXtc4pvP8b-VzzHY,2125
|
|
90
|
+
sqlglot/typing/tsql.py,sha256=wzEm5RcKl_u0Bg67f0WLm6IFBP9Kaxeillg5hOYiNaQ,749
|
|
91
|
+
sqlglot-28.8.0.dist-info/licenses/LICENSE,sha256=p1Yk0B4oa0l8Rh-_dYyy75d8spjPd_vTloXfz4FWxys,1065
|
|
92
|
+
sqlglot-28.8.0.dist-info/METADATA,sha256=3b6-RAsfa4yK3K_JcitJWj8Rs_fvZ6W6K9GNK4ca6lY,22946
|
|
93
|
+
sqlglot-28.8.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
94
|
+
sqlglot-28.8.0.dist-info/top_level.txt,sha256=5kRskCGA_gVADF9rSfSzPdLHXqvfMusDYeHePfNY2nQ,8
|
|
95
|
+
sqlglot-28.8.0.dist-info/RECORD,,
|