sqlglotc 30.7.0__tar.gz → 30.9.0__tar.gz

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.
Files changed (112) hide show
  1. {sqlglotc-30.7.0/sqlglotc.egg-info → sqlglotc-30.9.0}/PKG-INFO +2 -2
  2. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/pyproject.toml +2 -2
  3. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/aggregate.py +1 -1
  4. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/array.py +1 -1
  5. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/core.py +35 -14
  6. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/datatypes.py +18 -5
  7. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/ddl.py +9 -1
  8. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/dml.py +1 -0
  9. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/functions.py +13 -1
  10. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/query.py +29 -6
  11. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/string.py +2 -5
  12. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generator.py +239 -17
  13. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/bigquery.py +1 -0
  14. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/clickhouse.py +1 -1
  15. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/duckdb.py +46 -7
  16. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/exasol.py +27 -18
  17. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/hive.py +5 -4
  18. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/mysql.py +38 -0
  19. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/oracle.py +10 -2
  20. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/postgres.py +3 -0
  21. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/redshift.py +30 -0
  22. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/singlestore.py +6 -1
  23. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/snowflake.py +1 -0
  24. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/spark.py +8 -2
  25. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/sqlite.py +39 -10
  26. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/tsql.py +19 -7
  27. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/annotate_types.py +121 -39
  28. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/qualify.py +3 -2
  29. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/qualify_columns.py +3 -3
  30. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/scope.py +13 -0
  31. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/simplify.py +31 -3
  32. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parser.py +207 -24
  33. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/bigquery.py +37 -16
  34. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/clickhouse.py +20 -8
  35. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/databricks.py +1 -3
  36. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/dremio.py +2 -2
  37. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/drill.py +1 -1
  38. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/duckdb.py +9 -3
  39. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/exasol.py +1 -1
  40. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/hive.py +26 -17
  41. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/mysql.py +13 -3
  42. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/oracle.py +26 -4
  43. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/postgres.py +7 -4
  44. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/presto.py +8 -4
  45. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/redshift.py +26 -1
  46. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/singlestore.py +3 -3
  47. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/snowflake.py +21 -5
  48. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/spark2.py +3 -2
  49. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/tsql.py +72 -10
  50. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/schema.py +19 -13
  51. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/serde.py +11 -7
  52. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/time.py +6 -5
  53. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/tokenizer_core.py +3 -0
  54. {sqlglotc-30.7.0 → sqlglotc-30.9.0/sqlglotc.egg-info}/PKG-INFO +2 -2
  55. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglotc.egg-info/requires.txt +1 -1
  56. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/MANIFEST.in +0 -0
  57. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/setup.cfg +0 -0
  58. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/setup.py +0 -0
  59. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/errors.py +0 -0
  60. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/executor/table.py +0 -0
  61. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/builders.py +0 -0
  62. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/constraints.py +0 -0
  63. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/json.py +0 -0
  64. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/math.py +0 -0
  65. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/properties.py +0 -0
  66. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/expressions/temporal.py +0 -0
  67. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/athena.py +0 -0
  68. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/databricks.py +0 -0
  69. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/doris.py +0 -0
  70. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/dremio.py +0 -0
  71. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/drill.py +0 -0
  72. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/druid.py +0 -0
  73. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/dune.py +0 -0
  74. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/fabric.py +0 -0
  75. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/materialize.py +0 -0
  76. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/presto.py +0 -0
  77. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/prql.py +0 -0
  78. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/python.py +0 -0
  79. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/risingwave.py +0 -0
  80. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/solr.py +0 -0
  81. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/spark2.py +0 -0
  82. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/starrocks.py +0 -0
  83. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/tableau.py +0 -0
  84. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/teradata.py +0 -0
  85. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/generators/trino.py +0 -0
  86. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/helper.py +0 -0
  87. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/lineage.py +0 -0
  88. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/canonicalize_internal_names.py +0 -0
  89. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
  90. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
  91. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/qualify_tables.py +0 -0
  92. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/optimizer/resolver.py +0 -0
  93. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/athena.py +0 -0
  94. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/base.py +0 -0
  95. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/doris.py +0 -0
  96. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/druid.py +0 -0
  97. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/dune.py +0 -0
  98. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/fabric.py +0 -0
  99. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/materialize.py +0 -0
  100. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/prql.py +0 -0
  101. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/risingwave.py +0 -0
  102. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/solr.py +0 -0
  103. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/spark.py +0 -0
  104. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/sqlite.py +0 -0
  105. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/starrocks.py +0 -0
  106. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/tableau.py +0 -0
  107. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/teradata.py +0 -0
  108. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/parsers/trino.py +0 -0
  109. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglot/trie.py +0 -0
  110. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglotc.egg-info/SOURCES.txt +0 -0
  111. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglotc.egg-info/dependency_links.txt +0 -0
  112. {sqlglotc-30.7.0 → sqlglotc-30.9.0}/sqlglotc.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglotc
