sqlglotc 30.1.0__tar.gz → 30.2.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 (110) hide show
  1. {sqlglotc-30.1.0/sqlglotc.egg-info → sqlglotc-30.2.0}/PKG-INFO +1 -1
  2. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/setup.py +2 -0
  3. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/builders.py +80 -47
  4. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/core.py +138 -110
  5. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/datatypes.py +26 -16
  6. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/dml.py +15 -10
  7. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/functions.py +10 -2
  8. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/json.py +4 -0
  9. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/math.py +1 -1
  10. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/properties.py +8 -0
  11. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/query.py +52 -46
  12. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/string.py +1 -1
  13. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generator.py +46 -14
  14. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/bigquery.py +1 -1
  15. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/clickhouse.py +2 -5
  16. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/databricks.py +12 -1
  17. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/duckdb.py +49 -18
  18. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/hive.py +3 -7
  19. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/postgres.py +2 -2
  20. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/presto.py +1 -1
  21. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/sqlite.py +2 -0
  22. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/helper.py +16 -14
  23. sqlglotc-30.2.0/sqlglot/optimizer/annotate_types.py +908 -0
  24. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/optimizer/qualify_tables.py +4 -3
  25. sqlglotc-30.2.0/sqlglot/optimizer/simplify.py +1725 -0
  26. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parser.py +13 -11
  27. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/athena.py +13 -8
  28. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/bigquery.py +1 -1
  29. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/clickhouse.py +6 -8
  30. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/dremio.py +2 -2
  31. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/duckdb.py +13 -1
  32. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/hive.py +1 -1
  33. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/redshift.py +5 -4
  34. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/singlestore.py +1 -4
  35. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/snowflake.py +8 -7
  36. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/sqlite.py +15 -0
  37. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/schema.py +4 -4
  38. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/tokenizer_core.py +6 -1
  39. {sqlglotc-30.1.0 → sqlglotc-30.2.0/sqlglotc.egg-info}/PKG-INFO +1 -1
  40. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglotc.egg-info/SOURCES.txt +2 -0
  41. sqlglotc-30.2.0/sqlglotc.egg-info/top_level.txt +2 -0
  42. sqlglotc-30.1.0/sqlglotc.egg-info/top_level.txt +0 -2
  43. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/MANIFEST.in +0 -0
  44. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/pyproject.toml +0 -0
  45. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/setup.cfg +0 -0
  46. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/errors.py +0 -0
  47. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/executor/table.py +0 -0
  48. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/aggregate.py +0 -0
  49. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/array.py +0 -0
  50. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/constraints.py +0 -0
  51. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/ddl.py +0 -0
  52. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/expressions/temporal.py +0 -0
  53. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/athena.py +0 -0
  54. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/doris.py +0 -0
  55. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/dremio.py +0 -0
  56. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/drill.py +0 -0
  57. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/druid.py +0 -0
  58. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/dune.py +0 -0
  59. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/exasol.py +0 -0
  60. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/fabric.py +0 -0
  61. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/materialize.py +0 -0
  62. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/mysql.py +0 -0
  63. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/oracle.py +0 -0
  64. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/prql.py +0 -0
  65. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/redshift.py +0 -0
  66. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/risingwave.py +0 -0
  67. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/singlestore.py +0 -0
  68. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/snowflake.py +0 -0
  69. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/solr.py +0 -0
  70. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/spark.py +0 -0
  71. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/spark2.py +0 -0
  72. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/starrocks.py +0 -0
  73. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/tableau.py +0 -0
  74. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/teradata.py +0 -0
  75. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/trino.py +0 -0
  76. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/generators/tsql.py +0 -0
  77. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
  78. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
  79. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/optimizer/qualify.py +0 -0
  80. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/optimizer/qualify_columns.py +0 -0
  81. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/optimizer/resolver.py +0 -0
  82. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/optimizer/scope.py +0 -0
  83. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/base.py +0 -0
  84. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/databricks.py +0 -0
  85. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/doris.py +0 -0
  86. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/drill.py +0 -0
  87. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/druid.py +0 -0
  88. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/dune.py +0 -0
  89. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/exasol.py +0 -0
  90. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/fabric.py +0 -0
  91. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/materialize.py +0 -0
  92. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/mysql.py +0 -0
  93. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/oracle.py +0 -0
  94. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/postgres.py +0 -0
  95. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/presto.py +0 -0
  96. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/prql.py +0 -0
  97. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/risingwave.py +0 -0
  98. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/solr.py +0 -0
  99. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/spark.py +0 -0
  100. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/spark2.py +0 -0
  101. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/starrocks.py +0 -0
  102. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/tableau.py +0 -0
  103. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/teradata.py +0 -0
  104. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/trino.py +0 -0
  105. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/parsers/tsql.py +0 -0
  106. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/serde.py +0 -0
  107. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/time.py +0 -0
  108. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglot/trie.py +0 -0
  109. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglotc.egg-info/dependency_links.txt +0 -0
  110. {sqlglotc-30.1.0 → sqlglotc-30.2.0}/sqlglotc.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglotc
3
- Version: 30.1.0
3
+ Version: 30.2.0
4
4
  Summary: mypyc-compiled extensions for sqlglot
5
5
  Author-email: Toby Mao <toby.mao@gmail.com>
6
6
  License-Expression: MIT
@@ -65,6 +65,8 @@ def _source_files(src_dir):
65
65
  "qualify.py",
66
66
  "qualify_tables.py",
67
67
  "qualify_columns.py",
68
+ "simplify.py",
69
+ "annotate_types.py",
68
70
  ],
69
71
  ),
70
72
  *_subpkg_files(src_dir, "parsers"),
@@ -5,7 +5,6 @@ from __future__ import annotations
5
5
  import re
6
6
  import typing as t
7
7
 
8
- from sqlglot._typing import E
9
8
  from sqlglot.helper import seq_get, ensure_collection, split_num_words
10
9
  from sqlglot.errors import ParseError, TokenError
11
10
  from sqlglot.expressions.core import (
@@ -43,21 +42,32 @@ from sqlglot.expressions.query import (
43
42
  Values,
44
43
  Where,
45
44
  With,
45
+ Query,
46
46
  )
47
47
  from sqlglot.expressions.ddl import Alter, AlterRename, RenameColumn
48
48
  from sqlglot.expressions.dml import Delete, Insert, Merge, Update, When, Whens
49
49
  from sqlglot.expressions.functions import Case, Cast
50
50
  from sqlglot.expressions.array import Array
51
51
 
52
+
52
53
  if t.TYPE_CHECKING:
53
- from collections.abc import Sequence, Iterable
54
+ from collections.abc import Sequence, Iterable, Iterator
54
55
  from sqlglot.dialects.dialect import DialectType
55
56
  from sqlglot.expressions.core import ExpOrStr, Func
56
57
  from sqlglot.expressions.datatypes import DATA_TYPE
57
- from sqlglot.expressions.query import Query
58
+ from sqlglot._typing import ParserArgs, ParserNoDialectArgs, E
59
+ from typing_extensions import Unpack, ParamSpec, Concatenate
60
+ from sqlglot.expressions.core import Dot
61
+
62
+ P = ParamSpec("P")
58
63
 
59
64
 
60
- def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts: t.Any) -> Select:
65
+ def select(
66
+ *expressions: ExpOrStr,
67
+ dialect: DialectType = None,
68
+ copy: bool = True,
69
+ **opts: Unpack[ParserNoDialectArgs],
70
+ ) -> Select:
61
71
  """
62
72
  Initializes a syntax tree from one or multiple SELECT expressions.
63
73
 
@@ -76,10 +86,15 @@ def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts: t.Any) -
76
86
  Returns:
77
87
  Select: the syntax tree for the SELECT statement.
78
88
  """
79
- return Select().select(*expressions, dialect=dialect, **opts)
89
+ return Select().select(*expressions, dialect=dialect, copy=copy, **opts)
80
90
 
81
91
 
82
- def from_(expression: ExpOrStr, dialect: DialectType = None, **opts: t.Any) -> Select:
92
+ def from_(
93
+ expression: ExpOrStr,
94
+ dialect: DialectType = None,
95
+ copy: bool = True,
96
+ **opts: Unpack[ParserNoDialectArgs],
97
+ ) -> Select:
83
98
  """
84
99
  Initializes a syntax tree from a FROM expression.
85
100
 
@@ -98,17 +113,18 @@ def from_(expression: ExpOrStr, dialect: DialectType = None, **opts: t.Any) -> S
98
113
  Returns:
99
114
  Select: the syntax tree for the SELECT statement.
100
115
  """
