sqlglot 27.12.0__py3-none-any.whl → 27.13.1__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 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.12.0'
32
- __version_tuple__ = version_tuple = (27, 12, 0)
31
+ __version__ = version = '27.13.1'
32
+ __version_tuple__ = version_tuple = (27, 13, 1)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -572,7 +572,6 @@ class BigQuery(Dialect):
572
572
  e, exp.DataType.Type.VARCHAR
573
573
  ),
574
574
  exp.Concat: _annotate_concat,
575
- exp.Contains: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BOOLEAN),
576
575
  exp.Corr: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
577
576
  exp.Cot: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
578
577
  exp.CosineDistance: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
@@ -768,6 +767,10 @@ class BigQuery(Dialect):
768
767
  FUNCTIONS = {
769
768
  **parser.Parser.FUNCTIONS,
770
769
  "APPROX_TOP_COUNT": exp.ApproxTopK.from_arg_list,
770
+ "BIT_AND": exp.BitwiseAndAgg.from_arg_list,
771
+ "BIT_OR": exp.BitwiseOrAgg.from_arg_list,
772
+ "BIT_XOR": exp.BitwiseXorAgg.from_arg_list,
773
+ "BIT_COUNT": exp.BitwiseCountAgg.from_arg_list,
771
774
  "BOOL": exp.JSONBool.from_arg_list,
772
775
  "CONTAINS_SUBSTR": _build_contains_substring,
773
776
  "DATE": _build_date,
@@ -1273,6 +1276,10 @@ class BigQuery(Dialect):
1273
1276
  exp.ArrayContains: _array_contains_sql,
1274
1277
  exp.ArrayFilter: filter_array_using_unnest,
1275
1278
  exp.ArrayRemove: filter_array_using_unnest,
1279
+ exp.BitwiseAndAgg: rename_func("BIT_AND"),
1280
+ exp.BitwiseOrAgg: rename_func("BIT_OR"),
1281
+ exp.BitwiseXorAgg: rename_func("BIT_XOR"),
1282
+ exp.BitwiseCountAgg: rename_func("BIT_COUNT"),
1276
1283
  exp.ByteLength: rename_func("BYTE_LENGTH"),
1277
1284
  exp.Cast: transforms.preprocess([transforms.remove_precision_parameterized_types]),
1278
1285
  exp.CollateProperty: lambda self, e: (
@@ -818,6 +818,7 @@ class Dialect(metaclass=_Dialect):
818
818
  exp.Cast: lambda self, e: self._annotate_with_type(e, e.args["to"]),
819
819
  exp.Case: lambda self, e: self._annotate_by_args(e, "default", "ifs"),
820
820
  exp.Coalesce: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
821
+ exp.Contains: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BOOLEAN),
821
822
  exp.Count: lambda self, e: self._annotate_with_type(
822
823
  e, exp.DataType.Type.BIGINT if e.args.get("big_int") else exp.DataType.Type.INT
823
824
  ),
@@ -2005,6 +2006,12 @@ def groupconcat_sql(
2005
2006
  on_overflow_sql = self.sql(expression, "on_overflow")
2006
2007
  on_overflow_sql = f" ON OVERFLOW {on_overflow_sql}" if (on_overflow and on_overflow_sql) else ""
2007
2008
 
2009
+ if isinstance(this, exp.Limit) and this.this:
2010
+ limit = this
2011
+ this = limit.this.pop()
2012
+ else:
2013
+ limit = None
2014
+
2008
2015
  order = this.find(exp.Order)
2009
2016
 
2010
2017
  if order and order.this:
@@ -2013,11 +2020,16 @@ def groupconcat_sql(
2013
2020
  args = self.format_args(this, f"{separator}{on_overflow_sql}")
2014
2021
  listagg: exp.Expression = exp.Anonymous(this=func_name, expressions=[args])
2015
2022
 
2023
+ modifiers = self.sql(limit)
2024
+
2016
2025
  if order:
2017
2026
  if within_group:
2018
2027
  listagg = exp.WithinGroup(this=listagg, expression=order)
2019
2028
  else:
2020
- listagg.set("expressions", [f"{args}{self.sql(expression=expression.this)}"])
2029
+ modifiers = f"{self.sql(order)}{modifiers}"
2030
+
2031
+ if modifiers:
2032
+ listagg.set("expressions", [f"{args}{modifiers}"])
2021
2033
 
2022
2034
  return self.sql(listagg)
2023
2035
 
@@ -167,6 +167,8 @@ class Dremio(Dialect):
167
167
  FUNCTIONS = {
168
168
  **parser.Parser.FUNCTIONS,
169
169
  "ARRAY_GENERATE_RANGE": exp.GenerateSeries.from_arg_list,
170
+ "BIT_AND": exp.BitwiseAndAgg.from_arg_list,
171
+ "BIT_OR": exp.BitwiseOrAgg.from_arg_list,
170
172
  "DATE_ADD": build_date_delta_with_cast_interval(exp.DateAdd),
171
173
  "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "dremio"),
172
174
  "DATE_SUB": build_date_delta_with_cast_interval(exp.DateSub),
@@ -216,6 +218,8 @@ class Dremio(Dialect):
216
218
 
217
219
  TRANSFORMS = {
218
220
  **generator.Generator.TRANSFORMS,
221
+ exp.BitwiseAndAgg: rename_func("BIT_AND"),
222
+ exp.BitwiseOrAgg: rename_func("BIT_OR"),
219
223
  exp.ToChar: rename_func("TO_CHAR"),
220
224
  exp.TimeToStr: lambda self, e: self.func("TO_CHAR", e.this, self.format_time(e)),
221
225
  exp.DateAdd: _date_delta_sql("DATE_ADD"),
sqlglot/dialects/mysql.py CHANGED
@@ -301,6 +301,10 @@ class MySQL(Dialect):
301
301
 
302
302
  FUNCTIONS = {
303
303
  **parser.Parser.FUNCTIONS,
304
+ "BIT_AND": exp.BitwiseAndAgg.from_arg_list,
305
+ "BIT_OR": exp.BitwiseOrAgg.from_arg_list,
306
+ "BIT_XOR": exp.BitwiseXorAgg.from_arg_list,
307
+ "BIT_COUNT": exp.BitwiseCountAgg.from_arg_list,
304
308
  "CONVERT_TZ": lambda args: exp.ConvertTimezone(
305
309
  source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0)
306
310
  ),
@@ -691,7 +695,7 @@ class MySQL(Dialect):
691
695
  class Generator(generator.Generator):
692
696
  INTERVAL_ALLOWS_PLURAL_FORM = False
693
697
  LOCKING_READS_SUPPORTED = True
694
- NULL_ORDERING_SUPPORTED = None
698
+ NULL_ORDERING_SUPPORTED: t.Optional[bool] = None
695
699
  JOIN_HINTS = False
696
700
  TABLE_HINTS = True
697
701
  DUPLICATE_KEY_UPDATE_WITH_SET = False
@@ -712,6 +716,10 @@ class MySQL(Dialect):
712
716
  TRANSFORMS = {
713
717
  **generator.Generator.TRANSFORMS,
714
718
  exp.ArrayAgg: rename_func("GROUP_CONCAT"),
719
+ exp.BitwiseAndAgg: rename_func("BIT_AND"),
720
+ exp.BitwiseOrAgg: rename_func("BIT_OR"),
721
+ exp.BitwiseXorAgg: rename_func("BIT_XOR"),
722
+ exp.BitwiseCountAgg: rename_func("BIT_COUNT"),
715
723
  exp.CurrentDate: no_paren_current_date_sql,
716
724
  exp.DateDiff: _remove_ts_or_ds_to_date(
717
725
  lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
@@ -779,6 +787,8 @@ class MySQL(Dialect):
779
787
  exp.Week: _remove_ts_or_ds_to_date(),
780
788
  exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
781
789
  exp.Year: _remove_ts_or_ds_to_date(),
790
+ exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"),
791
+ exp.UtcTime: rename_func("UTC_TIME"),
782
792
  }
783
793
 
784
794
  UNSIGNED_TYPE_MAPPING = {
@@ -338,6 +338,8 @@ class Oracle(Dialect):
338
338
  exp.Unicode: lambda self, e: f"ASCII(UNISTR({self.sql(e.this)}))",
339
339
  exp.UnixToTime: lambda self,
340
340
  e: f"TO_DATE('1970-01-01', 'YYYY-MM-DD') + ({self.sql(e, 'this')} / 86400)",
341
+ exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"),
342
+ exp.UtcTime: rename_func("UTC_TIME"),
341
343
  }
342
344
 
343
345
  PROPERTIES_LOCATION = {
@@ -327,8 +327,7 @@ class Postgres(Dialect):
327
327
  "<@": TokenType.LT_AT,
328
328
  "|/": TokenType.PIPE_SLASH,
329
329
  "||/": TokenType.DPIPE_SLASH,
330
- "BEGIN": TokenType.COMMAND,
331
- "BEGIN TRANSACTION": TokenType.BEGIN,
330
+ "BEGIN": TokenType.BEGIN,
332
331
  "BIGSERIAL": TokenType.BIGSERIAL,
333
332
  "CONSTRAINT TRIGGER": TokenType.COMMAND,
334
333
  "CSTRING": TokenType.PSEUDO_TYPE,
@@ -22,11 +22,13 @@ from sqlglot.generator import unsupported_args
22
22
  from sqlglot.helper import seq_get
23
23
 
24
24
 
25
- def cast_to_time6(expression: t.Optional[exp.Expression]) -> exp.Cast:
25
+ def cast_to_time6(
26
+ expression: t.Optional[exp.Expression], time_type: DataType.Type = exp.DataType.Type.TIME
27
+ ) -> exp.Cast:
26
28
  return exp.Cast(
27
29
  this=expression,
28
30
  to=exp.DataType.build(
29
- exp.DataType.Type.TIME,
31
+ time_type,
30
32
  expressions=[exp.DataTypeParam(this=exp.Literal.number(6))],
31
33
  ),
32
34
  )
@@ -63,6 +65,7 @@ class SingleStore(MySQL):
63
65
  "TIMESTAMP": TokenType.TIMESTAMP,
64
66
  "UTC_DATE": TokenType.UTC_DATE,
65
67
  "UTC_TIME": TokenType.UTC_TIME,
68
+ "UTC_TIMESTAMP": TokenType.UTC_TIMESTAMP,
66
69
  ":>": TokenType.COLON_GT,
67
70
  "!:>": TokenType.NCOLON_GT,
68
71
  "::$": TokenType.DCOLONDOLLAR,
@@ -162,6 +165,8 @@ class SingleStore(MySQL):
162
165
  json_type="JSON",
163
166
  ),
164
167
  "JSON_PRETTY": exp.JSONFormat.from_arg_list,
168
+ "JSON_BUILD_ARRAY": lambda args: exp.JSONArray(expressions=args),
169
+ "JSON_BUILD_OBJECT": lambda args: exp.JSONObject(expressions=args),
165
170
  "DATE": exp.Date.from_arg_list,
166
171
  "DAYNAME": lambda args: exp.TimeToStr(
167
172
  this=seq_get(args, 0),
@@ -199,10 +204,19 @@ class SingleStore(MySQL):
199
204
  ),
200
205
  }
201
206
 
207
+ FUNCTION_PARSERS: t.Dict[str, t.Callable] = {
208
+ **MySQL.Parser.FUNCTION_PARSERS,
209
+ "JSON_AGG": lambda self: exp.JSONArrayAgg(
210
+ this=self._parse_term(),
211
+ order=self._parse_order(),
212
+ ),
213
+ }
214
+
202
215
  NO_PAREN_FUNCTIONS = {
203
216
  **MySQL.Parser.NO_PAREN_FUNCTIONS,
204
217
  TokenType.UTC_DATE: exp.UtcDate,
205
218
  TokenType.UTC_TIME: exp.UtcTime,
219
+ TokenType.UTC_TIMESTAMP: exp.UtcTimestamp,
206
220
  }
207
221
 
208
222
  CAST_COLUMN_OPERATORS = {TokenType.COLON_GT, TokenType.NCOLON_GT}
@@ -237,6 +251,8 @@ class SingleStore(MySQL):
237
251
 
238
252
  class Generator(MySQL.Generator):
239
253
  SUPPORTS_UESCAPE = False
254
+ NULL_ORDERING_SUPPORTED = True
255
+ MATCH_AGAINST_TABLE_PREFIX = "TABLE "
240
256
 
241
257
  @staticmethod
242
258
  def _unicode_substitute(m: re.Match[str]) -> str:
@@ -339,6 +355,11 @@ class SingleStore(MySQL):
339
355
  if e.unit is not None
340
356
  else self.func("DATEDIFF", e.this, e.expression),
341
357
  exp.TimestampTrunc: unsupported_args("zone")(timestamptrunc_sql()),
358
+ exp.CurrentDatetime: lambda self, e: self.sql(
359
+ cast_to_time6(
360
+ exp.CurrentTimestamp(this=exp.Literal.number(6)), exp.DataType.Type.DATETIME
361
+ )
362
+ ),
342
363
  exp.JSONExtract: unsupported_args(
343
364
  "only_json_types",
344
365
  "expressions",
@@ -354,6 +375,21 @@ class SingleStore(MySQL):
354
375
  exp.JSONPathSubscript: lambda self, e: self.json_path_part(e.this),
355
376
  exp.JSONPathRoot: lambda *_: "",
356
377
  exp.JSONFormat: unsupported_args("options", "is_json")(rename_func("JSON_PRETTY")),
378
+ exp.JSONArrayAgg: unsupported_args("null_handling", "return_type", "strict")(
379
+ lambda self, e: self.func("JSON_AGG", e.this, suffix=f"{self.sql(e, 'order')})")
380
+ ),
381
+ exp.JSONArray: unsupported_args("null_handling", "return_type", "strict")(
382
+ rename_func("JSON_BUILD_ARRAY")
383
+ ),
384
+ exp.JSONBExists: lambda self, e: self.func(
385
+ "BSON_MATCH_ANY_EXISTS", e.this, e.args.get("path")
386
+ ),
387
+ exp.JSONExists: unsupported_args("passing", "on_condition")(
388
+ lambda self, e: self.func("JSON_MATCH_ANY_EXISTS", e.this, e.args.get("path"))
389
+ ),
390
+ exp.JSONObject: unsupported_args(
391
+ "null_handling", "unique_keys", "return_type", "encoding"
392
+ )(rename_func("JSON_BUILD_OBJECT")),
357
393
  exp.DayOfWeekIso: lambda self, e: f"(({self.func('DAYOFWEEK', e.this)} % 7) + 1)",
358
394
  exp.DayOfMonth: rename_func("DAY"),
359
395
  exp.Hll: rename_func("APPROX_COUNT_DISTINCT"),
@@ -417,11 +453,20 @@ class SingleStore(MySQL):
417
453
  ),
418
454
  "RLIKE",
419
455
  ),
456
+ exp.Stuff: lambda self, e: self.func(
457
+ "CONCAT",
458
+ self.func("SUBSTRING", e.this, exp.Literal.number(1), e.args.get("start") - 1),
459
+ e.expression,
460
+ self.func("SUBSTRING", e.this, e.args.get("start") + e.args.get("length")),
461
+ ),
420
462
  exp.Reduce: unsupported_args("finish")(
421
463
  lambda self, e: self.func(
422
464
  "REDUCE", e.args.get("initial"), e.this, e.args.get("merge")
423
465
  )
424
466
  ),
467
+ exp.MatchAgainst: unsupported_args("modifier")(
468
+ lambda self, e: super().matchagainst_sql(e)
469
+ ),
425
470
  }
426
471
  TRANSFORMS.pop(exp.JSONExtractScalar)
427
472
  TRANSFORMS.pop(exp.CurrentDate)
@@ -1667,3 +1712,32 @@ class SingleStore(MySQL):
1667
1712
  self.unsupported("CurrentTime with timezone is not supported in SingleStore")
1668
1713
 
1669
1714
  return self.func("CURRENT_TIME")
1715
+
1716
+ def currenttimestamp_sql(self, expression: exp.CurrentTimestamp) -> str:
1717
+ arg = expression.this
1718
+ if arg:
1719
+ if isinstance(arg, exp.Literal) and arg.name.lower() == "utc":
1720
+ return self.func("UTC_TIMESTAMP")
1721
+ if isinstance(arg, exp.Literal) and arg.is_number:
1722
+ return self.func("CURRENT_TIMESTAMP", arg)
1723
+ self.unsupported("CurrentTimestamp with timezone is not supported in SingleStore")
1724
+
1725
+ return self.func("CURRENT_TIMESTAMP")
1726
+
1727
+ def standardhash_sql(self, expression: exp.StandardHash) -> str:
1728
+ hash_function = expression.expression
1729
+ if hash_function is None:
1730
+ return self.func("SHA", expression.this)
1731
+ if isinstance(hash_function, exp.Literal):
1732
+ if hash_function.name.lower() == "sha":
1733
+ return self.func("SHA", expression.this)
1734
+ if hash_function.name.lower() == "md5":
1735
+ return self.func("MD5", expression.this)
1736
+
1737
+ self.unsupported(
1738
+ f"{hash_function.this} hash method is not supported in SingleStore"
1739
+ )
1740
+ return self.func("SHA", expression.this)
1741
+
1742
+ self.unsupported("STANDARD_HASH function is not supported in SingleStore")
1743
+ return self.func("SHA", expression.this)
@@ -496,6 +496,15 @@ class Snowflake(Dialect):
496
496
  ALTER_TABLE_ADD_REQUIRED_FOR_EACH_COLUMN = False
497
497
  TRY_CAST_REQUIRES_STRING = True
498
498
 
499
+ ANNOTATORS = {
500
+ **Dialect.ANNOTATORS,
501
+ **{
502
+ expr_type: lambda self, e: self._annotate_by_args(e, "this")
503
+ for expr_type in (exp.Reverse,)
504
+ },
505
+ exp.ConcatWs: lambda self, e: self._annotate_by_args(e, "expressions"),
506
+ }
507
+
499
508
  TIME_MAPPING = {
500
509
  "YYYY": "%Y",
501
510
  "yyyy": "%Y",
@@ -574,6 +583,7 @@ class Snowflake(Dialect):
574
583
  end=exp.Sub(this=seq_get(args, 1), expression=exp.Literal.number(1)),
575
584
  step=seq_get(args, 2),
576
585
  ),
586
+ "ARRAY_SORT": exp.SortArray.from_arg_list,
577
587
  "BITXOR": _build_bitwise(exp.BitwiseXor, "BITXOR"),
578
588
  "BIT_XOR": _build_bitwise(exp.BitwiseXor, "BITXOR"),
579
589
  "BITOR": _build_bitwise(exp.BitwiseOr, "BITOR"),
@@ -582,6 +592,18 @@ class Snowflake(Dialect):
582
592
  "BIT_SHIFTLEFT": _build_bitwise(exp.BitwiseLeftShift, "BIT_SHIFTLEFT"),
583
593
  "BITSHIFTRIGHT": _build_bitwise(exp.BitwiseRightShift, "BITSHIFTRIGHT"),
584
594
  "BIT_SHIFTRIGHT": _build_bitwise(exp.BitwiseRightShift, "BIT_SHIFTRIGHT"),
595
+ "BITANDAGG": exp.BitwiseAndAgg.from_arg_list,
596
+ "BITAND_AGG": exp.BitwiseAndAgg.from_arg_list,
597
+ "BIT_AND_AGG": exp.BitwiseAndAgg.from_arg_list,
598
+ "BIT_ANDAGG": exp.BitwiseAndAgg.from_arg_list,
599
+ "BITORAGG": exp.BitwiseOrAgg.from_arg_list,
600
+ "BITOR_AGG": exp.BitwiseOrAgg.from_arg_list,
601
+ "BIT_OR_AGG": exp.BitwiseOrAgg.from_arg_list,
602
+ "BIT_ORAGG": exp.BitwiseOrAgg.from_arg_list,
603
+ "BITXORAGG": exp.BitwiseXorAgg.from_arg_list,
604
+ "BITXOR_AGG": exp.BitwiseXorAgg.from_arg_list,
605
+ "BIT_XOR_AGG": exp.BitwiseXorAgg.from_arg_list,
606
+ "BIT_XORAGG": exp.BitwiseXorAgg.from_arg_list,
585
607
  "BOOLXOR": _build_bitwise(exp.Xor, "BOOLXOR"),
586
608
  "DATE": _build_datetime("DATE", exp.DataType.Type.DATE),
587
609
  "DATE_TRUNC": _date_trunc_to_time,
@@ -1200,6 +1222,10 @@ class Snowflake(Dialect):
1200
1222
  ),
1201
1223
  exp.BitwiseOr: rename_func("BITOR"),
1202
1224
  exp.BitwiseXor: rename_func("BITXOR"),
1225
+ exp.BitwiseAnd: rename_func("BITAND"),
1226
+ exp.BitwiseAndAgg: rename_func("BITANDAGG"),
1227
+ exp.BitwiseOrAgg: rename_func("BITORAGG"),
1228
+ exp.BitwiseXorAgg: rename_func("BITXORAGG"),
1203
1229
  exp.BitwiseLeftShift: rename_func("BITSHIFTLEFT"),
1204
1230
  exp.BitwiseRightShift: rename_func("BITSHIFTRIGHT"),
1205
1231
  exp.Create: transforms.preprocess([_flatten_structured_types_unless_iceberg]),
@@ -1272,6 +1298,7 @@ class Snowflake(Dialect):
1272
1298
  ]
1273
1299
  ),