3
- Version: 30.7.0
3
+ Version: 30.9.0
4
4
  Summary: mypyc-compiled extensions for sqlglot
5
5
  Author-email: Toby Mao <toby.mao@gmail.com>
6
6
  License-Expression: MIT
@@ -10,4 +10,4 @@ Requires-Python: >=3.10
10
10
  Provides-Extra: dev
11
11
  Requires-Dist: setuptools>=61.0; extra == "dev"
12
12
  Requires-Dist: setuptools_scm; extra == "dev"
13
- Requires-Dist: sqlglot-mypy>=1.20.0.post6; extra == "dev"
13
+ Requires-Dist: sqlglot-mypy>=2.1.0.post2; extra == "dev"
@@ -7,7 +7,7 @@ license = "MIT"
7
7
  requires-python = ">= 3.10"
8
8
 
9
9
  [project.optional-dependencies]
10
- dev = ["setuptools >= 61.0", "setuptools_scm", "sqlglot-mypy >= 1.20.0.post6"]
10
+ dev = ["setuptools >= 61.0", "setuptools_scm", "sqlglot-mypy >= 2.1.0.post2"]
11
11
 
12
12
  [project.urls]
13
13
  Homepage = "https://sqlglot.com/"
@@ -17,7 +17,7 @@ Repository = "https://github.com/tobymao/sqlglot"
17
17
  requires = [
18
18
  "setuptools >= 61.0",
19
19
  "setuptools_scm",
20
- "sqlglot-mypy >= 1.20.0.post6",
20
+ "sqlglot-mypy >= 2.1.0.post2",
21
21
  "types-python-dateutil",
22
22
  "sqlglot",
23
23
  ]
@@ -208,7 +208,7 @@ class NthValue(Expression, AggFunc):
208
208
 
209
209
 
210
210
  class ObjectAgg(Expression, AggFunc):
211
- arg_types = {"this": True, "expression": True}
211
+ arg_types = {"this": True, "expression": False}
212
212
 
213
213
 
214
214
  class PercentileCont(Expression, AggFunc):
@@ -365,5 +365,5 @@ class StDistance(Expression, Func):
365
365
 
366
366
 
367
367
  class StPoint(Expression, Func):
368
- arg_types = {"this": True, "expression": True, "null": False}
368
+ arg_types = {"this": True, "expression": True, "z": False, "m": False}
369
369
  _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
@@ -88,6 +88,7 @@ class Expr:
88
88
  _hash_raw_args: t.ClassVar[bool] = False
89
89
  is_subquery: t.ClassVar[bool] = False
90
90
  is_cast: t.ClassVar[bool] = False
91
+ is_data_type: t.ClassVar[bool] = False
91
92
 
92
93
  args: dict[str, t.Any]
93
94
  parent: Expr | None
@@ -837,26 +838,35 @@ class Expression(Expr):
837
838
  def __hash__(self) -> int:
838
839
  if self._hash is None:
839
840
  nodes: list[Expr] = []
840
- queue: deque[Expr] = deque()
841
- queue.append(self)
841
+ stack: list[Expr] = [self]
842
842
 
843
- while queue:
844
- node = queue.popleft()
843
+ # Collect nodes, finding child expressions inline instead of via the
844
+ # iter_expressions generator (whose per-node generator object dominates the
845
+ # hash's cost). reversed(nodes) is a valid post-order regardless of DFS/BFS.
846
+ while stack:
847
+ node = stack.pop()
845
848
  nodes.append(node)
846
849
 
847
- for child in node.iter_expressions():
848
- if child._hash is None:
849
- queue.append(child)
850
+ for v in node.args.values():
851
+ if isinstance(v, Expr):
852
+ if v._hash is None:
853
+ stack.append(v)
854
+ elif type(v) is list:
855
+ for x in v:
856
+ if isinstance(x, Expr) and x._hash is None:
857
+ stack.append(x)
850
858
 
851
859
  for node in reversed(nodes):
852
860
  hash_ = hash(node.key)