101
- return Select().from_(expression, dialect=dialect, **opts)
116
+ return Select().from_(expression, dialect=dialect, copy=copy, **opts)
102
117
 
103
118
 
104
119
  def update(
105
120
  table: str | Table,
106
- properties: t.Optional[dict] = None,
121
+ properties: t.Optional[dict[str, object]] = None,
107
122
  where: t.Optional[ExpOrStr] = None,
108
123
  from_: t.Optional[ExpOrStr] = None,
109
124
  with_: t.Optional[dict[str, ExpOrStr]] = None,
110
125
  dialect: DialectType = None,
111
- **opts: t.Any,
126
+ copy: bool = True,
127
+ **opts: Unpack[ParserNoDialectArgs],
112
128
  ) -> Update:
113
129
  """
114
130
  Creates an update statement.
@@ -124,35 +140,38 @@ def update(
124
140
  from_: sql statement parsed into a FROM statement
125
141
  with_: dictionary of CTE aliases / select statements to include in a WITH clause.
126
142
  dialect: the dialect used to parse the input expressions.
143
+ copy: whether to copy the input expressions.
127
144
  **opts: other options to use to parse the input expressions.
128
145
 
129
146
  Returns:
130
147
  Update: the syntax tree for the UPDATE statement.
131
148
  """
132
- update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
149
+ update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect, copy=copy))
133
150
  if properties:
134
151
  update_expr.set(
135
152
  "expressions",
136
153
  [
137
- EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
154
+ EQ(this=maybe_parse(k, dialect=dialect, copy=copy, **opts), expression=convert(v))
138
155
  for k, v in properties.items()
139
156
  ],
140
157
  )
141
158
  if from_:
142
159
  update_expr.set(
143
160
  "from_",
144
- maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
161
+ maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", copy=copy, **opts),
145
162
  )
146
163
  if isinstance(where, Condition):
147
164
  where = Where(this=where)
148
165
  if where:
149
166
  update_expr.set(
150
167
  "where",
151
- maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
168
+ maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", copy=copy, **opts),
152
169
  )
153
170
  if with_:
154
171
  cte_list = [
155
- alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
172
+ alias_(
173
+ CTE(this=maybe_parse(qry, dialect=dialect, copy=copy, **opts)), alias, table=True
174
+ )
156
175
  for alias, qry in with_.items()
157
176
  ]