1274
1300
  exp.SHA: rename_func("SHA1"),
1301
+ exp.SortArray: rename_func("ARRAY_SORT"),
1275
1302
  exp.StarMap: rename_func("OBJECT_CONSTRUCT"),
1276
1303
  exp.StartsWith: rename_func("STARTSWITH"),
1277
1304
  exp.EndsWith: rename_func("ENDSWITH"),
sqlglot/dialects/spark.py CHANGED
@@ -125,6 +125,10 @@ class Spark(Spark2):
125
125
  FUNCTIONS = {
126
126
  **Spark2.Parser.FUNCTIONS,
127
127
  "ANY_VALUE": _build_with_ignore_nulls(exp.AnyValue),
128
+ "BIT_AND": exp.BitwiseAndAgg.from_arg_list,
129
+ "BIT_OR": exp.BitwiseOrAgg.from_arg_list,
130
+ "BIT_XOR": exp.BitwiseXorAgg.from_arg_list,
131
+ "BIT_COUNT": exp.BitwiseCountAgg.from_arg_list,
128
132
  "DATE_ADD": _build_dateadd,
129
133
  "DATEADD": _build_dateadd,
130
134
  "TIMESTAMPADD": _build_dateadd,
@@ -189,6 +193,10 @@ class Spark(Spark2):
189
193
  exp.ArrayConstructCompact: lambda self, e: self.func(
190
194
  "ARRAY_COMPACT", self.func("ARRAY", *e.expressions)
191
195
  ),
196
+ exp.BitwiseAndAgg: rename_func("BIT_AND"),
197
+ exp.BitwiseOrAgg: rename_func("BIT_OR"),
198
+ exp.BitwiseXorAgg: rename_func("BIT_XOR"),
199
+ exp.BitwiseCountAgg: rename_func("BIT_COUNT"),
192
200
  exp.Create: preprocess(
193
201
  [
194
202
  remove_unique_constraints,
sqlglot/expressions.py CHANGED
@@ -5520,19 +5520,19 @@ class AggFunc(Func):
5520
5520
 
5521
5521
 
5522
5522
  class BitwiseAndAgg(AggFunc):
5523
- _sql_names = ["BIT_AND"]
5523
+ pass
5524
5524
 
5525
5525
 
5526
5526
  class BitwiseOrAgg(AggFunc):
5527
- _sql_names = ["BIT_OR"]
5527
+ pass
5528
5528
 
5529
5529
 
5530
5530
  class BitwiseXorAgg(AggFunc):
5531
- _sql_names = ["BIT_XOR"]
5531
+ pass
5532
5532
 
5533
5533
 
5534
5534
  class BitwiseCountAgg(AggFunc):
5535
- _sql_names = ["BIT_COUNT"]
5535
+ pass
5536
5536
 
5537
5537
 
5538
5538
  class ByteLength(Func):
@@ -6075,7 +6075,11 @@ class UtcDate(Func):
6075
6075
 
6076
6076
 
6077
6077
  class UtcTime(Func):
6078
- arg_types = {}
6078
+ arg_types = {"this": False}
6079
+
6080
+
6081
+ class UtcTimestamp(Func):
6082
+ arg_types = {"this": False}
6079
6083
 
6080
6084
 
6081
6085
  class DateAdd(Func, IntervalOp):
@@ -7167,7 +7171,7 @@ class Sign(Func):
7167
7171
 
7168
7172
 
7169
7173
  class SortArray(Func):
7170
- arg_types = {"this": True, "asc": False}
7174
+ arg_types = {"this": True, "asc": False, "nulls_first": False}
7171
7175
 
7172
7176
 
7173
7177
  class Soundex(Func):
sqlglot/generator.py CHANGED
@@ -218,6 +218,9 @@ class Generator(metaclass=_Generator):
218
218
  exp.UppercaseColumnConstraint: lambda *_: "UPPERCASE",
219
219
  exp.UtcDate: lambda self, e: self.sql(exp.CurrentDate(this=exp.Literal.string("UTC"))),
220
220
  exp.UtcTime: lambda self, e: self.sql(exp.CurrentTime(this=exp.Literal.string("UTC"))),
221
+ exp.UtcTimestamp: lambda self, e: self.sql(
222
+ exp.CurrentTimestamp(this=exp.Literal.string("UTC"))
223
+ ),
221
224
  exp.VarMap: lambda self, e: self.func("MAP", e.args["keys"], e.args["values"]),
222
225
  exp.ViewAttributeProperty: lambda self, e: f"WITH {self.sql(e, 'this')}",
223
226
  exp.VolatileProperty: lambda *_: "VOLATILE",
@@ -500,6 +503,9 @@ class Generator(metaclass=_Generator):
500
503
  # Whether LIKE and ILIKE support quantifiers such as LIKE ANY/ALL/SOME
501
504
  SUPPORTS_LIKE_QUANTIFIERS = True
502
505
 
506
+ # Prefix which is appended to exp.Table expressions in MATCH AGAINST
507
+ MATCH_AGAINST_TABLE_PREFIX: t.Optional[str] = None
508
+
503
509
  TYPE_MAPPING = {
504
510
  exp.DataType.Type.DATETIME2: "TIMESTAMP",
505
511
  exp.DataType.Type.NCHAR: "CHAR",
@@ -3068,9 +3074,21 @@ class Generator(metaclass=_Generator):
3068
3074
  return self.case_sql(exp.Case(ifs=[expression], default=expression.args.get("false")))
3069
3075
 
3070
3076
  def matchagainst_sql(self, expression: exp.MatchAgainst) -> str:
3077
+ if self.MATCH_AGAINST_TABLE_PREFIX:
3078
+ expressions = []
3079
+ for expr in expression.expressions:
3080
+ if isinstance(expr, exp.Table):
3081
+ expressions.append(f"TABLE {self.sql(expr)}")
3082
+ else:
3083
+ expressions.append(expr)
3084
+ else:
3085
+ expressions = expression.expressions
3086
+
3071
3087
  modifier = expression.args.get("modifier")
3072
3088
  modifier = f" {modifier}" if modifier else ""
3073
- return f"{self.func('MATCH', *expression.expressions)} AGAINST({self.sql(expression, 'this')}{modifier})"
3089
+ return (
3090
+ f"{self.func('MATCH', *expressions)} AGAINST({self.sql(expression, 'this')}{modifier})"
3091
+ )
3074
3092
 
3075
3093
  def jsonkeyvalue_sql(self, expression: exp.JSONKeyValue) -> str:
3076
3094
  return f"{self.sql(expression, 'this')}{self.JSON_KEY_VALUE_PAIR_SEP} {self.sql(expression, 'expression')}"
@@ -3449,7 +3467,9 @@ class Generator(metaclass=_Generator):
3449
3467
  return f"TTL{self.seg(self.expressions(expression))}{where}{group}{aggregates}"
3450
3468
 
3451
3469
  def transaction_sql(self, expression: exp.Transaction) -> str:
3452
- return "BEGIN"
3470
+ modes = self.expressions(expression, key="modes")
3471
+ modes = f" {modes}" if modes else ""
3472
+ return f"BEGIN{modes}"
3453
3473
 
3454
3474
  def commit_sql(self, expression: exp.Commit) -> str:
3455
3475
  chain = expression.args.get("chain")
@@ -5223,7 +5243,8 @@ class Generator(metaclass=_Generator):
5223
5243
  metrics = self.seg(f"METRICS {metrics}") if metrics else ""
5224
5244
  where = self.sql(expression, "where")
5225
5245
  where = self.seg(f"WHERE {where}") if where else ""
5226
- return f"SEMANTIC_VIEW({self.indent(this + metrics + dimensions + where)}{self.seg(')', sep='')}"
5246
+ body = self.indent(this + metrics + dimensions + where, skip_first=True)
5247
+ return f"SEMANTIC_VIEW({body}{self.seg(')', sep='')}"
5227
5248
 
5228
5249
  def getextract_sql(self, expression: exp.GetExtract) -> str:
5229
5250
  this = expression.this
sqlglot/parser.py CHANGED
@@ -7,7 +7,7 @@ import typing as t
7
7
  from collections import defaultdict
8
8
 
9
9
  from sqlglot import exp
10
- from sqlglot.errors import ErrorLevel, ParseError, concat_messages, merge_errors
10
+ from sqlglot.errors import ErrorLevel, ParseError, TokenError, concat_messages, merge_errors
11
11
  from sqlglot.helper import apply_index_offset, ensure_list, seq_get
12
12
  from sqlglot.time import format_time
13
13
  from sqlglot.tokens import Token, Tokenizer, TokenType
@@ -644,6 +644,7 @@ class Parser(metaclass=_Parser):
644
644
  TokenType.TRUNCATE,
645
645
  TokenType.UTC_DATE,
646
646
  TokenType.UTC_TIME,
647
+ TokenType.UTC_TIMESTAMP,
647
648
  TokenType.WINDOW,
648
649
  TokenType.XOR,
649
650
  *TYPE_TOKENS,
@@ -5298,18 +5299,21 @@ class Parser(metaclass=_Parser):
5298
5299
  this: t.Optional[exp.Expression] = None
5299
5300
  prefix = self._match_text_seq("SYSUDTLIB", ".")
5300
5301
 
5301
- if not self._match_set(self.TYPE_TOKENS):
5302
+ if self._match_set(self.TYPE_TOKENS):
5303
+ type_token = self._prev.token_type
5304
+ else:
5305
+ type_token = None
5302
5306
  identifier = allow_identifiers and self._parse_id_var(
5303
5307
  any_token=False, tokens=(TokenType.VAR,)
5304
5308
  )
5305
5309
  if isinstance(identifier, exp.Identifier):
5306
- tokens = self.dialect.tokenize(identifier.sql(dialect=self.dialect))
5307
-
5308
- if len(tokens) != 1:
5309
- self.raise_error("Unexpected identifier", self._prev)
5310
+ try:
5311
+ tokens = self.dialect.tokenize(identifier.name)
5312
+ except TokenError:
5313
+ tokens = None
5310
5314
 
5311
- if tokens[0].token_type in self.TYPE_TOKENS:
5312
- self._prev = tokens[0]
5315
+ if tokens and len(tokens) == 1 and tokens[0].token_type in self.TYPE_TOKENS:
5316
+ type_token = tokens[0].token_type
5313
5317
  elif self.dialect.SUPPORTS_USER_DEFINED_TYPES:
5314
5318
  this = self._parse_user_defined_type(identifier)
5315
5319
  else:
@@ -5318,8 +5322,6 @@ class Parser(metaclass=_Parser):
5318
5322
  else:
5319
5323
  return None
5320
5324
 
5321
- type_token = self._prev.token_type
5322
-
5323
5325
  if type_token == TokenType.PSEUDO_TYPE:
5324
5326
  return self.expression(exp.PseudoType, this=self._prev.text.upper())
5325
5327
 
@@ -5395,7 +5397,7 @@ class Parser(metaclass=_Parser):
5395
5397
  if type_token == TokenType.VECTOR and len(expressions) == 2:
5396
5398
  expressions[0] = exp.DataType.build(expressions[0].name, dialect=self.dialect)
5397
5399
 
5398
- if not expressions or not self._match(TokenType.R_PAREN):
5400
+ if not self._match(TokenType.R_PAREN):
5399
5401
  self._retreat(index)
5400
5402
  return None
5401
5403
 
@@ -6462,6 +6464,11 @@ class Parser(metaclass=_Parser):
6462
6464
  return this
6463
6465
 
6464
6466
  def _parse_case(self) -> t.Optional[exp.Expression]:
6467
+ if self._match(TokenType.DOT, advance=False):
6468
+ # Avoid raising on valid expressions like case.*, supported by, e.g., spark & snowflake
6469
+ self._retreat(self._index - 1)
6470
+ return None
6471
+
6465
6472
  ifs = []
6466
6473
  default = None
6467
6474
 
@@ -6862,7 +6869,15 @@ class Parser(metaclass=_Parser):
6862
6869
  )
6863
6870
 
6864
6871
  def _parse_match_against(self) -> exp.MatchAgainst:
6865
- expressions = self._parse_csv(self._parse_column)
6872
+ if self._match_text_seq("TABLE"):
6873
+ # parse SingleStore MATCH(TABLE ...) syntax
6874
+ # https://docs.singlestore.com/cloud/reference/sql-reference/full-text-search-functions/match/
6875
+ expressions = []
6876
+ table = self._parse_table()
6877
+ if table:
6878
+ expressions = [table]
6879
+ else:
6880
+ expressions = self._parse_csv(self._parse_column)
6866
6881
 
6867
6882
  self._match_text_seq(")", "AGAINST", "(")
6868
6883
 
@@ -7069,8 +7084,8 @@ class Parser(metaclass=_Parser):
7069
7084
  if kind:
7070
7085
  self._match(TokenType.BETWEEN)
7071
7086
  start = self._parse_window_spec()
7072
- self._match(TokenType.AND)
7073
- end = self._parse_window_spec()
7087
+
7088
+ end = self._parse_window_spec() if self._match(TokenType.AND) else {}
7074
7089
  exclude = (
7075
7090
  self._parse_var_from_options(self.WINDOW_EXCLUDE_OPTIONS)
7076
7091
  if self._match_text_seq("EXCLUDE")
@@ -7082,8 +7097,8 @@ class Parser(metaclass=_Parser):
7082
7097
  kind=kind,
7083
7098
  start=start["value"],
7084
7099
  start_side=start["side"],
7085
- end=end["value"],
7086
- end_side=end["side"],
7100
+ end=end.get("value"),
7101
+ end_side=end.get("side"),
7087
7102
  exclude=exclude,
7088
7103
  )
7089
7104
  else:
@@ -7121,7 +7136,7 @@ class Parser(metaclass=_Parser):
7121
7136
  "value": (
7122
7137
  (self._match_text_seq("UNBOUNDED") and "UNBOUNDED")
7123
7138
  or (self._match_text_seq("CURRENT", "ROW") and "CURRENT ROW")
7124
- or self._parse_bitwise()
7139
+ or self._parse_type()
7125
7140
  ),
7126
7141
  "side": self._match_texts(self.WINDOW_SIDES) and self._prev.text,
7127
7142
  }
@@ -7343,7 +7358,7 @@ class Parser(metaclass=_Parser):
7343
7358
  modes = []
7344
7359
  while True:
7345
7360
  mode = []
7346
- while self._match(TokenType.VAR):
7361
+ while self._match(TokenType.VAR) or self._match(TokenType.NOT):
7347
7362
  mode.append(self._prev.text)
7348
7363
 
7349
7364
  if mode:
sqlglot/tokens.py CHANGED
@@ -234,7 +234,6 @@ class TokenType(AutoName):
234
234
  # keywords
235
235
  ALIAS = auto()
236
236
  ALTER = auto()
237
- ALWAYS = auto()
238
237
  ALL = auto()
239
238
  ANTI = auto()
240
239
  ANY = auto()
@@ -426,6 +425,7 @@ class TokenType(AutoName):
426
425
  UNIQUE = auto()
427
426
  UTC_DATE = auto()
428
427
  UTC_TIME = auto()
428
+ UTC_TIMESTAMP = auto()
429
429
  VERSION_SNAPSHOT = auto()
430
430
  TIMESTAMP_SNAPSHOT = auto()
431
431
  OPTION = auto()
@@ -712,7 +712,6 @@ class Tokenizer(metaclass=_Tokenizer):
712
712
  "~~*": TokenType.ILIKE,
713
713
  "~*": TokenType.IRLIKE,
714
714
  "ALL": TokenType.ALL,
715
- "ALWAYS": TokenType.ALWAYS,
716
715
  "AND": TokenType.AND,
717
716
  "ANTI": TokenType.ANTI,
718
717
  "ANY": TokenType.ANY,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglot
3
- Version: 27.12.0
3
+ Version: 27.13.1
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
@@ -1,31 +1,31 @@
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=pbMJ-il-pWtz_20YYeCzDhngpKNC-V0g18Eaoow3758,708
4
+ sqlglot/_version.py,sha256=ou5bykwli5rw5_qblbMze4DFs75loRI8NxexhmePC64,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=sECexwmvrQTKzuFzmPDeC_FezaQ1Hc9bg24TTKC0Jew,253741
8
- sqlglot/generator.py,sha256=jJkQGBy0q6hOm6oFw-0LlA6McSqFHLIozsoceJBARM4,223908
7
+ sqlglot/expressions.py,sha256=oestq-dQt-OC2XLgG0B-I3cDgg7DptuXmcUW7_uP6aQ,253755
8
+ sqlglot/generator.py,sha256=cO2HdHWKlL8Y7zs81hSsR-mFcy7U5x0Wd3A27jkn3lk,224692
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=QSBr7HWlDPpJ039_p4fcWV4FA2-_HtDDCXXMBAhoPuo,332586
12
+ sqlglot/parser.py,sha256=6QMiFaVbl7LJX-YMaZvJT_g28de2k3G5V-uDAx3zWTg,333268
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
16
16
  sqlglot/serde.py,sha256=DQVJ95WrIvhYfe02Ytb4NQug2aMwDCEwpMBW1LKDqzE,2031
17
17
  sqlglot/time.py,sha256=Q62gv6kL40OiRBF6BMESxKJcMVn7ZLNw7sv8H34z5FI,18400
18
- sqlglot/tokens.py,sha256=rqOMcjPDNa_35xC5zdUqPHgILNJUYxMC5N00NsOC8ps,49105
18
+ sqlglot/tokens.py,sha256=GuRPOipxixWdEJDxIat9ZLPAn3JhQ2cP94qvOelXogU,49076
19
19
  sqlglot/transforms.py,sha256=utNDsCBsA7hPUK3-aby3DDgiY_XVMAKQqeoLm1EyihI,41218
20
20
  sqlglot/trie.py,sha256=v27uXMrHfqrXlJ6GmeTSMovsB_3o0ctnlKhdNt7W6fI,2245
21
21
  sqlglot/dialects/__init__.py,sha256=e3K2NHrZO7oXfBzEpRsvgWAgJ_UCEyg7SlUCRqvnPj4,3799
22
22
  sqlglot/dialects/athena.py,sha256=ofArmayYLev4qZQ15GM8mevG04qqR5WGFb2ZcuYm6x4,10966
23
- sqlglot/dialects/bigquery.py,sha256=z9R-xVAxFxkwu4NkrgO9LI6NVTiUm9hr09et13LyU_U,71724
23
+ sqlglot/dialects/bigquery.py,sha256=IO5u1sdT0wzl76_z3FVm8FgtVnnMBrFPab-HhxuxROs,72078
24
24
  sqlglot/dialects/clickhouse.py,sha256=YLY8s7oCfdCoD0X2iOIltivXXjtT_nJdb3931P0TDeU,58553
25
25
  sqlglot/dialects/databricks.py,sha256=H4QTq7gg6tJylKc_YWsGp6049KydoI_wlQUHM7iCJtI,4753
26
- sqlglot/dialects/dialect.py,sha256=02W-j8nYJduA78_BMxMTMGXv2i9mcAGAmXBt1YsH0CQ,73055
26
+ sqlglot/dialects/dialect.py,sha256=MFP2WHesP-wf2HXub8s0_XyeUnjXCk8QNcqn5AIhARw,73361
27
27
  sqlglot/dialects/doris.py,sha256=CFnF955Oav3IjZWA80ickOI8tPpCjxk7BN5R4Z6pA1U,25263
28
- sqlglot/dialects/dremio.py,sha256=D2YwjqbTjJ8VZ94GQs7GBRCKUiizwggcEaR_drKpnoc,8242
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
31
  sqlglot/dialects/duckdb.py,sha256=ANzn5L5KS5pe9hn81Ta_4h5ngdPxMS1k_LdMuYGiff8,52470
@@ -34,16 +34,16 @@ sqlglot/dialects/exasol.py,sha256=ay3g_VyT5WvHTgNyJuCQu0nBt4bpllLZ9IdMBizEgYM,15
34
34
  sqlglot/dialects/fabric.py,sha256=4Sng2ZhQSaf6eK3ituR9DqDZERaVwYS_UfdpusjsISg,10220
35
35
  sqlglot/dialects/hive.py,sha256=zFr6WmNZXw5C0m3nFc9ynrbzk8Wtb5gyzmJ0tPlMge8,32014
36
36
  sqlglot/dialects/materialize.py,sha256=LD2q1kTRrCwkIu1BfoBvnjTGbupDtoQ8JQMDCIYAXHg,3533
37
- sqlglot/dialects/mysql.py,sha256=tQHedJthtXdjgHi3cDfdt71kJ4w6ju6J8kD4_MYFwyE,47308
38
- sqlglot/dialects/oracle.py,sha256=RXwJ82VLRaPfxb-OI0Bjd8KNaXs0XghyAJO4Bm0msYk,15862
39
- sqlglot/dialects/postgres.py,sha256=RAwAhrp_Gbz5Oi8OEuLcmHKnYXydvczYexd81Co0N9Y,33901
37
+ sqlglot/dialects/mysql.py,sha256=pAIWuwvirUrFbJE06UiST9iyiA4-IkA1sGiMgkeo1DY,47884
38
+ sqlglot/dialects/oracle.py,sha256=zWPCpzGiTlgCJ5E6FjfX3Rszjcw4SnHg6xeVboMYIyo,15972
39
+ sqlglot/dialects/postgres.py,sha256=NsaNBKUrqzb3bjVi16IBlYi8FPJnHRTl46lQX1GDNzw,33849
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=_sQTom4CGozFDZXW9y6bHQcZ-KiQ7QJjjQqM5rVagSc,15889
43
43
  sqlglot/dialects/risingwave.py,sha256=BqWwW1iT_OIVMwfRamaww79snnBwIgCfr22Go-ggO68,3289
44
- sqlglot/dialects/singlestore.py,sha256=3iSunYKjG9PYr4jnZmqa9E3MJxs1-ZvCRHejaYjGU2U,52201
45
- sqlglot/dialects/snowflake.py,sha256=PrpCq4BL8jzxQ9EnpZc-AJN4IZ_g5BJf4DU0RYFcyko,70779
46
- sqlglot/dialects/spark.py,sha256=XJbQq5d-tvCKYfmOG5rtf4ROS9rTqKJsmQVp6JjlFp0,9699
44
+ sqlglot/dialects/singlestore.py,sha256=_42yJP-YYbHswIBCKO5qxP5Z_AVksLh3bMX394iivwQ,55764
45
+ sqlglot/dialects/snowflake.py,sha256=xIftl1twnug9C-MW-jUncKskKVOwds3jpBvCDFmp5kM,72084
46
+ sqlglot/dialects/spark.py,sha256=PzyhkelDzbCMgJ3RVHD6yyzLIFp9NdZfwVas5IymowM,10147
47
47
  sqlglot/dialects/spark2.py,sha256=qz36FT9k4iuiqboRpyG4VpKGkPR0P2fifmqgZ9gNUEU,14851
48
48
  sqlglot/dialects/sqlite.py,sha256=UIQ66shIt2bQoLd7tYG4NVzh4HwCfERgAaLyukz8HjE,13231
49
49
  sqlglot/dialects/starrocks.py,sha256=2gav0PSNgRdAGXzawdznZliBpglJoQ0wBxPI7ZIMsRw,11314
@@ -76,8 +76,8 @@ sqlglot/optimizer/qualify_tables.py,sha256=dA4ZazL7ShQh2JgBwpHuG-4c5lBw1TNzCnuN7
76
76
  sqlglot/optimizer/scope.py,sha256=UOTrbwqcTc5iRQf0WStgYWXpE24w6riZy-tJYA18yTw,31229
77
77
  sqlglot/optimizer/simplify.py,sha256=-_yus42OYwqjQ9a2TSGhtG2G0pSkInUry1z7hEMz2pY,51062
78
78
  sqlglot/optimizer/unnest_subqueries.py,sha256=kzWUVDlxs8z9nmRx-8U-pHXPtVZhEIwkKqmKhr2QLvc,10908
79
- sqlglot-27.12.0.dist-info/licenses/LICENSE,sha256=p1Yk0B4oa0l8Rh-_dYyy75d8spjPd_vTloXfz4FWxys,1065
80
- sqlglot-27.12.0.dist-info/METADATA,sha256=ggllRKer1u6zYd5tvnxmMCJ30mNdFtI_tnwImwE7Z4M,20682
81
- sqlglot-27.12.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
82
- sqlglot-27.12.0.dist-info/top_level.txt,sha256=5kRskCGA_gVADF9rSfSzPdLHXqvfMusDYeHePfNY2nQ,8
83
- sqlglot-27.12.0.dist-info/RECORD,,
79
+ sqlglot-27.13.1.dist-info/licenses/LICENSE,sha256=p1Yk0B4oa0l8Rh-_dYyy75d8spjPd_vTloXfz4FWxys,1065
80
+ sqlglot-27.13.1.dist-info/METADATA,sha256=rnD1jn-fbRMKBZZGZWvzMgUuE3KzqbHgqXMzDSnwIcw,20682
81
+ sqlglot-27.13.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
82
+ sqlglot-27.13.1.dist-info/top_level.txt,sha256=5kRskCGA_gVADF9rSfSzPdLHXqvfMusDYeHePfNY2nQ,8
83
+ sqlglot-27.13.1.dist-info/RECORD,,