853
861
 
854
862
  if node._hash_raw_args:
855
- for k, v in sorted(node.args.items()):
863
+ for k in sorted(node.args):
864
+ v = node.args[k]
856
865
  if v:
857
866
  hash_ = hash((hash_, k, v))
858
867
  else:
859
- for k, v in sorted(node.args.items()):
868
+ for k in sorted(node.args):
869
+ v = node.args[k]
860
870
  vt = type(v)
861
871
 
862
872
  if vt is list:
@@ -953,6 +963,8 @@ class Expression(Expr):
953
963
 
954
964
  @property
955
965
  def type(self) -> DataType | None:
966
+ if self.is_data_type:
967
+ return self # type: ignore[return-value]
956
968
  if self.is_cast:
957
969
  return self._type or self.to # type: ignore[attr-defined]
958
970
  return self._type
@@ -1039,6 +1051,11 @@ class Expression(Expr):
1039
1051
  return comments
1040
1052
 
1041
1053
  def append(self, arg_key: str, value: t.Any) -> None:
1054
+ node: Expr | None = self
1055
+ while node and node._hash is not None:
1056
+ node._hash = None
1057
+ node = node.parent
1058
+
1042
1059
  if type(self.args.get(arg_key)) is not list:
1043
1060
  self.args[arg_key] = []
1044
1061
  self._set_parent(arg_key, value)
@@ -2118,6 +2135,10 @@ class Distance(Expression, Binary):
2118
2135
  pass
2119
2136
 
2120
2137
 
2138
+ class DistanceNd(Expression, Binary):
2139
+ pass
2140
+
2141
+
2121
2142
  class Escape(Expression, Binary):
2122
2143
  pass
2123
2144
 
@@ -2135,7 +2156,7 @@ class GTE(Expression, Binary, Predicate):
2135
2156
 
2136
2157
 
2137
2158
  class ILike(Expression, Binary, Predicate):
2138
- pass
2159
+ arg_types = {"this": True, "expression": True, "negate": False}
2139
2160
 
2140
2161
 
2141
2162
  class IntDiv(Expression, Binary):
@@ -2147,7 +2168,7 @@ class Is(Expression, Binary, Predicate):
2147
2168
 
2148
2169
 
2149
2170
  class Like(Expression, Binary, Predicate):
2150
- pass
2171
+ arg_types = {"this": True, "expression": True, "negate": False}
2151
2172
 
2152
2173
 
2153
2174
  class Match(Expression, Binary, Predicate):
@@ -2269,8 +2290,7 @@ class Or(Expression, Connector, Func):
2269
2290
 
2270
2291
 
2271
2292
  class Xor(Expression, Connector, Func):
2272
- arg_types = {"this": False, "expression": False, "expressions": False, "round_input": False}
2273
- is_var_len_args = True
2293
+ arg_types = {"this": True, "expression": True, "round_input": False}
2274
2294
 
2275
2295
 
2276
2296
  class Pow(Expression, Binary, Func):
@@ -2428,6 +2448,7 @@ QUERY_MODIFIERS = {
2428
2448
  "settings": False,
2429
2449
  "format": False,
2430
2450
  "options": False,
2451
+ "for_": False,
2431
2452
  }
2432
2453
 
2433
2454
 