158
177
  update_expr.set(
@@ -167,7 +186,7 @@ def delete(
167
186
  where: t.Optional[ExpOrStr] = None,
168
187
  returning: t.Optional[ExpOrStr] = None,
169
188
  dialect: DialectType = None,
170
- **opts: t.Any,
189
+ **opts: Unpack[ParserNoDialectArgs],
171
190
  ) -> Delete:
172
191
  """
173
192
  Builds a delete statement.
@@ -195,13 +214,13 @@ def delete(
195
214
 
196
215
  def insert(
197
216
  expression: ExpOrStr,
198
- into: ExpOrStr,
217
+ into: str | Table,
199
218
  columns: t.Optional[Sequence[str | Identifier]] = None,
200
219
  overwrite: t.Optional[bool] = None,
201
220
  returning: t.Optional[ExpOrStr] = None,
202
221
  dialect: DialectType = None,
203
222
  copy: bool = True,
204
- **opts: t.Any,
223
+ **opts: Unpack[ParserNoDialectArgs],
205
224
  ) -> Insert:
206
225
  """
207
226
  Builds an INSERT statement.
@@ -245,7 +264,7 @@ def merge(
245
264
  returning: t.Optional[ExpOrStr] = None,
246
265
  dialect: DialectType = None,
247
266
  copy: bool = True,
248
- **opts: t.Any,
267
+ **opts: Unpack[ParserNoDialectArgs],
249
268
  ) -> Merge:
250
269
  """
251
270
  Builds a MERGE statement.
@@ -271,7 +290,7 @@ def merge(
271
290
  Returns:
272
291
  Merge: The syntax tree for the MERGE statement.
273
292
  """
274
- expressions: t.List[Expr] = []
293
+ expressions: list[Expr] = []
275
294
  for when_expr in when_exprs:
276
295
  expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
277
296
  expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
@@ -332,7 +351,7 @@ def to_interval(interval: str | Expr) -> Interval:
332
351
 
333
352
 
334
353
  def to_table(
335
- sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
354
+ sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs: object
336
355
  ) -> Table:
337
356
  """
338
357
  Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
@@ -360,10 +379,7 @@ def to_table(
360
379
 
361
380
  table = table_(this, db=db, catalog=catalog)
362
381
 
363
- for k, v in kwargs.items():
364
- table.set(k, v)
365
-
366
- return table
382
+ return table.set_kwargs(kwargs)
367
383
 
368
384
 
369
385
  def to_column(
@@ -371,8 +387,8 @@ def to_column(
371
387
  quoted: t.Optional[bool] = None,
372
388
  dialect: DialectType = None,
373
389
  copy: bool = True,
374
- **kwargs,
375
- ) -> Column:
390
+ **kwargs: t.Any,
391
+ ) -> t.Union[Column, Dot]:
376
392
  """
377
393
  Create a column from a `[table].[column]` sql path. Table is optional.
378
394
  If a column is passed in then that column is returned.
@@ -409,7 +425,8 @@ def subquery(
409
425
  expression: ExpOrStr,
410
426
  alias: t.Optional[Identifier | str] = None,
411
427
  dialect: DialectType = None,
412
- **opts: t.Any,
428
+ copy: bool = True,
429
+ **opts: Unpack[ParserNoDialectArgs],
413
430
  ) -> Select:
414
431
  """
415
432
  Build a subquery expression that's selected from.
@@ -428,9 +445,10 @@ def subquery(
428
445
  Returns:
429
446
  A new Select instance with the subquery expression included.
430
447
  """
431
-
432
- expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
433
- return Select().from_(expression, dialect=dialect, **opts)
448
+ expr = (
449
+ maybe_parse(expression, dialect=dialect, **opts).assert_is(Query).subquery(alias, copy=copy)
450
+ )
451
+ return Select().from_(expr, dialect=dialect, **opts)
434
452
 
435
453
 
436
454
  def cast(
@@ -438,7 +456,7 @@ def cast(
438
456
  to: DATA_TYPE,
439
457
  copy: bool = True,
440
458
  dialect: DialectType = None,
441
- **opts: t.Any,
459
+ **opts: Unpack[ParserNoDialectArgs],
442
460
  ) -> Cast:
443
461
  """Cast an expression to a data type.
444
462
 
@@ -630,7 +648,12 @@ def rename_column(
630
648
  )
631
649
 
632
650
 
633
- def replace_children(expression: Expr, fun: t.Callable, *args, **kwargs) -> None:
651
+ def replace_children(
652
+ expression: Expr,
653
+ fun: t.Callable[Concatenate[Expr, P], object],
654
+ *args: P.args,
655
+ **kwargs: P.kwargs,
656
+ ) -> None:
634
657
  """
635
658
  Replace children of an expression with the result of a lambda fun(child) -> exp.
636
659
  """
@@ -655,7 +678,7 @@ def replace_children(expression: Expr, fun: t.Callable, *args, **kwargs) -> None
655
678
 
656
679
  def replace_tree(
657
680
  expression: Expr,
658
- fun: t.Callable,
681
+ fun: t.Callable[[Expr], Expr],
659
682
  prune: t.Optional[t.Callable[[Expr], bool]] = None,
660
683
  ) -> Expr:
661
684
  """
@@ -679,7 +702,7 @@ def replace_tree(
679
702
  return new_node
680
703
 
681
704
 
682
- def find_tables(expression: Expr) -> t.Set[Table]:
705
+ def find_tables(expression: Expr) -> set[Table]:
683
706
  """
684
707
  Find all tables referenced in a query.
685
708
 
@@ -699,7 +722,7 @@ def find_tables(expression: Expr) -> t.Set[Table]:
699
722
  }
700
723
 
701
724
 
702
- def column_table_names(expression: Expr, exclude: str = "") -> t.Set[str]:
725
+ def column_table_names(expression: Expr, exclude: str = "") -> set[str]:
703
726
  """
704
727
  Return all table names referenced through columns in an expression.
705
728
 
@@ -779,7 +802,7 @@ def normalize_table_name(table: str | Table, dialect: DialectType = None, copy:
779
802
 
780
803
 
781
804
  def replace_tables(
782
- expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
805
+ expression: E, mapping: dict[str, str], dialect: DialectType = None, copy: bool = True
783
806
  ) -> E:
784
807
  """Replace all tables in expression according to the mapping.
785
808
 
@@ -818,7 +841,7 @@ def replace_tables(
818
841
  return expression.transform(_replace_tables, copy=copy) # type: ignore
819
842
 
820
843
 
821
- def replace_placeholders(expression: Expr, *args, **kwargs) -> Expr:
844
+ def replace_placeholders(expression: Expr, *args: object, **kwargs: t.Any) -> Expr:
822
845
  """Replace placeholders in an expression.
823
846
 
824
847
  Args:
@@ -838,7 +861,7 @@ def replace_placeholders(expression: Expr, *args, **kwargs) -> Expr:
838
861
  The mapped expression.
839
862
  """
840
863
 
841
- def _replace_placeholders(node: Expr, args, **kwargs) -> Expr:
864
+ def _replace_placeholders(node: Expr, args: Iterator[object], **kwargs: object) -> Expr:
842
865
  if isinstance(node, Placeholder):
843
866
  if node.this:
844
867
  new_name = kwargs.get(node.this)
@@ -856,7 +879,7 @@ def replace_placeholders(expression: Expr, *args, **kwargs) -> Expr:
856
879
 
857
880
  def expand(
858
881
  expression: Expr,
859
- sources: t.Dict[str, Query | t.Callable[[], Query]],
882
+ sources: dict[str, Query | t.Callable[[], Query]],
860
883
  dialect: DialectType = None,
861
884
  copy: bool = True,
862
885
  ) -> Expr:
@@ -900,7 +923,9 @@ def expand(
900
923
  return expression.transform(_expand, copy=copy)
901
924
 
902
925
 
903
- def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
926
+ def func(
927
+ name: str, *args: t.Any, copy: bool = True, dialect: DialectType = None, **kwargs: t.Any
928
+ ) -> Func:
904
929
  """
905
930
  Returns a Func expression.
906
931
 
@@ -932,7 +957,7 @@ def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwa
932
957
 
933
958
  dialect = Dialect.get_or_raise(dialect)
934
959
 
935
- converted: t.List[Expr] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
960
+ converted: list[Expr] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
936
961
  kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
937
962
 
938
963
  constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
@@ -967,7 +992,8 @@ def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwa
967
992
 
968
993
  def case(
969
994
  expression: t.Optional[ExpOrStr] = None,
970
- **opts: t.Any,
995
+ copy: bool = True,
996
+ **opts: Unpack[ParserArgs],
971
997
  ) -> Case:
972
998
  """
973
999
  Initialize a CASE statement.
@@ -977,17 +1003,21 @@ def case(
977
1003
 
978
1004
  Args:
979
1005
  expression: Optionally, the input expression (not all dialects support this)
1006
+ copy: whether to copy the argument expressions.
980
1007
  **opts: Extra keyword arguments for parsing `expression`
981
1008
  """
982
1009
  if expression is not None:
983
- this = maybe_parse(expression, **opts)
1010
+ this = maybe_parse(expression, copy=copy, **opts)
984
1011
  else:
985
1012
  this = None
986
1013
  return Case(this=this, ifs=[])
987
1014
 
988
1015
 
989
1016
  def array(
990
- *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
1017
+ *expressions: ExpOrStr,
1018
+ copy: bool = True,
1019
+ dialect: DialectType = None,
1020
+ **kwargs: Unpack[ParserNoDialectArgs],
991
1021
  ) -> Array:
992
1022
  """
993
1023
  Returns an array.
@@ -1014,7 +1044,10 @@ def array(
1014
1044
 
1015
1045
 
1016
1046
  def tuple_(
1017
- *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
1047
+ *expressions: ExpOrStr,
1048
+ copy: bool = True,
1049
+ dialect: DialectType = None,
1050
+ **kwargs: Unpack[ParserNoDialectArgs],
1018
1051
  ) -> Tuple:
1019
1052
  """
1020
1053
  Returns an tuple.
@@ -1063,10 +1096,10 @@ def null() -> Null:
1063
1096
 
1064
1097
  def apply_index_offset(
1065
1098
  this: Expr,
1066
- expressions: t.List[E],
1099
+ expressions: list[E],
1067
1100
  offset: int,
1068
1101
  dialect: DialectType = None,
1069
- ) -> t.List[E]:
1102
+ ) -> list[E]:
1070
1103
  if not offset or len(expressions) != 1:
1071
1104
  return expressions
1072
1105