@@ -2534,7 +2555,7 @@ def _to_s(node: t.Any, verbose: bool = False, level: int = 0, repr_str: bool = F
2534
2555
  if isinstance(node, Expr):
2535
2556
  args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
2536
2557
 
2537
- if (node.type or verbose) and type(node).__name__ != "DataType":
2558
+ if (node.type or verbose) and not node.is_data_type:
2538
2559
  args["_type"] = node.type
2539
2560
  if node.comments or verbose:
2540
2561
  args["_comments"] = node.comments
@@ -8,6 +8,7 @@ from enum import auto
8
8
  from sqlglot.helper import AutoName
9
9
  from sqlglot.errors import ErrorLevel, ParseError
10
10
  from sqlglot.expressions.core import (
11
+ Expr,
11
12
  Expression,
12
13
  _TimeUnit,
13
14
  Identifier,
@@ -17,13 +18,18 @@ from sqlglot.expressions.core import (
17
18
  from builtins import type as Type
18
19
 
19
20
  if t.TYPE_CHECKING:
21
+ from sqlglot._typing import DataTypeArgs
20
22
  from sqlglot.dialects.dialect import DialectType
21
- from typing_extensions import Self
23
+ from typing_extensions import Self, Unpack
22
24
 
23
25
 
24
26
  class DataTypeParam(Expression):
25
27
  arg_types = {"this": True, "expression": False}
26
28
 
29
+ @property
30
+ def this(self) -> Expr:
31
+ return self.args["this"]
32
+
27
33
  @property
28
34
  def name(self) -> str:
29
35
  return self.this.name
@@ -178,8 +184,11 @@ class DataType(Expression):
178
184
  "values": False,
179
185
  "kind": False,
180
186
  "nullable": False,
187
+ "collate": False,
181
188
  }
182
189
 
190
+ is_data_type: t.ClassVar[bool] = True
191
+
183
192
  Type: t.ClassVar[Type[DType]] = DType
184
193
 
185
194
  STRUCT_TYPES: t.ClassVar[set[DType]] = {
@@ -330,7 +339,7 @@ class DataType(Expression):
330
339
  dialect: DialectType = None,
331
340
  udt: bool = False,
332
341
  copy: bool = True,
333
- **kwargs: object,
342
+ **kwargs: Unpack[DataTypeArgs],
334
343
  ) -> Self:
335
344
  """
336
345
  Constructs a DataType object.
@@ -363,7 +372,11 @@ class DataType(Expression):
363
372
 
364
373
  @classmethod
365
374
  def from_str(
366
- cls, dtype: str, dialect: DialectType = None, udt: bool = False, **kwargs: object
375
+ cls,
376
+ dtype: str,
377
+ dialect: DialectType = None,
378
+ udt: bool = False,
379
+ **kwargs: Unpack[DataTypeArgs],
367
380
  ) -> Self:
368
381
  """
369
382
  Constructs a `DataType` object from a `str` representation.
@@ -404,10 +417,10 @@ class DataType(Expression):
404
417
  Returns:
405
418
  True, if and only if there is a type in `dtypes` which is equal to this DataType.
406
419
  """
407
- self_is_nullable = self.args.get("nullable")
420
+ self_is_nullable: bool | None = self.args.get("nullable")
408
421
  for dtype in dtypes:
409
422
  other_type = DataType.build(dtype, copy=False, udt=True)
410
- other_is_nullable = other_type.args.get("nullable")
423
+ other_is_nullable: bool | None = other_type.args.get("nullable")
411
424
  if (
412
425
  other_type.expressions
413
426
  or (check_nullable and (self_is_nullable or other_is_nullable))
@@ -226,6 +226,14 @@ class UserDefinedFunction(Expression):
226
226
  arg_types = {"this": True, "expressions": False, "wrapped": False}
227
227
 
228
228
 
229
+ class MacroOverloads(Expression):
230
+ arg_types = {"expressions": True}
231
+
232
+
233
+ class MacroOverload(Expression):
234
+ arg_types = {"this": True, "expressions": False, "is_table": False}
235
+
236
+
229
237
  class CharacterSet(Expression):
230
238
  arg_types = {"this": True, "default": False}
231
239
 
@@ -246,7 +254,7 @@ class AlterColumn(Expression):
246
254
 
247
255
 
248
256
  class ModifyColumn(Expression):
249
- pass
257
+ arg_types = {"this": True, "rename_from": False}
250
258
 
251
259
 
252
260
  class AlterIndex(Expression):
@@ -283,6 +283,7 @@ class LoadData(Expression):
283
283
  "this": True,
284
284
  "local": False,
285
285
  "overwrite": False,
286
+ "temp": False,
286
287
  "inpath": False,
287
288
  "files": False,
288
289
  "partition": False,
@@ -70,7 +70,7 @@ class Cast(Expression, Func):
70
70
 
71
71
 
72
72
  class TryCast(Cast):
73
- arg_types = {**Cast.arg_types, "requires_string": False}
73
+ arg_types = {**Cast.arg_types, "requires_string": False, "null_on_text_overflow": False}
74
74
 
75
75
 
76
76
  class JSONCast(Cast):
@@ -148,6 +148,10 @@ class Nullif(Expression, Func):
148
148
  arg_types = {"this": True, "expression": True}
149
149
 
150
150
 
151
+ class ObjectTransform(Expression, Func):
152
+ arg_types = {"this": True, "keep": False, "set_": False}
153
+
154
+
151
155
  class Nvl2(Expression, Func):
152
156
  arg_types = {"this": True, "true": True, "false": False}
153
157
 
@@ -301,6 +305,10 @@ class CurrentUser(Expression, Func):
301
305
  arg_types = {"this": False}
302
306
 
303
307
 
308
+ class CurrentUserId(Expression, Func):
309
+ arg_types = {}
310
+
311
+
304
312
  class CurrentVersion(Expression, Func):
305
313
  arg_types = {}
306
314
 
@@ -428,6 +436,10 @@ class XMLElement(Expression, Func):
428
436
  arg_types = {"this": True, "expressions": False, "evalname": False}
429
437
 
430
438
 
439
+ class GetIgnoreCase(Expression, Func):
440
+ arg_types = {"this": True, "expression": True}
441
+
442
+
431
443
  class XMLGet(Expression, Func):
432
444
  _sql_names = ["XMLGET"]
433
445
  arg_types = {"this": True, "expression": True, "instance": False}
@@ -915,6 +915,11 @@ class QueryOption(Expression):
915
915
  arg_types = {"this": True, "expression": False}
916
916
 
917
917
 
918
+ # FOR { XML | JSON } query modifier; `kind` is the discriminant ("XML" or "JSON").
919
+ class ForClause(Expression):
920
+ arg_types = {"kind": True, "expressions": False}
921
+
922
+
918
923
  class WithTableHint(Expression):
919
924
  arg_types = {"expressions": True}
920
925
 
@@ -1753,6 +1758,9 @@ class Pivot(Expression):
1753
1758
  "default_on_null": False,
1754
1759
  "into": False,
1755
1760
  "with_": False,
1761
+ "identify_pivot_strings": False,
1762
+ "prefixed_pivot_columns": False,
1763
+ "pivot_column_naming": False,
1756
1764
  }
1757
1765
 
1758
1766
  @property
@@ -1763,14 +1771,15 @@ class Pivot(Expression):
1763
1771
  def fields(self) -> list[Expr]:
1764
1772
  return self.args.get("fields", [])
1765
1773
 
1766
- def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> list[str]:
1774
+ def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1767
1775
  """
1768
- Returns the columns produced by this (UN)PIVOT, in order.
1776
+ Returns an ordered map of post-rename output column name -> pre-rename
1777
+ source-side name, in the order the (UN)PIVOT produces them.
1769
1778
 
1770
- Example:
1779
+ For callers that just want the names, iterate the dict (or call .keys()):
1771
1780
  >>> from sqlglot import parse_one, exp
1772
1781
  >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1773
- >>> piv.output_columns(["a", "b", "c"])
1782
+ >>> list(piv.output_columns(["a", "b", "c"]))
1774
1783
  ['c', 'name', 'val']
1775
1784
 
1776
1785
  AST shape:
@@ -1813,9 +1822,23 @@ class Pivot(Expression):
1813
1822
  outputs = [c.alias_or_name for c in self.expressions]
1814
1823
 
1815
1824
  if not excluded or not outputs:
1816
- return []
1825
+ return {}
1826
+
1827
+ pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1828
+
1829
+ alias = self.args.get("alias")
1830
+ renames = alias.args.get("columns") if alias else None
1831
+
1832
+ # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1833
+ # positionally from the front (DuckDB, Snowflake): the user's names cover
1834
+ # the leading N output columns, remaining columns keep their auto names.
1835
+ if renames:
1836
+ rename_names = [r.name for r in renames]
1837
+ post_rename = rename_names + pre_rename[len(rename_names) :]
1838
+ else:
1839
+ post_rename = pre_rename
1817
1840
 
1818
- return [c for c in pre_pivot_columns if c not in excluded] + outputs
1841
+ return dict(zip(post_rename, pre_rename))
1819
1842
 
1820
1843
 
1821
1844
  class UnpivotColumns(Expression):
@@ -303,17 +303,13 @@ class FromBase64(Expression, Func):
303
303
 
304
304
 
305
305
  class Hex(Expression, Func):
306
- pass
306
+ arg_types = {"this": True, "case": False}
307
307
 
308
308
 
309
309
  class HexDecodeString(Expression, Func):
310
310
  pass
311
311
 
312
312
 
313
- class HexEncode(Expression, Func):
314
- arg_types = {"this": True, "case": False}
315
-
316
-
317
313
  class LowerHex(Hex):
318
314
  pass
319
315
 
@@ -379,6 +375,7 @@ class ToNumber(Expression, Func):
379
375
  "scale": False,
380
376
  "safe": False,
381
377
  "safe_name": False,
378
+ "default": False,
382
379
  }
383
380
 
384
381